【蓝牙】Linux Qt4查看已经配对的蓝牙信息

在Linux系统中使用Qt4查看已配对的蓝牙设备信息,可以基于DBus与BlueZ(Linux下的蓝牙协议栈)进行交互。以下是一个实现方案:

1. 引入必要的库和头文件

确保项目中包含DBus相关的头文件,并链接QtDBus模块:

cpp

复制代码
#include <QDBusInterface>
#include <QDBusReply>
#include <QDBusObjectPath>
#include <QVariantMap>

2. 定义DBus常量

用于连接BlueZ服务的DBus接口、服务名和路径:

cpp

复制代码
#define BLUEZ_DBUS_SERVICE  "org.bluez"
#define BLUEZ_DBUS_PATH "/org/bluez/hci0"
#define BLUEZ_DBUS_IF "org.bluez.Adapter1"

3. 获取已管理对象(Managed Objects)

通过调用org.freedesktop.DBus.ObjectManager接口的GetManagedObjects方法,可以获取所有蓝牙设备的信息。

cpp

复制代码
QVariantMap getManagedObjects()
{
    QDBusInterface manager(BLUEZ_DBUS_SERVICE, "/",
                           "org.freedesktop.DBus.ObjectManager", QDBusConnection::systemBus());

    QDBusReply<ManagedObjectList> reply = manager.call("GetManagedObjects");

    if (!reply.isValid()) {
        qWarning() << "Failed to get managed objects:" << reply.error().message();
        return QVariantMap();
    }

    ManagedObjectList objects = reply.value();
    QVariantMap result;

    foreach (const QDBusObjectPath &path, objects.keys()) {
        InterfaceList interfaces = objects.value(path);
        foreach (const QString &interface, interfaces.keys()) {
            result[path.path()] = interfaces.value(interface);
        }
    }

    return result;
}

需要自定义类型 ManagedObjectListInterfaceList

cpp

复制代码
typedef QMap<QString, QVariantMap> InterfaceList;
typedef QMap<QDBusObjectPath, InterfaceList> ManagedObjectList;

Q_DECLARE_METATYPE(InterfaceList)
Q_DECLARE_METATYPE(ManagedObjectList)

4. 过滤已配对的蓝牙设备

遍历返回的对象,提取出org.bluez.Device1接口中的设备信息,并筛选出已配对的设备。

cpp

复制代码
void getPairedDevices(BluetoothDeviceList_t &deviceList)
{
    QVariantMap objects = getManagedObjects();
    QSet<QString> uniqueAddresses; // 去重

    foreach (const QString &path, objects.keys()) {
        QVariantMap deviceProps = objects[path].toMap();

        if (deviceProps.contains("Name") && deviceProps.contains("Address") &&
            deviceProps.contains("Paired")) {
            QString name = deviceProps["Name"].toString();
            QString address = deviceProps["Address"].toString();
            bool paired = deviceProps["Paired"].toBool();

            if (!name.isEmpty() && !uniqueAddresses.contains(address) && paired) {
                uniqueAddresses.insert(address);

                BluetoothDevice_t device;
                device.address = address;
                device.Name = name;
                device.Paired = paired;
                device.Connected = deviceProps["Connected"].toBool();
                device.Icon = deviceProps["Icon"].toString();

                deviceList << device;
            }
        }
    }
}

5. 数据结构定义

定义蓝牙设备的数据结构:

cpp

复制代码
struct BluetoothDevice_t {
    QString address;
    QString Name;
    QString Icon;
    QString Alias;
    bool Connected;
    bool Paired;
};

typedef QList<BluetoothDevice_t> BluetoothDeviceList_t;

6. 注册元类型

为了让Qt支持跨线程传递自定义结构体,需要注册元类型:

cpp

复制代码
qRegisterMetaType<BluetoothDevice_t>("BluetoothDevice_t");
qRegisterMetaType<InterfaceList>("InterfaceList");
qRegisterMetaType<ManagedObjectList>("ManagedObjectList");

7. 展示设备列表

将获取到的设备列表展示在QTableWidget中:

cpp

复制代码
void setPairedDeviceList(const BluetoothDeviceList_t &deviceList)
{
    int row_count = deviceList.count();
    if (row_count <= 0) return;

    ui->tableWidget->setRowCount(row_count);
    ui->tableWidget->setColumnCount(1);

    for (int row = 0; row < row_count; ++row) {
        const BluetoothDevice_t &device = deviceList.at(row);
        QTableWidgetItem *item = new QTableWidgetItem(device.Name);
        item->setData(Qt::UserRole, device.address);
        item->setData(Qt::UserRole + 1, device.Paired);
        item->setData(Qt::UserRole + 2, device.Connected);

        QBrush brush = QColor(0, 0, 0);
        if (device.Connected && device.Paired) {
            brush = QColor(0x00DC00); // 绿色
        } else if (device.Paired) {
            brush = QColor(0x3E81DA); // 蓝色
        }

        item->setForeground(brush);
        ui->tableWidget->setItem(row, 0, item);
    }

    ui->tableWidget->selectRow(0);
}

8. 完整流程

  • 初始化UI:设置表格样式、隐藏表头等。
  • 获取设备列表:调用getPairedDevices()
  • 设置设备列表:调用setPairedDeviceList()显示到界面上。

示例运行效果

该程序会列出所有已配对的蓝牙设备名称和地址,并根据是否连接显示不同的颜色。


如需进一步扩展功能,例如连接/断开设备发送文件等,可以通过调用BlueZ提供的DBus接口实现

相关推荐
屿行屿行44 分钟前
【Linux】Socket编程(基于实际工程分析)
linux·服务器·网络
天才程序YUAN1 小时前
从零开始、保留 Windows 数据、安装Ubuntu 22.04 LTS双系统
linux·windows·ubuntu
Evan芙1 小时前
Rocky Linux 9 网卡改名及静态IP地址配置完整步骤
linux·网络·智能路由器
Zeku1 小时前
20251125 - 韦东山Linux第三篇笔记【上】
linux·笔记·单片机
企鹅侠客2 小时前
Linux性能调优 详解磁盘工作流程及性能指标
linux·运维·服务器·性能调优
icy、泡芙2 小时前
TF卡---热插拔
linux·驱动开发
企鹅侠客2 小时前
Linux性能调优 再谈磁盘性能指标和进程级IO
linux·运维·服务器·性能调优
wdfk_prog2 小时前
[Linux]学习笔记系列 -- [block][mq-deadline]
linux·笔记·学习
不过普通话一乙不改名3 小时前
Linux 网络收包的进阶之路:从普通 socket 到 AF_XDP 零拷贝
linux·运维·网络
Zeku3 小时前
20251125 - 韦东山Linux第三篇笔记【中】
linux·驱动开发