Creating new windows on Qtdesigner based .py files
I want to open new window from button. But my design comes from Qtdesigner. The question about QtDesigner based codes. The main problem is all those tactics are not working on qtdesigner based .py files.
I put one button at Qtdesigner. There is nothing more.
Just i wanted, when i push the button launch the same window. when i translate to python code, it gives me a class and an if structure.
Here i explained with photos: https://forum.qt.io/topic/113427/open-new-window-in-pyqt5/11
Because of this reason i copied the class and change name class Ui_MainWindow(object): >>>>>>>>>>>>>>>class Ui_MainWindow2(object):
Now i have two classes. In first class i will tried to call second class.
This the first untouched code:(so long 😉 )
# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'x.ui' # Created by: PyQt5 UI code generator 5.15.2 # WARNING: Any manual changes made to this file will be lost when pyuic5 is # run again. Do not edit this file unless you know what you are doing. from PyQt5 import QtCore, QtGui, QtWidgets class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(260, 226) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.pushButton = QtWidgets.QPushButton(self.centralwidget) self.pushButton.setGeometry(QtCore.QRect(90, 120, 75, 23)) self.pushButton.setObjectName("pushButton") MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 260, 21)) self.menubar.setObjectName("menubar") MainWindow.setMenuBar(self.menubar) self.statusbar = QtWidgets.QStatusBar(MainWindow) self.statusbar.setObjectName("statusbar") MainWindow.setStatusBar(self.statusbar) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) self.pushButton.setText(_translate("MainWindow", "PushButton")) 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_())
I just copied the class. Now i have two. And i added a simple def for calling the other class.
Finally any solution didn’t help me. Especially designer based codes hasn’t solution.
from PyQt5 import QtCore, QtGui, QtWidgets class Ui_MainWindow2(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(260, 226) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.pushButton = QtWidgets.QPushButton(self.centralwidget) self.pushButton.setGeometry(QtCore.QRect(90, 120, 75, 23)) self.pushButton.setObjectName("pushButton") MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 260, 21)) self.menubar.setObjectName("menubar") MainWindow.setMenuBar(self.menubar) self.statusbar = QtWidgets.QStatusBar(MainWindow) self.statusbar.setObjectName("statusbar") MainWindow.setStatusBar(self.statusbar) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) self.pushButton.setText(_translate("MainWindow", "PushButton")) class Ui_MainWindow(object): def **init**(self): self.nextWindow = Ui_MainWindow2() def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(260, 226) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.pushButton = QtWidgets.QPushButton(self.centralwidget) self.pushButton.setGeometry(QtCore.QRect(90, 120, 75, 23)) self.pushButton.setObjectName("pushButton") MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 260, 21)) self.menubar.setObjectName("menubar") MainWindow.setMenuBar(self.menubar) self.statusbar = QtWidgets.QStatusBar(MainWindow) self.statusbar.setObjectName("statusbar") MainWindow.setStatusBar(self.statusbar) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) self.pushButton.setText(_translate("MainWindow", "PushButton")) self.pushButton.clicked.connect(self.launcher) def launcher(self): self.nextWindow.show() 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_()) ------------------------- martin | 2021-03-01 07:02:26 UTC | #2 First up, it's not a good idea to edit the Python files generated from Qt Designer. They are automatically generated from the UI file: once you change them, you can no longer change your UI in Qt Designer, without re-applying all the changes you have made. The best way to do this is to import the class from the generated py file into your own code. For example, say you have a file named `main.py` which imports your `Ui_MainWindow2` like follows (you'll need to change the from import to your own filename).
from mainwindow import Ui_MainWindow2
You can then create a window the same way as you have at the bottom of your file
ui = Ui_MainWindow() ui.setupUi(MainWindow) MainWindow.show() sys.exit(app.exec_())
To add custom behaviour onto your window class you need to subclass it. For example
class MyMainWindow(QtWidgets.QMainWindow, Ui_MainWindow): def init(self, *args, kwargs): super().init(*args, kwargs) self.setupUi(self)
window = MyMainWindow() window.show() sys.exit(app.exec_())
You can add any custom behaviour in this subclass definition. So for example, to add your clicked handler, you could do.
class MyMainWindow(QtWidgets.QMainWindow, Ui_MainWindow): def init(self, *args, kwargs): super().init(*args, kwargs) self.setupUi(self)
set.pushButton.clicked.connect(self.launcher)
def launcher(self): self.nextWindow = QtWidgets.QMainWindow()
window = MyMainWindow() window.show() sys.exit(app.exec_())
If you want to create an identical second window (I wouldn't recommend this for a real app, but. )
class MyMainWindow(QtWidgets.QMainWindow, Ui_MainWindow): def init(self, *args, kwargs): super().init(*args, kwargs) self.setupUi(self)
set.pushButton.clicked.connect(self.launcher)
def launcher(self): self.nextWindow = MyMainWindow2() self.nextWinodw.show()
class MyMainWindow2(QtWidgets.QMainWindow, Ui_MainWindow): def init(self, *args, kwargs): super().init(*args, kwargs) self.setupUi(self)
window = MyMainWindow() window.show() sys.exit(app.exec_()) «`
I think this introduction to using Qt Designer UIs will be useful as it has a few other options for using your UI files.
yilmazbah10043 | 2021-02-23 13:56:22 UTC | #3
IT’S WORKING. Thank you too much.
from PyQt5 import QtWidgets import sys
from mainWindow import Ui_MainWindow
class MyMainWindow(QtWidgets.QMainWindow, Ui_MainWindow): _def init__(self, *args, kwargs): _super()._init(*args, kwargs) _self.nextWindow = MyMainWindow2() #PCYCHARM offered to sent init__ ____self.setupUi(self)
____self.pushButton.clicked.connect(self.launcher)
_def launcher(self): __ self.nextWindow.show()
class MyMainWindow2(QtWidgets.QMainWindow, Ui_MainWindow): _def init__(self, *args, kwargs): _super()._init(*args, kwargs) ____self.setupUi(self)
window = MyMainWindow() window.show() sys.exit(app.exec_())
1:1 Python GUIs Coaching & Training
Comprehensive code review • Bugfixes & improvements • Maintainability advice and architecture improvements • Design and usability assessment • Suggestions and tips to expand your knowledge • Packaging and distribution help for Windows, Mac & Linux • Find out more.
Как создать новое окно в PyQt5?
Есть созданное в Designer главное окно с кнопкой. Все это сохранено в файл test.ui.
Также в Designer создано новое пустое окно класса QWidget и сохранено в файл test2.ui.
В файле нового окна test2.py содержится:
def new_form(): new_window = uic.loadUi("interface2.ui") new_window.setWindowTitle("New form") new_window.show()
В файле главного окна test.py:
import test2 main_window.pushButton.clicked.connect(test2.new_form)
Если нажать в главном окне на кнопку, то новое окно откроется и сразу закроется. Подскажите, пожалуйста, как заставить это окно постоянно отображаться?
причина: переменная new_window умирает сразу как заканчивается функция new_form() (почему? во славу Сатаны конечно!)
Пути решения:
1) создать какую нибудь глобальную переменную. Но глобальные переменные это плохой тон (незнаю почему) :
new_window = None def new_form(): global new_window new_window = uic.loadUi("interface2.ui") new_window.setWindowTitle("New form") new_window.show()
2) создать переменную глобальный массив окон (так делаю я — это всё ещё «плохой тон» но зато потом можно циклом разом удалить все создаваемые окна например. ) :
мой_список_окон = [] def new_form(): global мой_список_окон new_window = uic.loadUi("interface2.ui") new_window.setWindowTitle("New form") new_window.show() мой_список_окон.append(new_window)
3) назначить new_window дочерю main_window (идиологически правильный вариант):
def new_form(parent): new_window = uic.loadUi("interface2.ui") new_window.setWindowTitle("New form") new_window.show() new_window.setParent(parent) import test2 main_window.pushButton.clicked.connect(lambda: test2.new_form(main_window))
4) new_window должна быть переменной того обьекта который гарантировано не будет удалён (незнаю насчёт идиалогии. все варианты правильные. ):
def new_form(parent): parent.new_window = uic.loadUi("interface2.ui") parent.new_window.setWindowTitle("New form") parent.new_window.show() import test2 main_window.pushButton.clicked.connect(lambda: test2.new_form(main_window))