Reputation: 89
I have a main window that displays a number, when clicking a button a second window should appear where you can input a scaling factor. When pressing "Ok" on the second window, the number in the main window should be multiplied by the scaling factor of the 2nd window and it should be closed.
This is the code I used for generating the MainApp and the creation of the 2nd window:
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_()
How can I achieve the scaling of the number?
I used Qt-designer to create both UIs using the following code:
# -*- 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
Upvotes: 0
Views: 1215
Reputation: 48384
In order to achieve what you want, you cannot use a QMainWindow for the second window, but a QDialog, which creates a modal dialog over the main window and, once "executed" waits until it's closed.
Then, the classes created with pyside-uic
are intended for direct instance creation or multiple inheritance. Subclassing from them is pointless.
First of all, create again the second window, but starting from a "Dialog", not a "Main Window", then generate its python code again.
This is a possible implementation of what you're trying to achieve:
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_()
An even better approach is to use a QDialogButtonBox. Designer provides three templates for QDialog: one empty, and two with the buttons (vertically or horizontally placed).
If you create the dialog with buttons, it will automatically connect the button box signals to those of the dialog, so if you press Ok
the dialog will be accepted, if you press Cancel
it will be rejected.
This can be also done manually by adding the button box to the dialog, and using the edit signal/slot mode of Designer (connect the accepted
signal to the accept
slot of the dialog, and the rejected
signal to the reject
slot). Alternatively, it can also be done by code:
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)
Note: if the signals are already connected in Designer, you should NOT connect them again in your code
This allows checking if the user actually pressed Ok in the dialog, otherwise the value will be ignored:
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))
Note that I added a further check in the if statement: if the value is 0, important_number
will become 0 and it could not be multiplied ever again.
Upvotes: 1