在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;
}
需要自定義類型?
ManagedObjectList
?和?InterfaceList
:
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接口實現