来者有分!在ubuntu环境下,用Qt怎么实现一个usb盘检测工具?

weiweiloong 2012-11-23 09:11:57
各位大侠,我目前的工作需要,在ubuntu环境下实现一个u盘插拔识别工具;
我选择了qt creator;在网上找了一段代码,是管理U盘的,我将代码加入到我的项目中,
编译运行后,发现插拔usb盘,我找到的代码没有反应,求助各位了,帮我看看了,来者有分。

#ifndef HALDEVICE_H
#define HALDEVICE_H

#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <QObject>
#include <QtDBus/QDBusConnection>
#include <QtDBus/QDBusInterface>
#include <QtDBus/QDBusObjectPath>
#include <QtDBus/QDBusReply>
#include <QtDBus/QDBusVariant>
#include <QTimer>
#include <QtDBus/QDBusMetaType>
#include <QtDBus/QDBusArgument>
#include <QFile>
#include <QDBusInterface>
//#include "filebrowser.h"

#ifdef DEBUG_LOG
#define LOG(...) printf(__VA_ARGS__)
#else
#define LOG( format, ... ) "\n"
#endif

#define DBUS_HAL_SERVICE "org.freedesktop.Hal"
#define DBUS_HAL_PATH "/org/freedesktop/Hal/Manager"
#define DBUS_HAL_INTERFACE "org.freedesktop.Hal.Manager"
#define DBUS_HAL_DEVICE_INTERFACE "org.freedesktop.Hal.Device"


struct ChangeStruct
{
QString propertyName;
bool added;
bool removed;
};

class haldevice : public QObject
{
Q_OBJECT
signals:
void mountedStatusChanged(bool);
void readyBrowserUsb(QString path);
public:
// usbdevice(QObject *parent = 0);
haldevice(QDBusInterface *interface,const QString &deviceUdi);
~haldevice();

public slots:
void propertyModified(int numChanges,const QList<ChangeStruct> &changes);
void proMountedStatusChanged(bool);
void proReadyBrowserUsb(QString path);
public:
const QString& udi() const;
const QString& parentUdi() const;
const QString& blockName() const;
const QString& category() const;
const QString& bus() const;
int majorNumber() const;
bool isMounted() const;
bool isMountedByDBus() const;
const QString& currentMountPointByDBus();

void setParentUdi(QString);
void setBlockName(QString);
void setCurrentMountPoint(QString);
void setCategory(QString);
void setBus(QString);
void setIsMounted(bool);
void setMajorNumber(int);
private:
QString deviceUdi;
QString deviceParentUdi;
QString deviceBlockName;
QString deviceCurrentMountPoint;
QString deviceCategory;
QString deviceBus;
bool deviceIsMounted;
int major;
QDBusInterface *informationCenter;
};

#endif

#ifndef UABMANAGER_H
#define UABMANAGER_H

#include "haldevice.h"
#include <QtCore/QMap>
#include <QDBusInterface>

class usbmanager : public QObject
{
Q_OBJECT

public:
usbmanager(QObject *parent = 0);

public slots:
void slotDeviceAdded(QString strdev);
void slotDeviceRemoved(QString strdev);
void scan();

private:
QMap<QString,haldevice*> mDeviceMap;
void getDevice(QDBusInterface *interface,const QString &udi);

bool isVolume(QString value);
bool isDisk(QString value);
bool isBlockDev(QString value);
bool isValidMajor(int value);
bool isUsb(QString value);

// Create interface to get information from Hal
QDBusInterface *interfaceHal;



};

#endif
...全文
548 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
shen_wei 2012-11-26
  • 打赏
  • 举报
回复
#define UEVENT_BUFFER_SIZE 2048

