PyQt 从 QtDesigner 生成的 MainWindow 打开一个新的 Windowed Widget
PyQt opening a new Windowed Widget from a MainWindow generated from QtDesigner
情况如下:
- 我有一个MainWindow和一个Widget
- MainWindow 和 Widget 是从 QtDesigner 创建的。
- Mainwindow 有一个可以打开 Widget 的按钮。
- 我通过
pyuic
传递了 *.ui
文件,以便将它们变成更像 Python 的形式。
- 然后我将 MainWindow 子类化,这样我就可以向按钮添加触发器来调用我的 Widget
最终目标是当我单击 MainWindow 中的按钮时让小部件出现在新的 window 中,但是 windows 以 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()
您的代码有几个错误,您继承的 class 与父级同名是不正确的。另一个错误是只能有一个 QApplication,因为它会在 GUI 所在的位置创建一个循环,当您按下按钮并调用 main()
时,您会创建另一个循环来阻止初始循环。
建议不要使用Qt Designer生成的class,因为它不是一个widget,我们不能处理某些事件,实现一个使用该设计的widget是合适的。
根据您的代码,我可以假设 Qt Designer 生成的 classes 分别是文件 ExampleMainWindow 和 ExampleWidget 中的 Ui_MainWindow 和 Ui_Form,并且都在ui 文件夹。那么您必须按以下方式实现 classes:
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_())
情况如下:
- 我有一个MainWindow和一个Widget
- MainWindow 和 Widget 是从 QtDesigner 创建的。
- Mainwindow 有一个可以打开 Widget 的按钮。
- 我通过
pyuic
传递了*.ui
文件,以便将它们变成更像 Python 的形式。 - 然后我将 MainWindow 子类化,这样我就可以向按钮添加触发器来调用我的 Widget
最终目标是当我单击 MainWindow 中的按钮时让小部件出现在新的 window 中,但是 windows 以 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()
您的代码有几个错误,您继承的 class 与父级同名是不正确的。另一个错误是只能有一个 QApplication,因为它会在 GUI 所在的位置创建一个循环,当您按下按钮并调用 main()
时,您会创建另一个循环来阻止初始循环。
建议不要使用Qt Designer生成的class,因为它不是一个widget,我们不能处理某些事件,实现一个使用该设计的widget是合适的。
根据您的代码,我可以假设 Qt Designer 生成的 classes 分别是文件 ExampleMainWindow 和 ExampleWidget 中的 Ui_MainWindow 和 Ui_Form,并且都在ui 文件夹。那么您必须按以下方式实现 classes:
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_())