Qt学习|Qt开发简易蓝牙调试助手(低功耗蓝牙)

概述 Qt中是有蓝牙模块的,直接用此模块开发就行。但是注意使用的是低功耗蓝牙的类,连接方式和经典蓝牙会有区别
大致的连接步骤是:

  1. 搜索附近的蓝牙设备
  2. 连接指定的蓝牙设备
  3. 获取服务
  4. 指定服务进行连接(因为每一种下的特征对象的权限是不一样的,有的只有读取权限,没有写权限,有的则相反,必要时可以直接打印一下查看)
  5. 获取服务下可用的特征对象
  6. 监听特征对象的消息变化和向特征对象发送消息
界面设计 Qt学习|Qt开发简易蓝牙调试助手(低功耗蓝牙)
文章图片

Qt学习|Qt开发简易蓝牙调试助手(低功耗蓝牙)
文章图片

Qt学习|Qt开发简易蓝牙调试助手(低功耗蓝牙)
文章图片

代码设计
主界面的.cpp和.h
#include "mainwindow.h" #include "ui_mainwindow.h" #include "QBluetoothLocalDevice"MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); //连接设备按钮点击事件 this->btConnect = new BluetoothConnect(); connect(ui->btnConnectDevice,&QPushButton::clicked,[=](){ //this->hide(); btConnect->show(); }); //监听连接设备窗口发送的连接服务信号 connect(btConnect,&BluetoothConnect::toConectCharacteristic,this,&MainWindow::ConnectCharacteristic); //数据发送按钮点击事件 connect(ui->btnSend,&QPushButton::clicked,[=](){ //发送数据 btConnect->m_service->writeCharacteristic(btConnect->m_characteristic,ui->leSendData->text().toUtf8(),QLowEnergyService::WriteMode::WriteWithoutResponse); }); //关闭数据接收按钮点击事件 connect(ui->btnClose,&QPushButton::clicked,[=](){ if(this->isClose) { ui->btnClose->setText("开启"); this->isClose = false; } else { ui->btnClose->setText("关闭"); this->isClose = true; } }); //清除数据接受区内容按钮点击事件 connect(ui->btnClear,&QPushButton::clicked,[=](){ ui->tbRevData->clear(); }); }void MainWindow::ConnectCharacteristic(QLowEnergyService * m_service) { // 通过监听特征对象的变化 //写的和读取到的都会进入到这个位置 connect(m_service,&QLowEnergyService::characteristicChanged,[=](QLowEnergyCharacteristic c,QByteArray value) { //qDebug() << "characteristicChanged state change::"; //qDebug() << "value length::" << value.length(); //qDebug() << "value length::" << value; if(this->isClose) { ui->tbRevData->append(value); } }); //没有写响应属性的Characteristic不会进入这个连接 //connect(m_service,&QLowEnergyService::characteristicWritten,[=](QLowEnergyCharacteristic c,QByteArray value) { qDebug() << "characteristicChanged state change::"; qDebug() << "value length::" << value.length(); qDebug() << "value length::" << value; //}); //service错误监听 connect(m_service,&QLowEnergyService::errorOccurred,[=](QLowEnergyService::ServiceError newErrorr){ if(QLowEnergyService::NoError == newErrorr) { qDebug() <<"没有发生错误。"; } if(QLowEnergyService::OperationError==newErrorr) { qDebug() <<"错误: 当服务没有准备好时尝试进行操作!"; } if(QLowEnergyService::CharacteristicReadError==newErrorr) { qDebug() <<"尝试读取特征值失败!"; } if(QLowEnergyService::CharacteristicWriteError==newErrorr) { qDebug() <<"尝试为特性写入新值失败!"; } if(QLowEnergyService::DescriptorReadError==newErrorr) { qDebug() <<"尝试读取描述符值失败!"; } if(QLowEnergyService::DescriptorWriteError==newErrorr) { qDebug() <<" 尝试向描述符写入新值失败!"; } if(QLowEnergyService::UnknownError==newErrorr) { qDebug() <<"与服务交互时发生未知错误!"; }}); }MainWindow::~MainWindow() { delete ui; }

#ifndef MAINWINDOW_H #define MAINWINDOW_H#include #include "bluetoothconnect.h"QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACEclass MainWindow : public QMainWindow { Q_OBJECTpublic: MainWindow(QWidget *parent = nullptr); ~MainWindow(); BluetoothConnect *btConnect; bool isClose = true; void ConnectCharacteristic(QLowEnergyService * m_service); private: Ui::MainWindow *ui; }; #endif // MAINWINDOW_H

