【问题标题】:How can I use the input of another window in my mainwindow (using PyQt5 and qt-designer)?如何在我的主窗口中使用另一个窗口的输入(使用 PyQt5 和 qt-designer)?
【发布时间】:2021-09-24 08:34:37
【问题描述】:

我有一个显示数字的主窗口,单击按钮时应该会出现第二个窗口,您可以在其中输入比例因子。在第二个窗口按“确定”时,主窗口中的数字应乘以第二个窗口的比例因子,然后关闭。

这是我用于生成 MainApp 和创建第二个窗口的代码:

from ui_Stackoverflow1 import *
from ui_Stackoverflow2 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_Stackoverflow2)
        # 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

【问题讨论】:

    标签: python qt-designer pyside2


    【解决方案1】:

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

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

    首先,再次创建第二个窗口,但从“Dialog”开始,而不是“主窗口”,然后再次生成其 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 的编辑信号/槽模式来手动完成(将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,并且不能再次相乘。

    【讨论】:

    • 好的,但是我怎么知道“确定”按钮是否真的被点击了?单击取消按钮时,数字是否也会更新?我可以解决它并在单击取消时将旋转框的内容设置为 1,然后对话框将关闭,但它似乎不太正确。
    • @KaiWinkler 查看更新。另外请不要尝试编辑部分代码,除非您完全确定自己在做什么:您创建 QDialog 的建议是错误的,因为 ScaleWindow 已经 继承自 QDialog。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-03
    • 2017-04-30
    • 2016-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多