static int init_hotplug_sock()
{
    const int buffersize = 1024;
    int ret;

    struct sockaddr_nl snl;
    bzero(&snl, sizeof(struct sockaddr_nl));
    snl.nl_family = AF_NETLINK;
    snl.nl_pid = getpid();
    snl.nl_groups = 1;

    int s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
    if (s == -1)
    {
        perror("socket");
        return -1;
    }
    setsockopt(s, SOL_SOCKET, SO_RCVBUF, &buffersize, sizeof(buffersize));

    ret = bind(s, (struct sockaddr *)&snl, sizeof(struct sockaddr_nl));
    if (ret < 0)
    {
        perror("bind");
        close(s);
        return -1;
    }
    return s;
}
void QDevThread::run()
{
    int hotplug_sock = init_hotplug_sock();
    if(hotplug_sock != -1)
    {
        while(1)
        {
            /* Netlink message buffer */
            char buf[UEVENT_BUFFER_SIZE * 2] = {0};
            recv(hotplug_sock, &buf, sizeof(buf), 0);
            QString str = buf;
            if(str.indexOf("add@/devices") == 0)
            {
                //qDebug()<<"Add"<<str;
                bDevAdd = true;              
            }
            if(str.indexOf("remove@/devices") == 0)
            {
                bDevAdd = false;
            }
        }
    }
}
检测USB的添加和移除。。。
菜园小火车 2012-11-26
  • 打赏
  • 举报
回复
接分
jianxichen 2012-11-26
  • 打赏
  • 举报
回复
我都看不
noodle123 2012-11-26
  • 打赏
  • 举报
回复
编译不过去,提示QDBusInterface未定义,Qt4.7.4版本,命名能看到这个文件,但是提示未定义。好郁闷呢。
noodle123 2012-11-26
  • 打赏
  • 举报
回复
楼主威武,这么长的代码,我先在windows下试试看啊。
水军总督 2012-11-25
  • 打赏
  • 举报
回复
听说在论坛随便回复也有分加,特地来留言。。。大二刚学Qt不久,晕得要死。之前搭个Linux平台足以让我吐血,最后还没搭成。。。
ljhhh0123 2012-11-23
  • 打赏
  • 举报
回复
udev是linux内核的设备管理器,xfce关于usb设备插入后的执行方式都会通过它.你可与这个守护进程通信来获取消息. 楼主的方法是用的hal是另一种方法.
彩阳 2012-11-23
  • 打赏
  • 举报
回复
我试了一下你给出的代码,发现插拔U盘有反应,只是会出现这样的错误: ../[Qt]USBMager/usbmanager.cpp,scan,19 error message:Could not get owner of name 'org.freedesktop.Hal': no such name
weiweiloong 2012-11-23
  • 打赏
  • 举报
