一、场景情况
实例中:当我们点击按钮,获取数据需要10秒中,则界面就会卡死10秒,无法做任何操作,甚至 是关闭窗口。
import datetime
import time
from PySide6.QtUiTools import QUiLoader
class TestView:
def __init__(self):
# 加载UI文件
self.ui = QUiLoader().load('untitled.ui')
self.ui.pushButton.clicked.connect(self.handle_button_click)
def handle_button_click(self):
# 处理数据需要10秒
time.sleep(10)
self.ui.label.setText(str(datetime.datetime.now()))
二、通过自定义信号异步处理
import time
from datetime import datetime
from threading import Thread
from PySide6.QtCore import QObject, Signal, Slot
from PySide6.QtUiTools import QUiLoader
# 第一步:定义信号
class CustomSignal(QObject):
# 定义一个信号,参数是字符串
signal_button_clicked = Signal(str)
# 第二步:实例化信号
custom_signal = CustomSignal()
class TestView:
def __init__(self):
# 加载UI文件
self.ui = QUiLoader().load('untitled.ui')
self.ui.pushButton.clicked.connect(self.signal_button_click)
# 第三步:定义异步发出信号
def signal_button_click(self):
# 第四步:绑定信号的处理函数
custom_signal.signal_button_clicked.connect(self.handle_button_click)
# 第五步:子线程处理数据
def thread_function():
# 子线程处理数据10秒
time.sleep(10)
# 数据处理完毕后发送信号,并将处理好的数据一并发给主线程,让主线程去渲染界面
custom_signal.signal_button_clicked.emit(str(datetime.now()))
# 第六步:开启子线程
thread = Thread(target=thread_function)
thread.start()
def handle_button_click(self, param):
print('主线程收到信号并进行处理')
self.ui.label.setText(param)
三、使用示例:
第一步:定信号并实例化
class CustomSignal(QObject):
signal_render_tree_widget = Signal(list)
signal_render_list_widget = Signal(list)
custom_signal = CustomSignal()
第二步:定义发送信号的方法
def send_signal_render_tree_widget(self):
# 信号绑定槽函数
custom_signal.signal_render_tree_widget.connect(self.render_tree_widget)
def thread_function():
# 在新线程中处理数据
data: list[TreeWidgetDataDTO] = [TreeWidgetDataDTO(x.id, None, x.link_name) for x in
get_database_connections()]
# 处理完数据发送渲染信号
custom_signal.signal_render_tree_widget.emit(data)
# 使用新线程去发送信号
thread = Thread(target=thread_function)
thread.start()
第三步:定义渲染的方法。参数是:异步处理完成后,传过来的数据。
# 渲染树
def render_tree_widget(self, data: list[TreeWidgetDataDTO]):
render_treeWidget(self.ui.treeWidget,
data=data,
itemClick=lambda item: self.send_signal_render_list_widget(item.data(0, Qt.UserRole + 1).id),
itemDoubleClick=lambda item: print('双击事件', item.data(0, Qt.UserRole + 1)))
第四步:连接触发发送信号的行为。