如何在我的 mainwindow 中使用另一个 window 的输入(使用 PyQt5 和 qt-designer)?

How can I use the input of another window in my mainwindow (using PyQt5 and qt-designer)?

我有一个显示数字的主 window,当单击一个按钮时,第二个 window 应该出现在您可以输入比例因子的地方。当在第二个 window 上按“确定”时,主 window 中的数字应乘以第二个 window 的比例因子并应将其关闭。

这是我用于生成 MainApp 和创建第二个 window:

的代码
from ui_Whosebug1 import *
from ui_Whosebug2 import *
import sys

class ScaleApp(Ui_ScaleWindow):

    def __init__(self, window2):

        self.setupUi(window2)

    # Todo: see below


class ButtonConnection(Ui_MainWindow):

    def __init__(self, window):

        self.setupUi(window)
        self.pushButton.clicked.connect(self.open_scale_window)

        self.important_number = 5
        self.lineEdit.setText(str(self.important_number))

    def open_scale_window(self):

        self.scale_window = QMainWindow()
        self.scale_ui = ScaleApp(self.scale_window)
        self.scale_window.show()

        # TODO
        # open new window (ui_Whosebug2)
        # wait for "ok" being pressed
        # take the input of the QSpinBox
        # use the input to scale self.important_number by this input

        self.lineEdit.setText(str(self.important_number))


if __name__ == "__main__":

    app = QApplication(sys.argv)
    MainWindow = QMainWindow()

    ui = ButtonConnection(MainWindow)

    MainWindow.show()
    app.exec_()

如何实现数字的缩放?


________________________________________________________

我使用 Qt-designer 使用以下代码创建了两个 UI:

# -*- coding: utf-8 -*-

################################################################################
## Form generated from reading UI file 'Stackoverlow1tsISdv.ui'
##
## Created by: Qt User Interface Compiler version 5.15.2
##
## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################

from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        if not MainWindow.objectName():
            MainWindow.setObjectName(u"MainWindow")
        MainWindow.resize(440, 275)
        self.centralwidget = QWidget(MainWindow)
        self.centralwidget.setObjectName(u"centralwidget")
        self.pushButton = QPushButton(self.centralwidget)
        self.pushButton.setObjectName(u"pushButton")
        self.pushButton.setGeometry(QRect(90, 10, 261, 151))
        self.lineEdit = QLineEdit(self.centralwidget)
        self.lineEdit.setObjectName(u"lineEdit")
        self.lineEdit.setGeometry(QRect(160, 180, 113, 20))
        self.lineEdit.setAlignment(Qt.AlignCenter)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QMenuBar(MainWindow)
        self.menubar.setObjectName(u"menubar")
        self.menubar.setGeometry(QRect(0, 0, 440, 21))
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QStatusBar(MainWindow)
        self.statusbar.setObjectName(u"statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)

        QMetaObject.connectSlotsByName(MainWindow)
    # setupUi

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"MainWindow", None))
        self.pushButton.setText(QCoreApplication.translate("MainWindow", u"PushButton", None))
        self.lineEdit.setText(QCoreApplication.translate("MainWindow", u"1", None))
    # retranslateUi


class Ui_ScaleWindow(object):
    def setupUi(self, ScaleWindow):
        if not ScaleWindow.objectName():
            ScaleWindow.setObjectName(u"ScaleWindow")
        ScaleWindow.resize(419, 201)
        self.centralwidget = QWidget(ScaleWindow)
        self.centralwidget.setObjectName(u"centralwidget")
        self.ok_button = QPushButton(self.centralwidget)
        self.ok_button.setObjectName(u"ok_button")
        self.ok_button.setGeometry(QRect(120, 110, 75, 23))
        self.cancel_button = QPushButton(self.centralwidget)
        self.cancel_button.setObjectName(u"cancel_button")
        self.cancel_button.setGeometry(QRect(210, 110, 75, 23))
        self.scaling_box = QDoubleSpinBox(self.centralwidget)
        self.scaling_box.setObjectName(u"scaling_box")
        self.scaling_box.setGeometry(QRect(170, 50, 62, 22))
        ScaleWindow.setCentralWidget(self.centralwidget)
        self.menubar = QMenuBar(ScaleWindow)
        self.menubar.setObjectName(u"menubar")
        self.menubar.setGeometry(QRect(0, 0, 419, 21))
        ScaleWindow.setMenuBar(self.menubar)
        self.statusbar = QStatusBar(ScaleWindow)
        self.statusbar.setObjectName(u"statusbar")
        ScaleWindow.setStatusBar(self.statusbar)

        self.retranslateUi(ScaleWindow)

        QMetaObject.connectSlotsByName(ScaleWindow)
    # setupUi

    def retranslateUi(self, ScaleWindow):
        ScaleWindow.setWindowTitle(QCoreApplication.translate("ScaleWindow", u"Scaling", None))
        self.ok_button.setText(QCoreApplication.translate("ScaleWindow", u"OK", None))
        self.cancel_button.setText(QCoreApplication.translate("ScaleWindow", u"Cancel", None))
    # retranslateUi

为了达到你想要的效果,你不能在第二个 window 中使用 QMainWindow,而是使用 QDialog,它会创建一个 modal主要 window 上的对话框,一旦“执行”,就会等到它关闭。

然后,用pyside-uic创建的类用于直接实例创建多重继承。从它们继承是没有意义的。

首先,再次创建第二个 window,但从“Dialog”开始,而不是“Main Window”,然后生成再次显示其 python 代码。

这是您要实现的目标的可能实现:

class ScaleWindow(QDialog, Ui_ScaleWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setupUi(self)
        self.ok_button.clicked.connect(self.close)


class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.important_number = 5
        self.lineEdit.setText(str(self.important_number))
        self.pushButton.clicked.connect(self.open_scale_window)

    def open_scale_window(self):
        scale_window = ScaleWindow(self)
        scale_window.exec_()
        self.important_number *= scale_window.scaling_box.value()
        self.lineEdit.setText(str(self.important_number))

if __name__ == "__main__":

    app = QApplication(sys.argv)
    mainWindow = MainWindow()
    mainWindow.show()
    app.exec_()

更好的方法是使用 QDialogBu​​ttonBox。 Designer 为 QDialog 提供了三个模板:一个是空的,两个带有按钮(垂直或水平放置)。

如果你用按钮创建对话框,它会自动将按钮框信号连接到对话框的信号,所以如果你按 Ok 对话框将被接受,如果你按 Cancel它将被拒绝。

这也可以手动完成,方法是将按钮框添加到对话框,并使用 Designer 的编辑 signal/slot 模式(将 accepted 信号连接到 accept 插槽对话,以及 rejected 信号到 reject 插槽)。或者,也可以通过代码来完成:

class ScaleWindow(QDialog, Ui_ScaleWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setupUi(self)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)

注意:如果信号已在 Designer 中连接,您应该不要在您的代码中再次连接它们

这允许检查用户是否真的在对话框中按下了确定,否则该值将被忽略:

class MainWindow(QMainWindow, Ui_MainWindow):
    # ...
    def open_scale_window(self):
        scale_window = ScaleWindow(self)
        if scale_window.exec_() and scale_window.scaling_box.value():
            self.important_number *= scale_window.scaling_box.value()
            self.lineEdit.setText(str(self.important_number))

请注意,我在 if 语句中添加了进一步的检查:如果值为 0,则 important_number 将变为 0,并且无法再次相乘。