利用qt檢測(cè)U盤插拔,思路有用qt的qdbus,dbus接收HAL的消息,或者是接收udisks的消息,這兩種方法在x86平臺(tái)上是可行的,但到板子里就不行。板子里不一定有HAL的,而HAL往板子里移植網(wǎng)上么有半點(diǎn)資料。udisk也沒(méi)有移植的資料。更要命的是,不管hal也好udisks也好,他們得到的消息都是udev發(fā)過(guò)來(lái)的。而udev需要sysfs文件系統(tǒng)的支持,但現(xiàn)在arm板子上大多數(shù)都是yaffs或yaffs2文件系統(tǒng)的支持。盡管有udev移植的資料,但往yaffs、yaffs2文件系統(tǒng)移植,是移植不了的。最后一步配置的時(shí)候,配置不了。
灑家最終要在tiny210開(kāi)發(fā)板上實(shí)現(xiàn)此功能,難道走投無(wú)路了么?? 發(fā)火 非也,參考我的上篇博客,linux整個(gè)處理usb的消息機(jī)制是這樣的:內(nèi)核----hotplug機(jī)制----udev---------HAL/UDISKS--------dbus.盡管網(wǎng)上很多人說(shuō)hotplug淘汰了,但貌似現(xiàn)在開(kāi)發(fā)板上用的都是hotplug。因此如果要用qt實(shí)現(xiàn)檢測(cè)arm上U盤插拔的話,hotplug才是正道,不要貪了qt封裝好的幾個(gè)QDBUS接口的函數(shù)!
這篇文章就先談一下,pc機(jī)上用qt自帶的qdbus類,得到hal或udisks消息,來(lái)實(shí)現(xiàn)檢測(cè)U盤插拔。咱廢話多不說(shuō),請(qǐng)看程序:
1,widget.h里面添加:
#include <QtDBus/QDBusInterface>
#include <QtDBus/QDBusConnection> //QDBusConnection
#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("初始化錯(cuò)誤,找不到QDBusInterface!")<<QDBusConnection::systemBus().lastError().message(); connect(dBusInterface, SIGNAL(DeviceAdded(QString)), this, SLOT(slotDeviceAdded(QString))); connect(dBusInterface, SIGNAL(DeviceRemoved(QString)), this, SLOT(slotDeviceRemoved(QString)));
然后就是兩個(gè)槽函數(shù):
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("創(chuàng)建device失敗!"); else num++; QString devicePath = device->path(); qDebug()<<tc->toUnicode("正在識(shí)別usb_device")<<num<<tc->toUnicode("號(hào)----路徑:")<<devicePath; if(devicePath.contains("volume")) { qDebug()<<tc->toUnicode("恭喜您,U盤找到了。name:")<<udi; currentUDI = udi; } else qDebug()<<tc->toUnicode("識(shí)別結(jié)果:不是USB存儲(chǔ)設(shè)備!"); } 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就是注冊(cè)u(píng)sb設(shè)備的路徑!大家可以打印出來(lái)看看,注冊(cè)的時(shí)候大概注冊(cè)了七個(gè),拔出U盤的時(shí)候也是打印了7個(gè)消息。如果沒(méi)有前面頭文件的.h里的define,可以在widget.CPP文件里new QDBusInterface時(shí)候直接寫上。這里我推薦用這種先聲明一個(gè)變量,然后連接槽函數(shù)的方法。網(wǎng)上有人做法如下:
// // 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 )));
也是可以的!
最坑爹的是有些人只說(shuō)DBUS_HAL_SERVICE、DBUS_HAL_PATH不交代前面的宏定義!
另外就是,如果不想通過(guò)hal得到消息,可以通過(guò)udisks得到消息,如下:
QDBusConnection :: systemBus ( ). connect ( "org.freedesktop.UDisks" , "/org/freedesktop/UDisks" , "org.freedesktop.UDisks" , "DeviceAdded" , this , SLOT (deviceAdded ( QDBusObjectPath ) ) ; void deviceAdded ( QDBusObjectPath dev ) { qDebug ( ) << "device added!" <<dev. path ( ) ; }
這樣就是通過(guò)udisks來(lái)檢測(cè),至于原理大家看我前面博文把。
網(wǎng)上有個(gè)公開(kāi)的用此思路寫的較為完整的源碼: http://download.csdn.net/detail/yanzi1225627/4507716 ,具體能運(yùn)行否我沒(méi)試。
另外,老外的 http://qt-project.org/forums/viewthread/8595 這個(gè)比較好。
本文為張軍原創(chuàng)文章,轉(zhuǎn)載無(wú)需和我聯(lián)系,但請(qǐng)注明來(lái)自張軍的軍軍小站,個(gè)人博客http://www.eyofj.com
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
