Qt监听热插拔事件

INUX2.6.13内核下是没有USB插拔 机制 的,即便是2.6.24内核依旧没有 解决 好USB插拔通知问题,而QT在版本4之前的版本都没有USB类的,没有USB插拔通知的方法,在QT4之后有了QDBUS,可通过QDBUS,进行USB热插拔
1、在QT4之后有了QDBUS,可通过QDBUS,进行USB热插拔
在pro 文件 中应该加入

QT +=dbus

//以下为检测设备的插入
      QDBusConnection::systemBus().connect(    "org.freedesktop.Hal",
                        "/org/freedesktop/Hal/Manager",
                        "org.freedesktop.Hal.Manager",
                        "DeviceAdded",
                        this,
                        SLOT(slotDeviceAdded(QString )));
//以下为检查设备的拨出
    QDBusConnection::systemBus().connect(    "org.freedesktop.Hal",
                        "/org/freedesktop/Hal/Manager",
                        "org.freedesktop.Hal.Manager",
                        "DeviceRemoved",
                        this,
                        SLOT(slotDeviceRemoved(QString )));

在slotDeviceAdded(QString udi)函数中,要使用到

QDBusInterface device("org.freedesktop.Hal", udi, "org.freedesktop.Hal.Device" , QDBusConnection::systemBus());
通过HAL可以查询到设备为volume的设备,然后通过判断是否为/dev/sd*的设备,就可以判断出是否为U盘,然后调用mount就可以了。
这时记录下U盘的UDI,在检测到设备拨出时,再查询一下U盘的UDI是否还在,就知道U盘是否被拨出了。

这是采用QDBUS应该行的通的办法。

但是我没有去验证过,因为我目前还一直用的QT2.1.3,QTOPIA2.2的库,其中没有QDBUS,QT3也没有QDBUS类,没尝试过将QDBUS拿到QT2来用。

2、可以通过UDEV规则
通过UDEV规则编写,能够实现热插拔,但是还是不能做到即时通知

KERNEL=="sd[b-z]", NAME="%k", SYMLINK+="usb1", OPTIONS="last_rule"
#ACTION=="add", KERNEL=="sd[b-z][0-9]", SYMLINK+="usb%n", GROUP="users", NAME="%k"

#auto mount u disk
ACTION=="add", KERNEL=="sd[b-z][0-9]", RUN+="/bin/mkdir -p /mnt/usb1"

ACTION=="add", KERNEL=="sd[b-z][0-9]", RUN+="/bin/mount -t vfat /dev/%k /mnt/usb1"
ACTION=="add", KERNEL=="sd[b-z]", RUN+="/bin/mkdir -p /mnt/usb1"
ACTION=="add", KERNEL=="sd[b-z]",RUN+="/bin/mount -t vfat /dev/%k /mnt/usb1"

#autu mount sd card
ACTION=="add", KERNEL=="mmcblk[0-9][b-z][0-9]", RUN+="/bin/mkdir -p /mnt/mmc%n"

ACTION=="add", KERNEL=="mmcblk[0-9][b-z][0-9]", RUN+="/bin/mount -t vfat /dev/%k /mnt/mmc%n"

#ACTION=="add", KERNEL=="sd[a-z][0-9]", PROGRAM=="/lib/udev/vol_id -t %N", RESULT=="vfat", RUN+="/bin/mount -t vfat -o rw,noauto,sync,dirsync,noexec,nodev,noatime,dmask=000,fmask=111 /dev/%k /mnt/usb%n", OPTIONS="last_rule"

#ACTION=="add", KERNEL=="sd[a-z][0-9]", RUN+="/bin/mount -t auto -o rw,noauto,sync,dirsync,noexec,nodev,noatime /dev/%k /mnt/usb%n", OPTIONS="last_rule"
ACTION=="remove", KERNEL=="sd[b-z][0-9]", RUN+="/bin/umount -l /mnt/usb1"

ACTION=="remove", KERNEL=="sd[b-z][0-9]", RUN+="/bin/rm -rf /mnt/usb1", OPTIONS="last_rule"
ACTION=="remove",KERNEL=="sd[b-z}", RUN+="/bin/umount -l /mnt/usb1"
ACTION=="remove",KERNEL=="sd[b-z]",RUN+="/bin/rm -rf /mnt/usb1",OPTIONS="last_rule"

其实是通过UDEV进行自动挂载和卸载USB,其设备号是罗列的,自己可以根据情况变化。
该方法USB的挂载情况依然无法实时通知给QT应用程序

3、修改启动文件
在/etc/init.d/rcS
添加
mount -t vfat /dev/sda1 /mnt/usb2
实现上机自动挂载
这个则只能实现U盘硬件自动启动挂载,离题都很远了。

4、采用定时机制
采用定时轮询方式,开启定时器,查询文件 /proc/MOUNT 或/proc/partition文件情况,读取相关信息,当该文件和分区情况有变化时,进行通知以及系统挂载。
该方法能解决相对问题,但增加系统负载,以及浪费定时器资源。

5、监测LINUX终端信息
LINUX本身对USB是有监测的,现在的问题是如何将LINUX监测的终端输出结果,顺利的给QT程序读取,同时QT进行挂载以及卸载操作,该方法在尝试。怎么将终端的输出结果顺利被LINUX进行检测到,采取的方法可以是LINUX对终端输出进行重定向,然后通过监测字段,发现USB变动情况。

A: 在 Linux 中,可以使用 UDev(Linux Kernel 中的一个守护程序)监听 USB 设备的插入和拔出事件。通过 UDev ,我们可以使用 Qt 的 QProcess 来与 UDev 通信,并监测 U 盘的热插拔事件。以下是使用 UDevQt 进行 U 盘热插拔检测的实现步骤: 1. 引入 Qt 的 QProcess 类和 UDev 头文件: ``` c++ #include <QProcess> #include <libudev.h> ``` 2. 定义 UDev 上下文和监听器: ``` c++ struct udev *udev; struct udev_monitor *mon; ``` 3. 初始化 UDev 上下文和监听器: ``` c++ udev = udev_new(); mon = udev_monitor_new_from_netlink(udev, "udev"); udev_monitor_filter_add_match_subsystem_devtype(mon, "usb", "usb_device"); udev_monitor_enable_receiving(mon); ``` 4. 初始化 Qt 的 QProcess 实例用于运行监测程序: ``` c++ QProcess *process = new QProcess(this); ``` 5. 启动监测程序并循环监听 UDev 中的事件: ``` c++ process->start("udevadm monitor --udev -s usb"); while (/*!done*/ true) { fd_set fds; FD_ZERO(&fds); FD_SET(udev_monitor_get_fd(mon), &fds); if (select(udev_monitor_get_fd(mon) + 1, &fds, nullptr, nullptr, nullptr) > 0) { if (FD_ISSET(udev_monitor_get_fd(mon), &fds)) { struct udev_device *dev = udev_monitor_receive_device(mon); // 对设备的属性和信息进行分析 udev_device_unref(dev); } } } ``` 通过以上实现,我们可以在 Linux 中使用 Qt 监测 U 盘的热插拔事件。需要注意的是,在实现中需要对 UDev 中的设备信息进行分析,并且需要在程序结束时释放 UDev 相关的数据结构。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值