回复
#include "usbmanager.h" #include <QMessageBox> usbmanager::usbmanager(QObject *parent) : QObject (parent) { mDeviceMap.clear(); interfaceHal = new QDBusInterface(DBUS_HAL_SERVICE,DBUS_HAL_PATH,DBUS_HAL_INTERFACE,QDBusConnection::systemBus()); QDBusConnection::systemBus().connect(DBUS_HAL_SERVICE, DBUS_HAL_PATH, DBUS_HAL_INTERFACE, "DeviceAdded", this, SLOT(slotDeviceAdded(QString))); QDBusConnection::systemBus().connect(DBUS_HAL_SERVICE, DBUS_HAL_PATH, DBUS_HAL_INTERFACE, "DeviceRemoved", this, SLOT(slotDeviceRemoved(QString))); QTimer::singleShot(0, this, SLOT(scan())); } void usbmanager::scan() { if (!interfaceHal ->isValid()) { printf("%s,%s,%d error message:%s\n",__FILE__,__FUNCTION__,__LINE__,QDBusConnection::systemBus().lastError().message().toLocal8Bit().data()); return; } QMessageBox::information(NULL, tr("Error!"), tr("sddd"), QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel); QDBusReply<QStringList> deviceList = interfaceHal->call(QDBus::Block, "GetAllDevices"); if(deviceList.isValid()) { for(int i = 0; i < deviceList.value().length(); i++) { slotDeviceAdded(deviceList.value().at(i)); } } } void usbmanager::slotDeviceAdded(QString udi) { QDBusInterface *remoteApp = new QDBusInterface(DBUS_HAL_SERVICE, udi, DBUS_HAL_DEVICE_INTERFACE, QDBusConnection::systemBus()); if(!remoteApp->isValid()) { printf("%s,%s,%d error message:%s\n",__FILE__,__FUNCTION__,__LINE__,remoteApp->lastError().message().toLocal8Bit().data()); return; } getDevice(remoteApp,udi); } void usbmanager::slotDeviceRemoved(QString udi) { mDeviceMap.remove(udi); } void usbmanager::getDevice(QDBusInterface *interface,const QString &udi) { QDBusInterface *informationCenter; QString deviceUdi; informationCenter = interface; deviceUdi = udi; QString deviceCategory; QString deviceBlockName; QString deviceParentUdi; QString deviceBus; QString deviceCurrentMountPoint; int major = 0; bool isMounted = false; QDBusReply<QString> categoryReply = informationCenter->call("GetPropertyString","info.category"); deviceCategory = categoryReply.value(); QDBusReply<QString> blockReply = informationCenter->call("GetPropertyString","block.device"); deviceBlockName = blockReply.value(); QDBusReply<int> majorReply = informationCenter->call("GetPropertyInteger","block.major"); major = majorReply.isValid() ? majorReply.value() : 0; LOG("%s,%s,%d category=%s blockName=%s major=%d\n", __FILE__,__FUNCTION__,__LINE__,deviceCategory.toLocal8Bit().data(),deviceBlockName.toLocal8Bit().data(),major); if (((isVolume(deviceCategory))||(isDisk(deviceCategory))) &&(isBlockDev(deviceBlockName)) &&(isValidMajor(major)) ) { QDBusReply<QString> parentReply = informationCenter->call("GetPropertyString","info.parent"); deviceParentUdi = parentReply.value(); //if is volume if (isVolume(deviceCategory)) { //if parent exist in map and not a usb device,return; if (mDeviceMap.contains(deviceParentUdi)) { haldevice *devParent = mDeviceMap.value(deviceParentUdi); if (NULL != devParent) { if (!isUsb(devParent->bus())) { return; } } } QDBusReply<bool> isMountReply = informationCenter->call("GetPropertyString", "volume.is_mounted"); if (isMountReply.isValid() ) { isMounted = isMountReply.value(); } //if already mounted, get mount point if (isMounted) { QDBusReply<QString> mountReplay = informationCenter->call(QDBus::AutoDetect, "GetPropertyString", "volume.mount_point"); if ( (mountReplay.isValid()) && (mountReplay.value() != "")) { deviceCurrentMountPoint = mountReplay.value(); } } } QDBusReply<QString> storageBusReply = informationCenter->call("GetPropertyString","storage.bus"); if (storageBusReply.isValid()) deviceBus = storageBusReply.value(); haldevice *dev = NULL; if (mDeviceMap.contains(udi)) { dev = mDeviceMap.take(udi); } else { dev = new haldevice(informationCenter,udi); } dev->setParentUdi(deviceParentUdi); dev->setCategory(deviceCategory); dev->setBlockName(deviceBlockName); dev->setMajorNumber(major); dev->setBus(deviceBus); dev->setCurrentMountPoint(deviceCurrentMountPoint); dev->setIsMounted(isMounted); if (isVolume(deviceCategory)) { //only volumn device needs connect the hal dbus signal informationCenter->connection().connect(DBUS_HAL_SERVICE,udi,DBUS_HAL_DEVICE_INTERFACE,"PropertyModified", dev,SLOT(propertyModified(int, const QList<ChangeStruct>&))); } //TODO //if is already mounted, open filebrowser mDeviceMap.insert(udi,dev); LOG("*****begin print device struct*****\n"); LOG("deviceUdi:%s ",udi.toLocal8Bit().data()); LOG("deviceCategory:%s ",deviceCategory.toLocal8Bit().data()); LOG("deviceBlockName:%s ",deviceBlockName.toLocal8Bit().data()); LOG("major:%d \n",major); LOG("deviceBus:%s ",deviceBus.toLocal8Bit().data()); LOG("deviceCurrentMountPoint:%s ",deviceCurrentMountPoint.toLocal8Bit().data()); LOG("isMounted:%d \n",isMounted); LOG("*****end print device struct*****\n"); } } bool usbmanager::isVolume(QString value) { QString volume("volume"); if (0 == volume.compare(value,Qt::CaseInsensitive)) { return true; } else { return false; } } bool usbmanager::isDisk(QString value) { QString storage("storage"); if (0 == storage.compare(value,Qt::CaseInsensitive)) { return true; } else { return false; } } bool usbmanager::isBlockDev(QString value) { return value.startsWith("/dev/"); } bool usbmanager::isValidMajor(int value) { return (0 != value); } bool usbmanager::isUsb(QString value) { QString usb("usb"); if (0 == usb.compare(value,Qt::CaseInsensitive)) { return true; } else { return false; } }
weiweiloong 2012-11-23
  • 打赏
  • 举报
