为何BleakClient在函数退出时断开蓝牙设备连接?
问题原因分析
- async with 上下文管理器的自动关闭特性:你在
connect方法里使用async with BleakClient(self.device) as self.client,当代码退出with代码块时,BleakClient会自动调用disconnect(),导致connect函数执行完毕后连接直接断开。 - 连接状态检测时机错误:在
ble_connect中,你是在loop.run_until_complete(self.ble.connect())执行完成后才检查self.ble.client.is_connected,此时connect方法里的with块已经退出,连接早已被关闭,所以检测结果显示未连接。
解决方案
1. 修改Bluetooth类的connect方法
移除async with,直接实例化BleakClient并手动调用连接方法,避免连接在函数结束时自动断开:
async def connect(self): print('Connecting...') self.client = BleakClient(self.device) try: await self.client.connect() if self.client.is_connected: self.connected = True print(f'Connected to: {self.device.address}') else: print('Failed to connect') except Exception as e: print(f'Connection error: {e}') self.connected = False
2. 调整连接状态检测逻辑
修改ble_connect函数,确保检测时机在连接建立后且未被主动关闭的阶段:
def ble_connect(self, name, timeout): self.ble = Bluetooth(name, timeout) self.loop.run_until_complete(self.ble.scan()) if self.ble.device is not None: self.loop.run_until_complete(self.ble.connect()) if self.ble.client and self.ble.client.is_connected: print('ble_connect: connected') return True else: print('ble_connect: not connected') return False else: print(f'ble_connect: {name} not found') return False
3. PySide6 QThread场景额外注意事项
- 由于代码运行在QThread中,要确保asyncio事件循环持续运行,避免连接因事件循环终止而意外断开。如果后续需要进行蓝牙读写操作,可在QThread的
run方法中启动事件循环的永久运行,或用asyncio.ensure_future调度异步任务。 - 不再需要连接时,需手动调用
await self.ble.client.disconnect()关闭连接,避免资源泄漏。
修改后预期输出
执行ble_connect后应该会得到如下输出:
Scanning... ...(扫描设备输出) Done scanning... Connecting... Connected to: 34:86:5D:18:A1:02 ble_connect: connected
内容的提问来源于stack exchange,提问作者Joe
相关产品推荐
相关产品推荐

