如何在我的 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_()
更好的方法是使用 QDialogButtonBox。 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,并且无法再次相乘。
我有一个显示数字的主 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_()
更好的方法是使用 QDialogButtonBox。 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,并且无法再次相乘。