You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyQt中使用threading类打开多窗口失败问题求助

问题分析与解决方案

核心问题

PyQt有严格的线程规则:所有GUI操作必须在主线程(即运行QApplication的线程)执行,子线程不能创建QApplication实例或GUI窗口;同时一个PyQt程序只能存在一个QApplication实例,你在子线程中重复创建QApplication会直接导致GUI运行冲突,这就是只显示线程中窗口的根本原因。


正确实现方式

通过信号槽机制实现子线程与主线程的通信:子线程负责耗时逻辑(如果有的话),主线程接收信号后创建并显示第二个窗口。

1. 修改线程类(ThreadModel)

移除子线程中的GUI代码,改为发送信号通知主线程:

from PyQt5 import QtCore
import threading

class ThreadModel(threading.Thread):
    # 定义信号,用于通知主线程显示窗口
    show_second_window = QtCore.pyqtSignal()

    def __init__(self):
        super().__init__()

    def run(self):
        # 这里放你的耗时业务逻辑,比如模拟耗时任务
        import time
        time.sleep(2)
        
        # 任务完成后发送信号,触发主线程创建窗口
        self.show_second_window.emit()

2. 修改主窗口类

在主线程中接收信号,创建并显示第二个窗口:

import sys
from PyQt5 import QtWidgets
from your_thread_module import ThreadModel  # 替换为你的线程文件路径

class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.setupUi(self)
        
        # 初始化线程并绑定信号
        self.thread_model = ThreadModel()
        self.thread_model.show_second_window.connect(self.create_second_window)
        self.thread_model.start()

    def create_second_window(self):
        # 在主线程中创建并显示第二个窗口
        self.second_win = QtWidgets.QWidget()
        self.second_win.resize(250, 250)
        self.second_win.setWindowTitle("test")
        self.second_win.show()

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    window = MainWindow()
    window.show()
    app.exec()

关键注意事项

  • 永远不要在子线程中执行任何GUI操作(创建控件、更新UI、显示窗口等),PyQt的GUI线程是主线程,所有GUI逻辑必须在此线程完成。
  • 一个PyQt程序只能有一个QApplication实例,且必须在主线程初始化并启动事件循环。
  • 信号槽是PyQt中线程间安全通信的标准方式,避免直接在子线程操作GUI引发的崩溃或异常。

内容的提问来源于stack exchange,提问作者Arpegio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 19:57:41