行业知识
Qt开发上位机软件建立经典蓝牙通讯
2026-10-21 10:11:09
来源:互联网转载
Qt开发上位机软件建立经典蓝牙通讯
之前做了一个具���经典蓝牙通讯功能的Windows上位机软件,在网上学习了相关博客以及参考了官方经典蓝牙例程之后,总结出了使用Qt建立经典蓝牙通讯的步骤,附带相关源码,作为分享
开发环境
我使用的Qt版本是5.15,使用的CMake构建项目。
整体开发使用的IDE是Qt Creator,采用的方式是基于widgets的ui设计界面、C++写逻辑的方式。
编译使用的是Desktop Qt 5.15.2 MINGW 64-bit
CMake配置
经典蓝牙通讯需要用到Qt的蓝牙模块,需要添加Bluetooth模块:
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Widgets Bluetooth) #寻找Bluetooth模块find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Widgets Bluetooth) #寻找Bluetooth模块 在add_executable之后设置target_link_libraries:
target_link_libraries(bluetooth_serial_host_computer PRIVATE Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Bluetooth #添加蓝牙 ) 包含头文件
#include //本地设备#include //设备发现#include //蓝牙套接字#include //蓝牙uuid#include //服务发现#include //服务信息
建立经典蓝牙通讯
建立经典蓝牙通讯的基本步骤如下:
首先是在构造函数中的初始化操作:
//创建设备发现对象m_deviceDiscoveryAgent = new QBluetoothDeviceDiscoveryAgent(this);m_btLocalDevice = new QBluetoothLocalDevice(); //创建本地设备对象m_btSocket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol); //蓝牙套接字QBluetoothAddress adapterAddress = m_btLocalDevice->address(); //使用默认蓝牙适配器m_serviceDiscoveryAgent = new QBluetoothServiceDiscoveryAgent(adapterAddress); //创建服务发现对象//连接信号与槽(deviceDiscoveryAgent是代码中自己声明的对象,ui中没有,无法自动生成槽函数;需要自己写槽函数,自己连接)/*-------------------- 初始化设备列表与服务列表 -----------------*///设置设备列表QListWidgetItem* item = new QListWidgetItem();//创建自定义窗口,放入到listwidget中BluetoothDeviceCell* btDevCell = new BluetoothDeviceCell();//设置item的高item->setSizeHint(QSize(ui->deviceListWidget->width(), btDevCell->height()));//设置label显示//第一个加进去的item在最上面,相当于标题btDevCell->m_btName->setText("名称");btDevCell->m_btAddr->setText("地址");btDevCell->m_btRssi->setText("信号强度");//将item加入到listwidget中ui->deviceListWidget->addItem(item);//设置item的窗口为自定义的窗口ui->deviceListWidget->setItemWidget(item, btDevCell);//设置服务列表的标题QListWidgetItem* items = new QListWidgetItem();//创建自定义窗口,放入到listwidget中BluetoothDeviceCell* btDevCells = new BluetoothDeviceCell();//设定item的尺寸items->setSizeHint(QSize(ui->serviceListWidget->width(), btDevCells->height()));//设置label的显示//第一个加进去的item在最上面,相当于标题btDevCells->m_btName->setText("名称");btDevCells->m_btAddr->setText("服务Uuid");btDevCells->m_btRssi->setText("空");//将item加入到listwidget中ui->serviceListWidget->addItem(items);//设置item的窗口为自定义的窗口ui->serviceListWidget->setItemWidget(items, btDevCells);/*------------- m_deviceDiscoveryAgent设备搜索对象的信号槽 -------------*/connect(m_deviceDiscoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, this, &BluetoothConnect::deviceDiscoveredSlot);//发现设备connect(m_deviceDiscoveryAgent, &QBluetoothDeviceDiscoveryAgent::finished, this, &BluetoothConnect::deviceSearchFinishedSlot);//搜索完毕void (QBluetoothDeviceDiscoveryAgent:: *deviceSearchErrorOccurred)(QBluetoothDeviceDiscoveryAgent::Error) = &QBluetoothDeviceDiscoveryAgent::error;//有重载connect(m_deviceDiscoveryAgent, deviceSearchErrorOccurred, this, &BluetoothConnect::deviceSearchErrorOccurredSlot);//设备搜索发生错误/*------------- m_btSocket蓝牙套接字的信号槽 ----------------*/void (QBluetoothSocket:: *socketErrorOccurred)(QBluetoothSocket::SocketError) = &QBluetoothSocket::error;connect(m_btSocket, socketErrorOccurred, this, &BluetoothConnect::socketErrorOccurredSlot); //错误处理槽函数connect(m_btSocket, &QBluetoothSocket::connected, this, &BluetoothConnect::socketConnectedSlot);//连接成功/*------------- m_serviceDiscoveryAgent服务发现对象的信号槽 ---------------*/connect(m_serviceDiscoveryAgent, &QBluetoothServiceDiscoveryAgent::serviceDiscovered, this, &BluetoothConnect::serviceDiscoveredSlot); //发现一个服务connect(m_serviceDiscoveryAgent, &QBluetoothServiceDiscoveryAgent::finished, this, &BluetoothConnect::serviceSearchFinishedSlot); //服务搜索完毕 deviceListWidget和serviceListWidget是我在ui中设置的两个列表组件,用来存放设备和服务信息。
搜索设备
利用QBluetoothDeviceDiscoveryAgent的start方法即可开启设备搜索:
void BluetoothConnect::on_searchButton_clicked() //点击Search按钮后开始搜索设备{ //如果已经搜索过1次,那么设备列表可能会大于1,需要先清空设备列表 //但是标题也会被清除,所以重新添加标题 if(ui->deviceListWidget->count() > 1) { ui->deviceListWidget->clear(); //设置设备列表 QListWidgetItem* item = new QListWidgetItem(); //创建自定义窗口,放入到listwidget中 BluetoothDeviceCell* btDevCell = new BluetoothDeviceCell(); //设置item的高 item->setSizeHint(QSize(ui->deviceListWidget->width(), btDevCell->height())); //设置label显示 btDevCell->m_btName->setText("名称"); btDevCell->m_btAddr->setText("地址"); btDevCell->m_btRssi->setText("信号强度"); //将item加入到listwidget中 ui->deviceListWidget->addItem(item); //设置item的窗口为自定义的窗口 ui->deviceListWidget->setItemWidget(item, btDevCell); } m_deviceDiscoveryAgent->start(QBluetoothDeviceDiscoveryAgent::ClassicMethod); //开启经典蓝牙设备搜索 ui->searchButton->setEnabled(false);//搜索过程中,search按钮不可点击 ui->statusLabel->setText("Searching for devices......");} QBluetoothDeviceDiscoveryAgent::ClassicMethod是以经典方式进行搜索,可以发现经典蓝牙和低功耗蓝牙设备。
发现一个设备的槽函数:
void BluetoothConnect::deviceDiscoveredSlot(QBluetoothDeviceInfo btDevInfo) //发现设备后将设备添加到listwidget中{ QListWidgetItem* item = new QListWidgetItem(); //声明一个item BluetoothDeviceCell* btDevCell = new BluetoothDeviceCell(); //声明一个蓝牙设备单元 item->setSizeHint(QSize(ui->deviceListWidget->width(), btDevCell->height())); //设定item的尺寸 //搜索到的设备信息存到设备单元中 btDevCell->m_btName->setText(btDevInfo.name()); btDevCell->m_btAddr->setText(btDevInfo.address().toString()); btDevCell->m_btRssi->setText(QString::number(btDevInfo.rssi())); //将设备单元添加到deviceListWidget中 ui->deviceListWidget->addItem(item); ui->deviceListWidget->setItemWidget(item,btDevCell); //设备信息list新增一个设备信息 m_devInfos.append(btDevInfo);} 设备搜索完成的槽函数:
void BluetoothConnect::deviceSearchFinishedSlot() //设备搜索完成{ ui->statusLabel->setText("Double Click a device to searhc for services"); QMessageBox::about(this, "提示", "设备搜索完成");// qDebug() searchButton->setEnabled(true); //一次搜索完之后才可以重新点击search键} 设备搜索出现错误的槽函数:
void BluetoothConnect::deviceSearchErrorOccurredSlot(QBluetoothDeviceDiscoveryAgent::Error error) //搜索蓝牙设备出现错误{ qDebug() serviceListWidget->count() > 1) { ui->serviceListWidget->clear(); //设置服务列表的标题 QListWidgetItem* items = new QListWidgetItem(); //创建自定义窗口,放入到listwidget中 BluetoothDeviceCell* btDevCells = new BluetoothDeviceCell(); //设定item的尺寸 items->setSizeHint(QSize(ui->serviceListWidget->width(), btDevCells->height())); //设置label的显示 //第一个加进去的item在最上面,相当于标题 btDevCells->m_btName->setText("名称"); btDevCells->m_btAddr->setText("服务Uuid"); btDevCells->m_btRssi->setText("空"); //将item加入到listwidget中 ui->serviceListWidget->addItem(items); //设置item的窗口为自定义的窗口 ui->serviceListWidget->setItemWidget(items, btDevCells); } QWidget* widget = ui->deviceListWidget->itemWidget(item); //将点击的item信息取出来 BluetoothDeviceCell* btDevCell = (BluetoothDeviceCell*) widget; //强制类型转换为DeviceCell设备单元 qDebug() m_btAddr->text(); //输出设备地址 m_btAddress = QBluetoothAddress(btDevCell->m_btAddr->text());//记录下来选中的设备的地址.后边点击service进行连接时,使用该地址 m_serviceDiscoveryAgent->setRemoteAddress(QBluetoothAddress(btDevCell->m_btAddr->text())); //要搜索的服务是当前激活的这个设备的服务 m_serviceDiscoveryAgent->start(); //开始搜索 ui->statusLabel->setText("Searching for services......"); //!!!!不同设备所允许的服务不同,需要寻找设备支持的服务有什么} 发现一个服务的槽函数,将服务信息添加到listWidget以及自己的list中:
void BluetoothConnect::serviceDiscoveredSlot(const QBluetoothServiceInfo& serviceInfo) //发现服务{ //serviceInfo中没有设备地址 if(serviceInfo.serviceName().isEmpty()) return; //!!!用serviceClassUuids才能得到有效的Uuid QList btUuids = serviceInfo.serviceClassUuids(); //每个list中只有1个元素 qDebug() setSizeHint(QSize(ui->serviceListWidget->width(), btDevCell->height())); btDevCell->m_btName->setText(serviceInfo.serviceName()); btDevCell->m_btAddr->setText(btUuid.toString()); btDevCell->m_btRssi->setText(""); ui->serviceListWidget->addItem(item); ui->serviceListWidget->setItemWidget(item, btDevCell); m_btUuids.append(btUuid);} 服务搜索完成的槽函数:
void BluetoothConnect::serviceSearchFinishedSlot() //服务搜索完成{ ui->statusLabel->setText("Double Click a service to connect to bluetooth"); QMessageBox::about(this, "Hint", "Service Search Finished!");} 连接到选定设备的选定服务,建立通讯
激活服务列表的服务的槽函数:
void BluetoothConnect::on_serviceListWidget_itemActivated(QListWidgetItem *item) //激活服务列表的项目{ QWidget* widget = ui->serviceListWidget->itemWidget(item); //将点击的item信息取出来 BluetoothDeviceCell* btDevCell = (BluetoothDeviceCell*) widget; //强制类型转换为DeviceCell设备单元 qDebug() text(); m_btSocket->connectToService(m_btAddress,QBluetoothUuid(btDevCell->m_btAddr->text()),QIODevice::ReadWrite); //根据设备地址与Uuid连接 ui->statusLabel->setText("Bluetooth connecting......");} 使用socket套接字连接成功后,经典蓝牙通讯即建立:
void BluetoothConnect::socketConnectedSlot() //socket连接成功{ ui->statusLabel->setText(""); QMessageBox::about(this, "Information", "Socket Connected Successfully!"); //隐去Bluetooth Connect窗口 this->close();} socket发生错误的槽函数:
void BluetoothConnect::socketErrorOccurredSlot(QBluetoothSocket::SocketError error) //socket发生错误{ switch(error) { case QBluetoothSocket::NoSocketError: break; case QBluetoothSocket::UnknownSocketError: qDebug() sendDataLineEdit->text().toUtf8(); if(m_isClose == false) //窗口显示打开,蓝牙发送使能;窗口显示关闭,蓝牙发送失能 { //将发送的数据也打印到窗口上 ui->revDataTextBrowser->append("发送:"); ui->revDataTextBrowser->append(dataSent); //通过socket发送数据 m_btConnect->m_btSocket->write(dataSent); }}
上一篇:服务器有arp攻击怎么查看?
下一篇:雷电云怎么开加速服务器?