Python PyQt5 开启线程避免界面卡死闪退
创建线程
file:[src/main.py]
from PyQt5 import QtCore
from PyQt5.QtCore import *
class ListDevicesThread(QtCore.QThread):
signal = pyqtSignal(dict, name='list_devices')
def run(self):
while True:
devices_list = apis.list_devices()
self.signal.emit(devices_list)
time.sleep(5)
这个线程每隔 5 秒执行一次获取数据的操作,并通过 emit
把数据发送出去。
使用线程
file:[src/main.py]
class Window(QWidget, Ui_Form):
def __init__(self):
super().__init__()
self.setupUi(self)
# 获取设备列表
self.list_shadow_thread = ListDevicesThread()
self.list_shadow_thread.signal.connect(self.after_list_devices)
self.list_shadow_thread.start()
创建 ListDevicesThread 线程,将线程对象挂载到 self 中,如果不设置,或者设置重复的线程变量名,要么让线程无法执行,要么主界面卡死,不能运行程序。
线程回调函数
在线程获取到一次数据之后,回调函数收到数据 data
:
file:[src/main.py]
def after_list_devices(self, data):
row = 0
self.tableWidget.setRowCount(data['page']['count'])
for item in data['devices']:
self.setTableItem(row, 0, item['device_id'])
self.setTableItem(row, 1, item['device_name'])
self.setTableItem(row, 2, item['product_name'])
self.setTableItem(row, 3, item['status'])
self.setTableItem(row, 4, item['description'])
row += 1
完整代码
file:[src/main.py]
from PyQt5 import QtCore
from PyQt5.QtCore import *
class ListDevicesThread(QtCore.QThread):
signal = pyqtSignal(dict, name='list_devices')
def run(self):
while True:
devices_list = apis.list_devices()
self.signal.emit(devices_list)
time.sleep(5)
class Window(QWidget, Ui_Form):
def __init__(self):
super().__init__()
self.setupUi(self)
# 获取设备列表
self.list_shadow_thread = ListDevicesThread()
self.list_shadow_thread.signal.connect(self.after_list_devices)
self.list_shadow_thread.start()
# 线程执行完成之后的回调函数
def after_list_devices(self, data):
row = 0
self.tableWidget.setRowCount(data['page']['count'])
for item in data['devices']:
self.setTableItem(row, 0, item['device_id'])
self.setTableItem(row, 1, item['device_name'])
self.setTableItem(row, 2, item['product_name'])
self.setTableItem(row, 3, item['status'])
self.setTableItem(row, 4, item['description'])
row += 1
线程获取主线程传递的值
在线程中创建一个设置值的函数,如 set_xxx
:
file:[src/main.py]
class QueryDeviceThread(QtCore.QThread):
signal = pyqtSignal(dict, name='query_device')
device_id = ''
def set_device_id(self, device_id):
self.device_id = device_id
def run(self):
device = apis.query_device(self.device_id)
self.signal.emit(device)
通过 set_device_id
函数给 device_id 设置新的值。在 run
函数执行的时候,获取到 device_id 值。
点击界面的按钮之后触发下面的函数,在开启线程之前,且线程对象创建之后,设置线程的类成员变量。
file:[src/main.py]
def query_device(self):
self.query_device_thread = QueryDeviceThread()
self.query_device_thread.set_device_id(self.input_query_device_id.text())
self.query_device_thread.signal.connect(self.after_query_device)
self.query_device_thread.start()
完整代码
file:[src/main.py]
from PyQt5 import QtCore
from PyQt5.QtCore import *
class QueryDeviceThread(QtCore.QThread):
signal = pyqtSignal(dict, name='query_device')
device_id = ''
def set_device_id(self, device_id):
self.device_id = device_id
def run(self):
device = apis.query_device(self.device_id)
self.signal.emit(device)
class Window(QWidget, Ui_Form):
def __init__(self):
super().__init__()
self.setupUi(self)
# 绑定界面的点击按钮
self.query_device_button.clicked.connect(self.query_device)
# 按钮点击的函数
def query_device(self):
self.query_device_thread = QueryDeviceThread()
self.query_device_thread.set_device_id(self.input_query_device_id.text())
self.query_device_thread.signal.connect(self.after_query_device)
self.query_device_thread.start()
# 线程执行完成之后的回调函数
def after_query_device(self, data):
print(data)
分类:
编程语言 / Python
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步