连接界面的.cpp和.h
#include "bluetoothconnect.h" #include "ui_bluetoothconnect.h"BluetoothConnect::BluetoothConnect(QWidget *parent) : QMainWindow(parent), ui(new Ui::BluetoothConnect) { ui->setupUi(this); //设置设备列表的标题 QListWidgetItem *item = new QListWidgetItem(); //创建自定义的窗口 然后放入到listwidget中 BtDevCell *bdc = new BtDevCell(); //设置item的高 item->setSizeHint(QSize(ui->lwShow->width(),bdc->height())); //设置label的显示 bdc->btName->setText("名称"); bdc->btAddr->setText("地址"); bdc->btRssi->setText("信号强度"); //把item加入到listwidget ui->lwShow->addItem(item); //设置item的窗口为自定义的窗口 ui->lwShow->setItemWidget(item,bdc); //设置服务列表的标题 QListWidgetItem *items = new QListWidgetItem(); //创建自定义的窗口 然后放入到listwidget中 BtDevCell *bdcs = new BtDevCell(); //把item加入到listwidget items->setSizeHint(QSize(ui->lwService->width(),bdcs->height())); //设置label的显示 bdcs->btName->setText("空"); bdcs->btAddr->setText("服务Uuid"); bdcs->btRssi->setText("空"); //设置item的窗口为自定义的窗口 ui->lwService->addItem(items); //设置item的窗口为自定义的窗口 ui->lwService->setItemWidget(items,bdcs); //创建通信的socket 普通蓝牙使用 //QBluetoothSocket *btSocket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol,this); //创建设备发现对象 QBluetoothDeviceDiscoveryAgent *discoveryAgent = new QBluetoothDeviceDiscoveryAgent(this); //点击搜索设备后开始搜索设备 connect(ui->btnSerachDevice,&QPushButton::clicked,[=](){ qDebug() << "开始搜索设备"; //如果已经搜索过一次了,那么设计列表可能就大于1,那么就清空设备列表 //但是标题也会被清除,所以重新构建 if(ui->lwShow->count()>1) { ui->lwShow->clear(); //设置设备列表的标题 QListWidgetItem *item = new QListWidgetItem(); //创建自定义的窗口 然后放入到listwidget中 BtDevCell *bdc = new BtDevCell(); //设置item的高 item->setSizeHint(QSize(ui->lwShow->width(),bdc->height())); //设置label的显示 bdc->btName->setText("名称"); bdc->btAddr->setText("地址"); bdc->btRssi->setText("信号强度"); //把item加入到listwidget ui->lwShow->addItem(item); //设置item的窗口为自定义的窗口 ui->lwShow->setItemWidget(item,bdc); }//开始搜索设备 discoveryAgent->start(); }); //搜索到设备后进入 connect(discoveryAgent,&QBluetoothDeviceDiscoveryAgent::deviceDiscovered,[=](QBluetoothDeviceInfo devInfo){ qDebug() << "搜索到设备"; //名称不为空且是低功耗蓝牙 if(devInfo.name() != "" && (devInfo.coreConfigurations() & QBluetoothDeviceInfo::LowEnergyCoreConfiguration)) { QListWidgetItem *item = new QListWidgetItem(); BtDevCell *bdc = new BtDevCell(); item->setSizeHint(QSize(ui->lwShow->width(),bdc->height())); bdc->btName->setText(devInfo.name()); bdc->btAddr->setText(devInfo.address().toString()); bdc->btRssi->setText(QString::number(devInfo.rssi())); ui->lwShow->addItem(item); ui->lwShow->setItemWidget(item,bdc); devInfos.append(devInfo); } }); //搜索设备发生错误 connect(discoveryAgent,&QBluetoothDeviceDiscoveryAgent::errorOccurred,[=](QBluetoothDeviceDiscoveryAgent::Error error){ qDebug() << error; //警告对话框 QMessageBox::warning(this,"警告","搜索蓝牙设备发生错误,请检查蓝牙是否开启!"); }); //搜索设备完成 connect(discoveryAgent,&QBluetoothDeviceDiscoveryAgent::finished,[=](){ qDebug() << "搜索完成"; }); //设备列表被点击事件 connect(ui->lwShow,&QListWidget::itemClicked,[=](QListWidgetItem *item){ //这是经典蓝牙的连接方式 //QWidget *widget = ui->lwShow->itemWidget(item); //BtDevCell *wbdc = (BtDevCell *)widget; //qDebug() << wbdc->btAddr->text().toUtf8().data(); //btSocket->connectToService(QBluetoothAddress(wbdc->btAddr->text().toUtf8().data()),QBluetoothUuid("00001101-0000-1000-8000-00805F9B34FB"),QIODevice::ReadWrite); //这是低功耗蓝牙的连接方式 //qDebug() << ui->lwShow->currentRow(); //创建蓝牙控制器 QLowEnergyController *lowBtControl = QLowEnergyController::createCentral(this->devInfos.at(ui->lwShow->currentRow()-1)); //连接设备 lowBtControl->connectToDevice(); //连接成功后进入 connect(lowBtControl,&QLowEnergyController::connected,[=](){ qDebug() << "连接成功"; //搜索服务 lowBtControl->discoverServices(); }); //连接失败后进入 connect(lowBtControl,&QLowEnergyController::errorOccurred,[=](QLowEnergyController::Error newError){ qDebug() << newError; }); //搜索到服务后进入 connect(lowBtControl,&QLowEnergyController::serviceDiscovered, [=](QBluetoothUuid serviceUuid) { qDebug() << "发现服务"; QListWidgetItem *item = new QListWidgetItem(); BtDevCell *bdc = new BtDevCell(); item->setSizeHint(QSize(ui->lwService->width(),bdc->height())); bdc->btName->setText(""); bdc->btAddr->setText(serviceUuid.toString()); bdc->btRssi->setText(""); ui->lwService->addItem(item); ui->lwService->setItemWidget(item,bdc); btUuids.append(serviceUuid); }); //服务uuid列表被点击事件 connect(ui->lwService,&QListWidget::itemClicked,[=](){ QBluetoothUuid serviceUuid = btUuids.at(ui->lwService->currentRow()-1); //创建服务 this->m_service = lowBtControl->createServiceObject(QBluetoothUuid(serviceUuid),this); if(m_service==NULL) { qDebug() << "服务建立失败!"; } else { qDebug() << "服务建立成功!"; // 服务对象创建成功后,坚挺服务状态变化,如果状态变成已发现,则进行后续服务下特征对象获取 connect(m_service,&QLowEnergyService::stateChanged, this, [this]() { //qDebug() << "service state change" << m_service->state(); //发现服务, 建立characteristic对象实例 if(m_service->state() == QLowEnergyService::ServiceDiscovered) {//获取特征对象 QList list=m_service->characteristics(); for(int i=0; im_characteristic = list.at(i); //qDebug() << c.properties(); /*如果QLowEnergyCharacteristic对象有效,则返回true,否则返回false*/ if(m_characteristic.isValid()) { //描述符定义特征如何由特定客户端配置。 QLowEnergyDescriptor m_notificationDesc = m_characteristic.descriptor(QBluetoothUuid::DescriptorType::ClientCharacteristicConfiguration); if(m_notificationDesc.isValid()) { //写描述符 m_service->writeDescriptor(m_notificationDesc, QByteArray::fromHex("0100")); //m_service->writeDescriptor(m_notificationDesc, QByteArray::fromHex("FEE1")); } } } } }); //通知主窗口可以连接service了 emit toConectCharacteristic(m_service); // 触发服务详情发现函数 ,不要忘记调用 m_service->discoverDetails(); } }); }); ////普通蓝牙使用 //connect(btSocket,&QBluetoothSocket::connected,[=](){ //qDebug() << "连接完成"; //}); //connect(btSocket,&QBluetoothSocket::errorOccurred,[=](QBluetoothSocket::SocketError error){ //qDebug() << "连接失败:" <

