在 PyQt中,主窗口UI 和 程序中生成的子线程是不同的两个线程,如果在子线程中更新窗体UI 可能会导致应用程序崩溃或报错,所有与主窗口UI相关的操作都应该在主线程中执行。
如果需要在子线程完成某些操作对主窗口进行更新显示或显示修改,可以使用 PyQt 提供的信号和槽机制进行。
1. 首先定义一个信号。
signal_show_item = pyqtSignal(list, name="signal_show_item")
2、把信号连接到一个槽函数。
self.signal_show_item.connect(self.show_item)
3.定义一个线程函数。
def start_thread_work(func, args=(), kwargs=None):
if kwargs is None:
kwargs = dict()
target = ThreadWithResult(target=func, args=args, kwargs=kwargs)
target.daemon = True
target.start()
return target
4.在代码中调用线程函数,开启线程。
如果满足response请求从接口获取到数据,触发信号
def again_view(self):
while True:
start_thread_work(self.check_data)
# # 等待5秒再次调用ThreadWithResult
time.sleep(5)
def check_data(self):
# 首先查看数据是否存在
interface = get_map_json_data("./config/config_interface.json")
url = interface["trigger_event_interface"]
try:
# 发送GET请求
response = requests.get(url, timeout=5)
if response.status_code == 200:
# print("发送GET请求")
# 解析返回的数据(这里返回的是JSON格式)
data = response.json()
if data['r'] == 0:
self.signal_show_item.emit(data['d'])
5.信号的触发函数会对主界面进行操作。
def show_item(self, data):
# data is list []
newks = []
# 取出新数据所有k
for j in data:
k = j["id"]
newks.append(k)
... ...
这种方法的关键是使用 `pyqtSignal` 来安全地跨线程通信,并确保 GUI 更新始终在主线程中执行。