我基于 Bleak 第三方庫撰寫了一個 BLE 程式,并在一個介面中讀取藍牙值。關閉介面后,我未能終止 BLE 程式。是什么原因?
我上傳了一個影片 GIF 來說明問題:

該程式包括:創建UI界面,UI界面將值讀入外部PY檔案中的BLE程式,關閉UI界面時平滑終止BLE程式。
BLE.py 代碼:
import numpy as np
import sys
import time
import asyncio
import logging
from bleak import BleakClient
logger = logging.getLogger()
async def run_ble_client(address: str, char_uuid: str, queue: asyncio.Queue):
async def callback_handler(sender, data):
await queue.put((time.time(), data))
async with BleakClient(address) as client:
logger.info(f"Connected: {client.is_connected}")
await client.start_notify(char_uuid, callback_handler)
while True:
await asyncio.sleep(3600.0)
# await client.stop_notify(char_uuid)
# Send an "exit command to the consumer"
await queue.put((time.time(), None))
async def run_queue_consumer(queue: asyncio.Queue):
while True:
# Use await asyncio.wait_for(queue.get(), timeout=1.0) if you want a timeout for getting data.
epoch, data = await queue.get()
if data is None:
logger.info(
"Got message from client about disconnection. Exiting consumer loop..."
)
break
else:
EMG = str(data, "utf-8").split(',')
print(EMG)
print(queue.full())
async def main(address: str, char_uuid: str):
queue = asyncio.Queue()
client_task = run_ble_client(address, char_uuid, queue)
consumer_task = run_queue_consumer(queue)
await asyncio.gather(client_task, consumer_task)
logger.info("Main method done.")
主要代碼:
import ble
from PyQt5 import QtCore, QtWidgets
import threading
import EMG_NUM
class UIForm(): # PE8: `CamelNames` for classes
def setupUI(self, form, **kwargs):
form.resize(820, 454)
form.setObjectName("Form")
self.gridLayoutWidget = QtWidgets.QWidget(form)
self.gridLayoutWidget.setGeometry(QtCore.QRect(550, 270, 261, 121))
self.gridLayoutWidget.setObjectName("gridLayoutWidget")
self.gridLayout = QtWidgets.QGridLayout(self.gridLayoutWidget)
self.gridLayout.setContentsMargins(0, 0, 0, 0)
self.gridLayout.setObjectName("gridLayout")
self.retranslateUi(form)
def retranslateUi(self, form):
_translate = QtCore.QCoreApplication.translate
form.setWindowTitle(_translate("Form", "xxxx"))
def main():
app = QtWidgets.QApplication([])
form = QtWidgets.QWidget() # PE8: `lower_case_names` for variables
ui = UIForm()
ui.setupUI(form)
form.show()
app.exec()
if __name__ == "__main__":
# better start before GUI to create all needed variables and values
thread_ble = threading.Thread(target=ble.ble)
thread_ble.start()
# input() # keep running program when GUI runs in thread
main()
thread_ble.join()
我使用了執行緒,但無法成功終止執行緒。你能告訴我如何終止執行緒嗎?
uj5u.com熱心網友回復:
furas 不好意思,最近一直在研究如何提高BLE的吞吐量。我沒有注意到你的評論。
上面的解決方案是修改BLE代碼。
在 BLE 的 main 函式中添加一個判斷,正如 Furas 所說:使用 global running = True。查看 BLE 訊息以檢查是否已連接。如果斷開連接,它會跳出來。這樣,藍牙就可以安全的關閉了。
用了幾天時間熟悉了Bleak第三方庫的使用,改成如下代碼。(代碼幾千行,這里就不放了,放個簡單的例子)
主檔案
...
if __name__ == "__main__":
thread_ble = threading.Thread(target=ble.ble)
thread_ble.start()
# input() # keep running program when GUI runs in thread
main()
EMG_NUM.Kill=True
thread_ble.join()
EMG_NUM.py
Kill=False
Connect=False
BLE.py
...
async def main(address: str, char_uuid: str):
async with BleakClient(address) as client:
EMG_NUM.Connect=client.is_connected
...
await client.start_notify(char_uuid, callback_handler)
while EMG_NUM.Connect:
if client.is_connected:
pass1`
else:
EMG_NUM.Connect=False
...
break
if EMG_NUM.Kill:
break
else:
await asyncio.sleep(1.0)
def ble():
while EMG_NUM.Kill == False:
try:
...
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/457409.html
標籤:Python python-3.x 多线程 pyqt python-多线程
上一篇:狀態在任務中被取消,沒有使用令牌進行初始化,并且在lambda中使用ThrowIfCancellationRequested呼叫
