【问题标题】:PyQt opening a new Windowed Widget from a MainWindow generated from QtDesignerPyQt 从 QtDesigner 生成的 MainWindow 打开一个新的 Windowed Widget
【发布时间】:2018-05-12 16:23:40
【问题描述】:

情况如下:

  • 我有一个 MainWindow 和一个 Widget
  • MainWindow 和 Widget 是从 QtDesigner 创建的。
  • 主窗口有一个可以打开小部件的按钮。
  • 我通过pyuic 传递了*.ui 文件,以便将它们转换为更加pythonic 的形式。
  • 然后我将 MainWindow 子类化,这样我就可以向按钮添加一个触发器来调用我的小部件

最终目标是当我单击 MainWindow 中的按钮时,小部件会出现在新窗口中,但是窗口会以 exit code -1 关闭

代码如下所示。我通过添加main() 函数对ExampleWidget.py 稍作改动。

# MainWindow.py

from PyQt5 import QtCore, QtGui, QtWidgets
from ui.ExampleWidget import main
from ui.ExampleMainWindow import Ui_MainWindow

class Ui_MainWindow(Ui_MainWindow):
    def setupUi(self, MainWindow):
        super().setupUi(MainWindow)
        self.pushButton.clicked.connect(main)


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

# ExampleWidget.py

from PyQt5 import QtCore, QtWidgets

class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        self.verticalLayout = QtWidgets.QVBoxLayout(Form)
        self.verticalLayout.setObjectName("verticalLayout")
        self.label = QtWidgets.QLabel(Form)
        self.label.setObjectName("label")
        self.verticalLayout.addWidget(self.label)

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

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(("Form"))
        self.label.setText(("It worked"))


def main():
    import sys
    app = QtWidgets.QApplication(sys.argv)
    Form = QtWidgets.QWidget()
    ui = Ui_Form()
    ui.setupUi(Form)
    Form.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()

【问题讨论】:

    标签: python pyqt pyqt5 qwidget qt-designer


    【解决方案1】:

    您的代码有几个错误,您继承的类与父类同名是不正确的。另一个错误是只能有一个 QApplication,因为它会在 GUI 所在的位置创建一个循环,并且当您按下按钮并调用 main() 时,您会创建另一个阻塞初始循环的循环。

    建议不要使用 Qt Designer 生成的类,因为它不是小部件,我们无法处理某些事件,最好实现使用该设计的小部件。

    根据您的代码,我可以假设 Qt Designer 生成的类是 Ui_MainWindow 和 Ui_Form,它们分别位于文件 ExampleMainWindow 和 ExampleWidget 中,并且都在 ui 文件夹中。然后你必须通过以下方式实现类:

    from PyQt5 import QtCore, QtGui, QtWidgets
    from ui.ExampleWidget import Ui_Form
    from ui.ExampleMainWindow import Ui_MainWindow
    
    class Form(QtWidgets.QWidget, Ui_Form):
        def __init__(self, *args, **kwargs):
            QtWidgets.QWidget.__init__(self, *args, **kwargs)
            self.setupUi(self)
    
    class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
        def __init__(self, *args, **kwargs):
            QtWidgets.QMainWindow.__init__(self, *args, **kwargs)
            self.setupUi(self)
            self.pushButton.clicked.connect(self.onClicked)
    
        def onClicked(self):
            self.form = Form()
            self.form.show()
    
    if __name__ == "__main__":
        import sys
        app = QtWidgets.QApplication(sys.argv)
        w = MainWindow()
        w.show()
        sys.exit(app.exec_())
    

    【讨论】:

    • 感谢您的回答。我现在意识到我的问题并不简洁,并且我已经澄清了缺失的信息。我想在按下按钮时弹出一个全新的窗口。像一个对话框窗口来显示文本。我希望这是有道理的,如果您需要进一步说明,请告诉我
    • 这就是我的解决方案所做的。你试过我的解决方案了吗?
    • 我已经尝试过您的解决方案。这是一个 gif 显示它在行动中。 i.imgur.com/eYJaYW6.gif
    • @iSwimInTheC 好的,我刚试过,你是对的,更新我的答案纠正错误,试试我的新代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-18
    • 1970-01-01
    • 2011-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-23
    相关资源
    最近更新 更多