回复
#include "haldevice.h" Q_DECLARE_METATYPE(ChangeStruct) Q_DECLARE_METATYPE(QList<ChangeStruct>) const QDBusArgument &operator<<( QDBusArgument &arg, const ChangeStruct &change ) { arg.beginStructure(); arg << change.propertyName << change.added << change.removed; arg.endStructure(); return arg; } const QDBusArgument &operator>>( const QDBusArgument &arg, ChangeStruct &change ) { arg.beginStructure(); arg >> change.propertyName >> change.added >> change.removed; arg.endStructure(); return arg; } haldevice::haldevice(QDBusInterface *interface, const QString& udi) { LOG("%s,%s,%d \n",__FILE__,__FUNCTION__,__LINE__); //init var informationCenter = interface; deviceUdi = udi; deviceIsMounted = false; major = 0; //register dbus meta type qDBusRegisterMetaType<ChangeStruct>(); qDBusRegisterMetaType< QList<ChangeStruct> >(); //connect signal and slot connect(this,SIGNAL(mountedStatusChanged(bool)),this,SLOT(proMountedStatusChanged(bool))); connect(this,SIGNAL(readyBrowserUsb(QString)),this,SLOT(proReadyBrowserUsb(QString))); } haldevice::~haldevice() { delete informationCenter; informationCenter = NULL; //TODO //if filebrowser is open,close it } const QString& haldevice::udi() const { return deviceUdi; } const QString& haldevice::parentUdi() const { return deviceParentUdi; } const QString& haldevice::blockName() const { return deviceBlockName; } const QString& haldevice::category() const { return deviceCategory; } const QString& haldevice::bus() const { return deviceBus; } int haldevice::majorNumber() const { return major; } bool haldevice::isMounted() const { return deviceIsMounted; } bool haldevice::isMountedByDBus() const { LOG("%s,%s,%d \n",__FILE__,__FUNCTION__,__LINE__); QDBusReply<bool> reply = informationCenter->call("GetPropertyBoolean","volume.is_mounted"); return reply.isValid() ? reply.value() : false; } const QString& haldevice::currentMountPointByDBus() { QDBusReply<QString> reply = informationCenter->call("GetPropertyString","volume.mount_point"); //if (reply.isValid()) LOG("%s,%s,%d %s\n",__FILE__,__FUNCTION__,__LINE__,reply.value().toLocal8Bit().data()); return reply.isValid() ? reply.value() : ""; } void haldevice::propertyModified(int numChanges,const QList<ChangeStruct> &changes) { LOG("%s,%s,%d udi=%s numChanges=%d\n",__FILE__,__FUNCTION__,__LINE__,deviceUdi.toLocal8Bit().data(),numChanges); foreach (const ChangeStruct changeStruct, changes) { LOG("%s,%s,%d name:%s %d %d\n",__FILE__,__FUNCTION__,__LINE__,changeStruct.propertyName.toLocal8Bit().data(),changeStruct.added,changeStruct.removed); if (changeStruct.propertyName == "volume.is_mounted") { LOG("%s,%s,%d \n",__FILE__,__FUNCTION__,__LINE__); emit (mountedStatusChanged(isMountedByDBus())); } } } void haldevice::proMountedStatusChanged(bool isMounted) { LOG("%s,%s,%d isMount=%d\n",__FILE__,__FUNCTION__,__LINE__,isMounted); if (isMounted) { emit (readyBrowserUsb(currentMountPointByDBus())); } else { //TODO //close filebrowser and release lib handle LOG("%s,%s,%d close file browser\n",__FILE__,__FUNCTION__,__LINE__); } } void haldevice::proReadyBrowserUsb(QString path) { //call filebrowser lib to browse usb files LOG("%s,%s,%d %s\n",__FILE__,__FUNCTION__,__LINE__,path.toLocal8Bit().data()); //TODO //open filebrowser with path //filebrowser browser; //browser.showFileBrowser(path); } void haldevice::setParentUdi(QString value) { deviceParentUdi = value; } void haldevice::setBlockName(QString value) { deviceBlockName = value; } void haldevice::setCurrentMountPoint(QString value) { deviceCurrentMountPoint = value; } void haldevice::setCategory(QString value) { deviceCategory = value; } void haldevice::setBus(QString value) { deviceBus = value; } void haldevice::setIsMounted(bool value) { deviceIsMounted = value; } void haldevice::setMajorNumber(int value) { major = value; }

16,213

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