读书人

x86上 linux qt检测U盘插拔(一)- HA

发布时间: 2012-09-11 10:49:03 作者: rapoo

x86下 linux qt检测U盘插拔(一)------- HAL 与UDISKS

非也,参考我的上篇博客,linux整个处理usb的消息机制是这样的:内核----hotplug机制----udev---------HAL/UDISKS--------dbus.尽管网上很多人说hotplug淘汰了,但貌似现在开发板上用的都是hotplug。因此如果要用qt实现检测arm上U盘插拔的话,hotplug才是正道,不要贪了qt封装好的几个QDBUS接口的函数!

#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_PATH "/org/freedesktop/Hal/devices"#define DBUS_HAL_DEVICE_INTERFACE "org.freedesktop.Hal.Device"


private slots:
void slotDeviceAdded(QString udi);
void slotDeviceRemoved(QString udi);

2,widget.cpp里面添加

QDBusInterface *dBusInterface = new QDBusInterface(DBUS_HAL_SERVICE,
DBUS_HAL_PATH,
DBUS_HAL_INTERFACE,
QDBusConnection::systemBus(),
this);

if(!dBusInterface->isValid())
qDebug()<<tc->toUnicode("初始化错误,找不到QDBusInterface!")<<QDBusConnection::systemBus().lastError().message();
connect(dBusInterface, SIGNAL(DeviceAdded(QString)), this, SLOT(slotDeviceAdded(QString)));
connect(dBusInterface, SIGNAL(DeviceRemoved(QString)), this, SLOT(slotDeviceRemoved(QString)));

然后就是两个槽函数:

void Widget::slotDeviceAdded(QString udi)
{
static int num = 0;
QDBusInterface *device = new QDBusInterface(DBUS_HAL_SERVICE, udi, DBUS_HAL_DEVICE_INTERFACE, QDBusConnection::systemBus(), this);

if(!device->isValid())
qDebug()<<tc->toUnicode("创建device失败!");
else
num++;
QString devicePath = device->path();
qDebug()<<tc->toUnicode("正在识别usb_device")<<num<<tc->toUnicode("号----路径:")<<devicePath;
if(devicePath.contains("volume"))
{
qDebug()<<tc->toUnicode("恭喜您,U盘找到了。name:")<<udi;
currentUDI = udi;
}
else
qDebug()<<tc->toUnicode("识别结果:不是USB存储设备!");

}

void Widget::slotDeviceRemoved(QString udi)
{

if(udi == currentUDI || udi.contains("volume"))
{
qDebug()<<tc->toUnicode("您的U盘已弹出!")<<udi;
currentUDI = "";
}
else
qDebug()<<"usb_device="<<udi<<tc->toUnicode("已弹出---");
}

这里的udi就是注册usb设备的路径!大家可以打印出来看看,注册的时候大概注册了七个,拔出U盘的时候也是打印了7个消息。如果没有前面头文件的.h里的define,可以在widget.CPP文件里new QDBusInterface时候直接写上。这里我推荐用这种先声明一个变量,然后连接槽函数的方法。网上有人做法如下:

// // 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 )));

也是可以的!

最坑爹的是有些人只说DBUS_HAL_SERVICE、DBUS_HAL_PATH不交代前面的宏定义!

另外就是,如果不想通过hal得到消息,可以通过udisks得到消息,如下:

  1. QDBusConnection::systemBus().connect(
  2. "org.freedesktop.UDisks",
  3. "/org/freedesktop/UDisks",
  4. "org.freedesktop.UDisks",
  5. "DeviceAdded",
  6. this, SLOT(deviceAdded(QDBusObjectPath));
  7. void deviceAdded(QDBusObjectPath dev){
  8. qDebug()<<"device added!"<<dev.path();
  9. }

这样就是通过udisks来检测,至于原理大家看我前面博文把。

网上有个公开的用此思路写的较为完整的源码:http://download.csdn.net/detail/yanzi1225627/4507716,具体能运行否我没试。

另外,老外的http://qt-project.org/forums/viewthread/8595这个比较好。

读书人网 >UNIXLINUX

热点推荐