在Linux系统下使用Qt监测U盘的插拔事件

本文介绍如何在Linux系统下使用Qt监测U盘的插入和拔出事件,包括利用sh命令读取lsblk输出并解析,以及通过监听DBus信号实现更高级的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文在Qt提供一段监测U盘数量的一段代码,可以监听U盘的插入和拔出,亲测可用。

#include <QProcess>
#include <QDebug>
void usb_arm64::on_toolButton_clicked()
{
         int i =0;
        QProcess piTerminal;
        piTerminal.start("sh",QStringList()<<"-c"<<"lsblk|grep media|grep part|grep -o -E '/.*'");
        piTerminal.waitForFinished();
        QString ret=piTerminal.readAllStandardOutput();
        QStringList list=ret.split("\n");
        if(list.size()!=1){
            for(i=0;i<list.size();i++){
                qDebug()<<list.at(i);//输出U盘的绝对路径
                ui->textBrowser->append(list.at(i));
                }
        }
        if(list.size()==1){
            qDebug()<<"未检测到U盘插入,请插入后重试";
        }
         ui->textBrowser->append(QString("检测到 %1个U盘").arg(i-1));
}

使用Qt监测U盘的插拔事件也可以通过监听DBus信号实现。以下是分步说明和示例代码:

方法概述

  1. 使用DBus监听U盘事件:通过org.freedesktop.UDisks2服务,订阅InterfacesAddedInterfacesRemoved信号。
  2. 过滤U盘设备:检查信号参数,确定是否为可移动USB存储设备。
  3. 处理挂载信息:通过DBus获取设备的挂载点和其他属性。

实现步骤

1. 添加Qt模块依赖

在Qt项目文件(.pro)中添加DBus模块:

QT += core dbus
2. 连接DBus信号

在代码中连接到系统总线,订阅UDisks2的信号:

#include <QDBusConnection>
#include <QDBusMessage>
#include <QDBusInterface>
#include <QDebug>

class UsbMonitor : public QObject {
    Q_OBJECT
public:
    UsbMonitor(QObject *parent = nullptr) : QObject(parent) {
        // 连接到系统总线
        QDBusConnection systemBus = QDBusConnection::systemBus();
        
        // 订阅InterfacesAdded和InterfacesRemoved信号
        systemBus.connect("org.freedesktop.UDisks2",
                          "/org/freedesktop/UDisks2",
                          "org.freedesktop.DBus.ObjectManager",
                          "InterfacesAdded",
                          this,
                          SLOT(onInterfacesAdded(QDBusObjectPath, QVariantMapMap)));

        systemBus.connect("org.freedesktop.UDisks2",
                          "/org/freedesktop/UDisks2",
                          "org.freedesktop.DBus.ObjectManager",
                          "InterfacesRemoved",
                          this,
                          SLOT(onInterfacesRemoved(QDBusObjectPath, QStringList)));
    }

private slots:
    void onInterfacesAdded(const QDBusObjectPath &object_path, const QVariantMapMap &interfaces) {
        // 检查是否为块设备
        if (interfaces.contains("org.freedesktop.UDisks2.Block")) {
            checkUsbDevice(object_path);
        }
    }

    void onInterfacesRemoved(const QDBusObjectPath &object_path, const QStringList &interfaces) {
        // 检查移除的接口是否为块设备
        if (interfaces.contains("org.freedesktop.UDisks2.Block")) {
            handleDeviceRemoved(object_path);
        }
    }

private:
    void checkUsbDevice(const QDBusObjectPath &block_path) {
        // 获取块设备属性
        QDBusInterface blockInterface("org.freedesktop.UDisks2",
                                      block_path.path(),
                                      "org.freedesktop.UDisks2.Block",
                                      QDBusConnection::systemBus());
        
        QString drive_path = blockInterface.property("Drive").value<QDBusObjectPath>().path();
        if (drive_path.isEmpty()) return;

        // 检查是否为USB设备
        QDBusInterface driveInterface("org.freedesktop.UDisks2",
                                       drive_path,
                                       "org.freedesktop.UDisks2.Drive",
                                       QDBusConnection::systemBus());
        
        bool isRemovable = driveInterface.property("MediaRemovable").toBool();
        QString connectionBus = driveInterface.property("ConnectionBus").toString();
        
        if (isRemovable && connectionBus == "usb") {
            QString deviceName = blockInterface.property("Device").toString();
            qDebug() << "USB设备插入:" << deviceName;
            emit usbDeviceAdded(deviceName);
        }
    }

    void handleDeviceRemoved(const QDBusObjectPath &block_path) {
        qDebug() << "设备移除:" << block_path.path();
        emit usbDeviceRemoved(block_path.path());
    }

signals:
    void usbDeviceAdded(const QString &device);
    void usbDeviceRemoved(const QString &path);
};
3. 使用监控类

在Qt主程序中初始化监控并连接信号:

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    UsbMonitor monitor;
    QObject::connect(&monitor, &UsbMonitor::usbDeviceAdded, [](const QString &dev) {
        qDebug() << "检测到U盘插入:" << dev;
    });
    QObject::connect(&monitor, &UsbMonitor::usbDeviceRemoved, [](const QString &path) {
        qDebug() << "U盘拔出:" << path;
    });

    return app.exec();
}

关键点说明

  1. DBus连接:通过系统总线连接到UDisks2服务,监听设备变化信号。
  2. 设备过滤:在checkUsbDevice中检查设备的ConnectionBus属性是否为usb,并确认是可移动设备。
  3. 异步处理:所有DBus调用均为同步操作,若需高性能可改用异步接口。

权限配置

确保应用有权访问DBus系统服务。可通过创建polkit规则(如/etc/polkit-1/rules.d/50-udisks.rules):

polkit.addRule(function(action, subject) {
    if (action.id == "org.freedesktop.udisks2.filesystem-mount-system" &&
        subject.user == "你的用户名") {
        return polkit.Result.YES;
    }
});

此方案通过Qt的DBus模块实现,能高效监测U盘插拔事件,并获取设备详细信息。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飘飘燃雪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值