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

PyQt5多窗口信息传递故障排查求助

问题描述

尝试在两个Qt Designer生成的独立窗口间传值:主窗口包含两个标签,编辑窗口用于修改标签内容。点击主窗口按钮后,编辑窗口短暂打开后立即关闭;注释掉主窗口edit_labels函数中的self.ui.update_label.connect(self.update_labels)代码后,编辑窗口可正常打开,但无法与主窗口联动。

原代码

FirstWindow.py

from PyQt5 import QtCore, QtGui, QtWidgets

from SecondWindow import Ui_SecondWindow


class Ui_FirstWindow(object):
    def setupUi(self, FirstWindow):
        FirstWindow.setObjectName("FirstWindow")
        FirstWindow.resize(800, 600)
        self.centralwidget = QtWidgets.QWidget(FirstWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.top_label = QtWidgets.QLabel(self.centralwidget)
        self.top_label.setGeometry(QtCore.QRect(80, 110, 331, 111))
        self.top_label.setObjectName("top_label")
        self.bottom_label = QtWidgets.QLabel(self.centralwidget)
        self.bottom_label.setGeometry(QtCore.QRect(80, 290, 47, 13))
        self.bottom_label.setObjectName("bottom_label")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget, clicked= lambda: self.edit_labels())
        self.pushButton.setGeometry(QtCore.QRect(580, 240, 171, 71))
        self.pushButton.setObjectName("pushButton")
        FirstWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(FirstWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
        self.menubar.setObjectName("menubar")
        FirstWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(FirstWindow)
        self.statusbar.setObjectName("statusbar")
        FirstWindow.setStatusBar(self.statusbar)

        self.retranslateUi(FirstWindow)
        QtCore.QMetaObject.connectSlotsByName(FirstWindow)

    def retranslateUi(self, FirstWindow):
        _translate = QtCore.QCoreApplication.translate
        FirstWindow.setWindowTitle(_translate("FirstWindow", "MainWindow"))
        self.top_label.setText(_translate("FirstWindow", "TextLabel"))
        self.bottom_label.setText(_translate("FirstWindow", "TextLabel"))
        self.pushButton.setText(_translate("FirstWindow", "Edit labels"))

    @QtCore.pyqtSlot(str, str)
    def update_labels(self, top_line_text, bottom_line_text):
        self.top_label.setText(top_line_text)
        self.bottom_label.setText(bottom_line_text)

    def edit_labels(self):
        self.window = QtWidgets.QMainWindow()
        self.ui = Ui_SecondWindow()
        self.ui.setupUi(self.window)
        self.ui.update_label.connect(self.update_labels)
        self.window.show()



if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    FirstWindow = QtWidgets.QMainWindow()
    ui = Ui_FirstWindow()
    ui.setupUi(FirstWindow)
    FirstWindow.show()
    sys.exit(app.exec_())

SecondWindow.py

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_SecondWindow(object):

update_label = QtCore.pyqtSignal(str, str)

def setupUi(self, SecondWindow):
    SecondWindow.setObjectName("SecondWindow")
    SecondWindow.resize(800, 600)
    self.centralwidget = QtWidgets.QWidget(SecondWindow)
    self.centralwidget.setObjectName("centralwidget")
    self.top_label_lineEdit = QtWidgets.QLineEdit(self.centralwidget)
    self.top_label_lineEdit.setGeometry(QtCore.QRect(110, 120, 421, 20))
    self.top_label_lineEdit.setObjectName("top_label_lineEdit")
    self.bottomLabel_lineEdit = QtWidgets.QLineEdit(self.centralwidget)
    self.bottomLabel_lineEdit.setGeometry(QtCore.QRect(110, 160, 421, 20))
    self.bottomLabel_lineEdit.setObjectName("bottomLabel_lineEdit")

    self.submit_pushButton = QtWidgets.QPushButton(self.centralwidget, clicked= lambda: self.on_submit())
    self.submit_pushButton.setGeometry(QtCore.QRect(280, 200, 75, 23))
    self.submit_pushButton.setObjectName("submit_pushButton")

    SecondWindow.setCentralWidget(self.centralwidget)
    self.menubar = QtWidgets.QMenuBar(SecondWindow)
    self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
    self.menubar.setObjectName("menubar")
    SecondWindow.setMenuBar(self.menubar)
    self.statusbar = QtWidgets.QStatusBar(SecondWindow)
    self.statusbar.setObjectName("statusbar")
    SecondWindow.setStatusBar(self.statusbar)

    self.retranslateUi(SecondWindow)
    QtCore.QMetaObject.connectSlotsByName(SecondWindow)

def on_submit(self):
    self.update_label.emit(self.top_label_lineEdit.text(), self.bottomLabel_lineEdit.text())
    self.close()

def retranslateUi(self, SecondWindow):
    _translate = QtCore.QCoreApplication.translate
    SecondWindow.setWindowTitle(_translate("SecondWindow", "MainWindow"))
    self.submit_pushButton.setText(_translate("SecondWindow", "Submit"))
问题原因与修复方案

核心问题

  1. 信号定义位置错误:PyQt的信号必须定义在继承自QObject的类中,而Qt Designer生成的Ui_SecondWindow类继承自object,不是QObject子类,直接在其中定义update_label信号是无效的。信号连接时会触发内部异常,导致Qt自动销毁异常的窗口对象,所以编辑窗口闪一下就关闭。
  2. 界面与逻辑耦合不当:直接在Ui类中写业务逻辑(如on_submit)不符合Qt的最佳实践,应该将界面和逻辑分离。

修复步骤

1. 重构SecondWindow.py

创建继承自QMainWindow和Ui_SecondWindow的新类,将信号和业务逻辑移到这个类中:

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_SecondWindow(object):
    def setupUi(self, SecondWindow):
        SecondWindow.setObjectName("SecondWindow")
        SecondWindow.resize(800, 600)
        self.centralwidget = QtWidgets.QWidget(SecondWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.top_label_lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.top_label_lineEdit.setGeometry(QtCore.QRect(110, 120, 421, 20))
        self.top_label_lineEdit.setObjectName("top_label_lineEdit")
        self.bottomLabel_lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.bottomLabel_lineEdit.setGeometry(QtCore.QRect(110, 160, 421, 20))
        self.bottomLabel_lineEdit.setObjectName("bottomLabel_lineEdit")

        self.submit_pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.submit_pushButton.setGeometry(QtCore.QRect(280, 200, 75, 23))
        self.submit_pushButton.setObjectName("submit_pushButton")

        SecondWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(SecondWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
        self.menubar.setObjectName("menubar")
        SecondWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(SecondWindow)
        self.statusbar.setObjectName("statusbar")
        SecondWindow.setStatusBar(self.statusbar)

        self.retranslateUi(SecondWindow)
        QtCore.QMetaObject.connectSlotsByName(SecondWindow)

    def retranslateUi(self, SecondWindow):
        _translate = QtCore.QCoreApplication.translate
        SecondWindow.setWindowTitle(_translate("SecondWindow", "MainWindow"))
        self.submit_pushButton.setText(_translate("SecondWindow", "Submit"))

# 新增继承类,承载信号与业务逻辑
class SecondWindow(QtWidgets.QMainWindow, Ui_SecondWindow):
    update_label = QtCore.pyqtSignal(str, str)

    def __init__(self, parent=None):
        super().__init__(parent)
        self.setupUi(self)
        self.submit_pushButton.clicked.connect(self.on_submit)

    def on_submit(self):
        self.update_label.emit(self.top_label_lineEdit.text(), self.bottomLabel_lineEdit.text())
        self.close()

2. 修改FirstWindow.py

  • 更新导入语句,改为导入SecondWindow类
  • 修改edit_labels方法,直接使用新的SecondWindow类创建窗口:
from PyQt5 import QtCore, QtGui, QtWidgets

# 替换原导入语句
from SecondWindow import SecondWindow


class Ui_FirstWindow(object):
    # 保留原setupUi、retranslateUi、update_labels方法不变

    def edit_labels(self):
        self.window = SecondWindow()
        self.window.update_label.connect(self.update_labels)
        self.window.show()


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    FirstWindow = QtWidgets.QMainWindow()
    ui = Ui_FirstWindow()
    ui.setupUi(FirstWindow)
    FirstWindow.show()
    sys.exit(app.exec_())

修复效果

修改后,点击主窗口按钮可正常打开编辑窗口,输入内容点击提交后,主窗口标签会同步更新,编辑窗口自动关闭,完全符合预期功能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 03:45:55