#ifndef BLUETOOTHCONNECT_H #define BLUETOOTHCONNECT_H#include #include "QLowEnergyController" #include "QBluetoothLocalDevice" #include "QBluetoothDeviceDiscoveryAgent" #include "QBluetoothSocket" #include "QDebug" #include "QListWidgetItem" #include "btdevcell.h" #include "QLabel" #include "QMessageBox" #include "QLowEnergyDescriptor" #include "QLowEnergyService" #include "QBluetoothUuid" #include "QTimer"namespace Ui { class BluetoothConnect; }class BluetoothConnect : public QMainWindow { Q_OBJECTpublic: explicit BluetoothConnect(QWidget *parent = nullptr); ~BluetoothConnect(); QList devInfos; QList btUuids; QLowEnergyService * m_service; QLowEnergyCharacteristic m_characteristic; void searchCharacteristic(); private: Ui::BluetoothConnect *ui; signals: void toConectCharacteristic(QLowEnergyService * m_service); }; #endif // BLUETOOTHCONNECT_H

listWidget Item界面.cpp和.h
#include "btdevcell.h" #include "ui_btdevcell.h"BtDevCell::BtDevCell(QWidget *parent) : QWidget(parent), ui(new Ui::BtDevCell) { ui->setupUi(this); this->btName = ui->btName; this->btAddr = ui->btAddr; this->btRssi = ui->btRssi; }BtDevCell::~BtDevCell() { delete ui; }

#ifndef BTDEVCELL_H #define BTDEVCELL_H#include #include "QLabel"namespace Ui { class BtDevCell; }class BtDevCell : public QWidget { Q_OBJECTpublic: explicit BtDevCell(QWidget *parent = nullptr); ~BtDevCell(); QLabel *btName; QLabel *btAddr; QLabel *btRssi; private: Ui::BtDevCell *ui; }; #endif // BTDEVCELL_H

运行演示 Qt学习|Qt开发简易蓝牙调试助手(低功耗蓝牙)
文章图片

Qt学习|Qt开发简易蓝牙调试助手(低功耗蓝牙)
文章图片

【Qt学习|Qt开发简易蓝牙调试助手(低功耗蓝牙)】

    推荐阅读