赞
踩
由于本人水平有限,仅用了最简单的进行实现,主要功能:
- from PyQt5.QtWidgets import *
- from PyQt5.QtGui import *
- from PyQt5.QtCore import *
- import sys
- import threading
- sys.path.append('..')
- from ui.Ui_ble_control_widget import *
- from drivers.driver_bluetooth import BluetoothDataTransfer
-
-
- class BleControlWidget(QWidget):
-
- # 信号定义
- # 蓝牙列表刷新
- refresh_signal = pyqtSignal()
- receive_data_signal = pyqtSignal(bytes)
- update_connection_signal = pyqtSignal()
-
- def __init__(self, parent=None):
- super().__init__(parent)
- self.ui = Ui_BleControlWidget()
- self.ui.setupUi(self)
-
- # 按钮槽函数调用
- self.init_ui()
-
- # 实例化属性便于全局调用
- self.device_list = [] # 蓝牙设备列表
- self.bd = None
-
- # 进入界面默认调用
- # 刷新蓝牙列表
- self.refreshBtn_subthread()
-
-
- def init_ui(self):
- '''按钮与槽函数连接'''
- # 刷新按钮槽函数绑定
- self.ui.refreshBtn.clicked.connect(self.refreshBtn_slot)
- # 连接蓝牙槽函数绑定
- self.ui.connectBtn.clicked.connect(self.connectBtn_slot)
- # 蓝牙列表更新信号与槽函数连接
- self.refresh_signal.connect(self.refresh_signal_slot)
- # 接收到的数据展示信号与槽函数连接
- self.receive_data_signal.connect(self.receive_data_signal_slot)
- # 更新蓝牙的状态槽函数绑定
- self.update_connection_signal.connect(self.update_connection_signal_slot)
-
- # 各控制按钮槽函数绑定
- self.ui.buzzerOnBtn.clicked.connect(self.contorl_btn_slot)
- self.ui.distanceBtn.clicked.connect(self.contorl_btn_slot)
- self.ui.downBtn.clicked.connect(self.contorl_btn_slot)
- self.ui.leftBtn.clicked.connect(self.contorl_btn_slot)
- self.ui.lightOffBtn.clicked.connect(self.contorl_btn_slot)
- self.ui.lightOnBtn.clicked.connect(self.contorl_btn_slot)
- self.ui.rightBtn.clicked.connect(self.contorl_btn_slot)
- self.ui.rotateBtn.clicked.connect(self.contorl_btn_slot)
- self.ui.stopBtn.clicked.connect(self.contorl_btn_slot)
- self.ui.trackOffBtn.clicked.connect(self.contorl_btn_slot)
- self.ui.trackOnBtn.clicked.connect(self.contorl_btn_slot)
- self.ui.upBtn.clicked.connect(self.contorl_btn_slot)
-
- def contorl_btn_slot(self):
- if not self.bp:
- QMessageBox.warning(self, "蓝牙未连接", "请先连接蓝牙")
- return
- sender = self.sender()
- if sender is self.ui.buzzerOnBtn:
- res,msg = self.bd.send_data(b"\x01")
- elif sender is self.ui.distanceBtn:
- res,msg = self.bd.send_data(b"\x02")
- elif sender is self.ui.downBtn:
- res,msg = self.bd.send_data(b"\x03")
- elif sender is self.ui.leftBtn:
- res,msg = self.bd.send_data(b"\x04")
- elif sender is self.ui.lightOffBtn:
- res,msg = self.bd.send_data(b"\x05")
- elif sender is self.ui.lightOnBtn:
- res,msg = self.bd.send_data(b"\x06")
- elif sender is self.ui.rightBtn:
- res,msg = self.bd.send_data(b"\x07")
- elif sender is self.ui.rotateBtn:
- res,msg = self.bd.send_data(b"\x08")
- elif sender is self.ui.stopBtn:
- res,msg = self.bd.send_data(b"\x09")
- elif sender is self.ui.trackOffBtn:
- res,msg = self.bd.send_data(b"\x0a")
- elif sender is self.ui.trackOnBtn:
- res,msg = self.bd.send_data(b"\x0b")
- elif sender is self.ui.upBtn:
- res,msg = self.bd.send_data(b"\x0c")
- if res:
- QMessageBox.information(self, '提示', msg)
- else:
- QMessageBox.warning(self, '警告', msg)
-
- def update_connection_signal_slot(self):
- self.ui.connectBtn.setText("已连接")
- self.ui.connectBtn.setIcon(QIcon(":/icon/disc"))
-
- def receive_data_signal_slot(self, data):
- QMessageBox.information(self, '提示', f'接收到数据:{data}')
-
- def refresh_signal_slot(self):
- if len(self.device_list)>0:
- for addr,bluetooth in self.device_list:
- self.ui.comboBox.addItem(bluetooth)
-
-
- def refreshBtn_slot(self):
- # 如果在刷新前有数据,清空下拉列表,否则会增加多倍数据在下拉框中导致索引超出
- if self.device_list:
- self.ui.comboBox.clear()
- self.device_list = []
- '''刷新按钮槽函数定义'''
- # 刷新很耗时间,需要开子线程处理,否则页面卡死
- t = threading.Thread(target=self.refreshBtn_subthread,daemon=True)
- t.start()
-
- def refreshBtn_subthread(self):
- '''搜索蓝牙并展示在选择下拉列表中'''
- self.device_list = BluetoothDataTransfer.scan_devices()
- # 展示在下拉列表中需要用到信号,子线程中无法直接更新ui页面,会报错
- print(self.device_list)
- # 发送信号
- self.refresh_signal.emit()
-
- def connectBtn_slot(self):
- if self.bd:
- self.bd.disconnect()
- self.bd = []
- self.ui.connectBtn.setText("连接蓝牙")
- self.ui.connectBtn.setIcon(QIcon(":/icon/connect"))
- return
- '''连接蓝牙按钮槽函数定义'''
- # 连接很耗时间,需要开子线程处理,否则页面卡死
- t = threading.Thread(target=self.connectBtn_subthread,daemon=True)
- t.start()
-
- def connectBtn_subthread(self):
- # 获取蓝牙选项
- index = self.ui.comboBox.currentIndex()
- address = self.device_list[index][0]
- name = self.ui.comboBox.currentText()
- # 连接蓝牙
- self.bd = BluetoothDataTransfer(address, name) # 替换为目标设备的蓝牙地址和端口号
- flag = self.bd.connect()
- print(flag)
-
- if not flag:
- return
- # 更新蓝牙连接状态文字和图标
- self.update_connection_signal.emit()
- # 开始接受数据
- while True:
- data = self.bd.receive_data(1024)
- if data:
- # 发送数据到页面弹窗显示
- print(data)
- #self.receive_data_signal.emit(data)
-
-
- if __name__ == '__main__':
- app = QApplication(sys.argv)
- widget = BleControlWidget()
- widget.show()
- sys.exit(app.exec_())
- import bluetooth
-
-
- # 扫描所有设备
- class BluetoothDataTransfer:
- def __init__(self, target_address, target_name, port=1):
- self.target_address = target_address
- self.target_name = target_name
- self.port = port
- self.socket = None
-
- def connect(self):
- """
- 连接蓝牙设备
- :return:
- """
- try:
- self.socket = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
- self.socket.connect((self.target_address, self.port))
- print("Connected successfully. {} ({})".format(
- self.target_name, self.target_address
- ))
- return True
- except (bluetooth.BluetoothError, OSError) as e:
- self.socket = None
- print("Connection failed:", str(e))
-
- return False
-
- def disconnect(self):
- """
- 断开蓝牙连接
- :return:
- """
- if self.socket is not None:
- self.socket.close()
- print("Disconnected.")
-
- def send_data(self, data):
- """
- 发送数据
- :param data:
- :return:
- """
- if self.socket is not None:
- try:
- self.socket.send(data)
- print("Data sent:", data)
- return True,"sent succeed"
- except bluetooth.BluetoothError as e:
- print("Failed to send data:", str(e))
- return False,str(e)
- else:
- print("Not connected.")
- return False,"Not connected."
-
- def receive_data(self, buffer_size=2048):
- """
- 接收数据
- :param buffer_size:
- :return:
- """
- if self.socket is None:
- print("Not connected.")
- return
-
- try:
- data = self.socket.recv(buffer_size)
- # print("Data received:", data.decode())
- return data
- except bluetooth.BluetoothError as e:
- print("Failed to receive data:", str(e))
-
- @staticmethod
- def scan_devices():
- """
- 扫描所有蓝牙设备
- :return:
- """
- devices = bluetooth.discover_devices()
- print("Scanning devices...")
- device_list = []
- for addr in devices:
- name = bluetooth.lookup_name(addr)
- print("Found device:", name, "(", addr, ")")
- device_list.append((addr, name))
- return device_list
-
-
- if __name__ == '__main__':
- # print("=========================================开始扫描")
- # devices = BluetoothDataTransfer.scan_devices()
- # for device in devices:
- # print(device)
- # print("=========================================结束扫描")
-
- # 示例用法
- bd = BluetoothDataTransfer("FA:34:0A:92:71:42", 'JDY-33-SPP-kkkkkkk') # 替换为目标设备的蓝牙地址和端口号
- flag = bd.connect()
- print(flag)
- if flag:
- # bd.send_data("Hello, Bluetooth!") # 发送数据
- bd.send_data(b"\x12") # 发送数据
- recv_data = bd.receive_data() # 接收数据
- print("接收到的数据:", recv_data)
- bd.disconnect()
- # -*- coding: utf-8 -*-
-
- # Form implementation generated from reading ui file 'c:\Users\Windows10\Desktop\02上课代码步骤\小车实战 copy\ui\ble_control_widget.ui'
- #
- # Created by: PyQt5 UI code generator 5.15.9
- #
- # WARNING: Any manual changes made to this file will be lost when pyuic5 is
- # run again. Do not edit this file unless you know what you are doing.
-
-
- from PyQt5 import QtCore, QtGui, QtWidgets
-
-
- class Ui_BleControlWidget(object):
- def setupUi(self, BleControlWidget):
- BleControlWidget.setObjectName("BleControlWidget")
- BleControlWidget.resize(411, 276)
- self.verticalLayout_2 = QtWidgets.QVBoxLayout(BleControlWidget)
- self.verticalLayout_2.setObjectName("verticalLayout_2")
- self.setLayout = QtWidgets.QHBoxLayout()
- self.setLayout.setObjectName("setLayout")
- self.label = QtWidgets.QLabel(BleControlWidget)
- font = QtGui.QFont()
- font.setFamily("Agency FB")
- font.setPointSize(10)
- font.setBold(True)
- font.setWeight(75)
- self.label.setFont(font)
- self.label.setObjectName("label")
- self.setLayout.addWidget(self.label)
- self.comboBox = QtWidgets.QComboBox(BleControlWidget)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.comboBox.sizePolicy().hasHeightForWidth())
- self.comboBox.setSizePolicy(sizePolicy)
- self.comboBox.setMinimumSize(QtCore.QSize(0, 25))
- self.comboBox.setObjectName("comboBox")
- self.setLayout.addWidget(self.comboBox)
- self.refreshBtn = QtWidgets.QPushButton(BleControlWidget)
- self.refreshBtn.setText("")
- icon = QtGui.QIcon()
- icon.addPixmap(QtGui.QPixmap(":/icon/refresh"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
- self.refreshBtn.setIcon(icon)
- self.refreshBtn.setFlat(True)
- self.refreshBtn.setObjectName("refreshBtn")
- self.setLayout.addWidget(self.refreshBtn)
- self.connectBtn = QtWidgets.QPushButton(BleControlWidget)
- icon1 = QtGui.QIcon()
- icon1.addPixmap(QtGui.QPixmap(":/icon/connect"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
- self.connectBtn.setIcon(icon1)
- self.connectBtn.setObjectName("connectBtn")
- self.setLayout.addWidget(self.connectBtn)
- self.setLayout.setStretch(0, 1)
- self.setLayout.setStretch(1, 4)
- self.setLayout.setStretch(2, 1)
- self.setLayout.setStretch(3, 2)
- self.verticalLayout_2.addLayout(self.setLayout)
- self.frame = QtWidgets.QFrame(BleControlWidget)
- self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
- self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
- self.frame.setObjectName("frame")
- self.verticalLayout = QtWidgets.QVBoxLayout(self.frame)
- self.verticalLayout.setContentsMargins(0, 0, 0, 0)
- self.verticalLayout.setSpacing(0)
- self.verticalLayout.setObjectName("verticalLayout")
- self.btnLayout = QtWidgets.QGridLayout()
- self.btnLayout.setSpacing(10)
- self.btnLayout.setObjectName("btnLayout")
- self.lightOnBtn = QtWidgets.QPushButton(self.frame)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.lightOnBtn.sizePolicy().hasHeightForWidth())
- self.lightOnBtn.setSizePolicy(sizePolicy)
- font = QtGui.QFont()
- font.setFamily("Agency FB")
- font.setPointSize(22)
- self.lightOnBtn.setFont(font)
- self.lightOnBtn.setObjectName("lightOnBtn")
- self.btnLayout.addWidget(self.lightOnBtn, 4, 0, 1, 1)
- self.upBtn = QtWidgets.QPushButton(self.frame)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.upBtn.sizePolicy().hasHeightForWidth())
- self.upBtn.setSizePolicy(sizePolicy)
- font = QtGui.QFont()
- font.setFamily("Agency FB")
- font.setPointSize(22)
- self.upBtn.setFont(font)
- self.upBtn.setObjectName("upBtn")
- self.btnLayout.addWidget(self.upBtn, 0, 1, 1, 1)
- self.stopBtn = QtWidgets.QPushButton(self.frame)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.stopBtn.sizePolicy().hasHeightForWidth())
- self.stopBtn.setSizePolicy(sizePolicy)
- font = QtGui.QFont()
- font.setFamily("Agency FB")
- font.setPointSize(22)
- self.stopBtn.setFont(font)
- self.stopBtn.setObjectName("stopBtn")
- self.btnLayout.addWidget(self.stopBtn, 2, 1, 1, 1)
- self.leftBtn = QtWidgets.QPushButton(self.frame)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.leftBtn.sizePolicy().hasHeightForWidth())
- self.leftBtn.setSizePolicy(sizePolicy)
- font = QtGui.QFont()
- font.setFamily("Agency FB")
- font.setPointSize(22)
- self.leftBtn.setFont(font)
- self.leftBtn.setObjectName("leftBtn")
- self.btnLayout.addWidget(self.leftBtn, 2, 0, 1, 1)
- self.rotateBtn = QtWidgets.QPushButton(self.frame)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.rotateBtn.sizePolicy().hasHeightForWidth())
- self.rotateBtn.setSizePolicy(sizePolicy)
- font = QtGui.QFont()
- font.setFamily("Agency FB")
- font.setPointSize(22)
- self.rotateBtn.setFont(font)
- self.rotateBtn.setObjectName("rotateBtn")
- self.btnLayout.addWidget(self.rotateBtn, 5, 1, 1, 1)
- self.downBtn = QtWidgets.QPushButton(self.frame)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.downBtn.sizePolicy().hasHeightForWidth())
- self.downBtn.setSizePolicy(sizePolicy)
- font = QtGui.QFont()
- font.setFamily("Agency FB")
- font.setPointSize(22)
- self.downBtn.setFont(font)
- self.downBtn.setObjectName("downBtn")
- self.btnLayout.addWidget(self.downBtn, 4, 1, 1, 1)
- self.lightOffBtn = QtWidgets.QPushButton(self.frame)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.lightOffBtn.sizePolicy().hasHeightForWidth())
- self.lightOffBtn.setSizePolicy(sizePolicy)
- font = QtGui.QFont()
- font.setFamily("Agency FB")
- font.setPointSize(22)
- self.lightOffBtn.setFont(font)
- self.lightOffBtn.setObjectName("lightOffBtn")
- self.btnLayout.addWidget(self.lightOffBtn, 4, 2, 1, 1)
- self.trackOffBtn = QtWidgets.QPushButton(self.frame)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.trackOffBtn.sizePolicy().hasHeightForWidth())
- self.trackOffBtn.setSizePolicy(sizePolicy)
- font = QtGui.QFont()
- font.setFamily("Agency FB")
- font.setPointSize(22)
- self.trackOffBtn.setFont(font)
- self.trackOffBtn.setObjectName("trackOffBtn")
- self.btnLayout.addWidget(self.trackOffBtn, 5, 2, 1, 1)
- self.trackOnBtn = QtWidgets.QPushButton(self.frame)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.trackOnBtn.sizePolicy().hasHeightForWidth())
- self.trackOnBtn.setSizePolicy(sizePolicy)
- font = QtGui.QFont()
- font.setFamily("Agency FB")
- font.setPointSize(22)
- self.trackOnBtn.setFont(font)
- self.trackOnBtn.setObjectName("trackOnBtn")
- self.btnLayout.addWidget(self.trackOnBtn, 5, 0, 1, 1)
- self.rightBtn = QtWidgets.QPushButton(self.frame)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.rightBtn.sizePolicy().hasHeightForWidth())
- self.rightBtn.setSizePolicy(sizePolicy)
- font = QtGui.QFont()
- font.setFamily("Agency FB")
- font.setPointSize(22)
- self.rightBtn.setFont(font)
- self.rightBtn.setObjectName("rightBtn")
- self.btnLayout.addWidget(self.rightBtn, 2, 2, 1, 1)
- self.distanceBtn = QtWidgets.QPushButton(self.frame)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.distanceBtn.sizePolicy().hasHeightForWidth())
- self.distanceBtn.setSizePolicy(sizePolicy)
- font = QtGui.QFont()
- font.setFamily("Agency FB")
- font.setPointSize(22)
- self.distanceBtn.setFont(font)
- self.distanceBtn.setObjectName("distanceBtn")
- self.btnLayout.addWidget(self.distanceBtn, 0, 2, 1, 1)
- self.buzzerOnBtn = QtWidgets.QPushButton(self.frame)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.buzzerOnBtn.sizePolicy().hasHeightForWidth())
- self.buzzerOnBtn.setSizePolicy(sizePolicy)
- font = QtGui.QFont()
- font.setFamily("Agency FB")
- font.setPointSize(22)
- self.buzzerOnBtn.setFont(font)
- self.buzzerOnBtn.setObjectName("buzzerOnBtn")
- self.btnLayout.addWidget(self.buzzerOnBtn, 0, 0, 1, 1)
- self.verticalLayout.addLayout(self.btnLayout)
- self.verticalLayout_2.addWidget(self.frame)
- self.verticalLayout_2.setStretch(0, 1)
- self.verticalLayout_2.setStretch(1, 3)
-
- self.retranslateUi(BleControlWidget)
- QtCore.QMetaObject.connectSlotsByName(BleControlWidget)
-
- def retranslateUi(self, BleControlWidget):
- _translate = QtCore.QCoreApplication.translate
- BleControlWidget.setWindowTitle(_translate("BleControlWidget", "小车蓝牙控制器"))
- self.label.setText(_translate("BleControlWidget", "蓝牙选择:"))
- self.connectBtn.setText(_translate("BleControlWidget", "连接蓝牙"))
- self.lightOnBtn.setText(_translate("BleControlWidget", "开灯"))
- self.upBtn.setText(_translate("BleControlWidget", "上"))
- self.stopBtn.setText(_translate("BleControlWidget", "停止"))
- self.leftBtn.setText(_translate("BleControlWidget", "左"))
- self.rotateBtn.setText(_translate("BleControlWidget", "旋转"))
- self.downBtn.setText(_translate("BleControlWidget", "下"))
- self.lightOffBtn.setText(_translate("BleControlWidget", "关灯"))
- self.trackOffBtn.setText(_translate("BleControlWidget", "关寻迹"))
- self.trackOnBtn.setText(_translate("BleControlWidget", "开寻迹"))
- self.rightBtn.setText(_translate("BleControlWidget", "右"))
- self.distanceBtn.setText(_translate("BleControlWidget", "测距"))
- self.buzzerOnBtn.setText(_translate("BleControlWidget", "开喇叭"))
- from ui import resource_rc
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。