Reputation: 95
first of all thanks for your time and sorry for the question length, the real question is just the first part. I can't understand ho to realize a 'page' change, like a web application. I would like to do that using .ui files, representing widgets or main windows. Basically, I would like to have two classes, each one mapped with an .ui file implementing a view, and switch between the two views when a button is clicked.
I would like to have is something like that:
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
# then load the home page file home.ui
class HomePage:
def method_0(self):
# method to load and show the home.ui file, at startup
def method_1(self):
# method to load and show the home.ui file, when a button in Second Page is pressed
class SecondPage
def method_1(self):
# method to load and show the second.ui file when a button in HomePage is pressed
if __name__ == '__main__':
app = QApplication([])
window = MainWindow()
window.show()
app.exec_()
After lots of researches I wrote the code below that almost realize that, I said almost because I must use the same class for all. What I want instead is to have one .py file for each .ui file to keep things separated.
from PyQt5 import uic
from PyQt5.QtWidgets import QApplication, QMainWindow, QStackedWidget
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.resize(800, 620)
self.central_widget = QStackedWidget()
self.setCentralWidget(self.central_widget)
self.home_page()
def home_page(self):
widget = uic.loadUi('home.ui')
self.central_widget.addWidget(widget)
self.central_widget.setCurrentWidget(widget)
widget.change_btn.clicked.connect(self.second_page)
def second_page(self):
widget = uic.loadUi('second.ui')
self.central_widget.addWidget(widget)
self.central_widget.setCurrentWidget(widget)
widget.change_btn.clicked.connect(self.home_page)
if __name__ == '__main__':
app = QApplication([])
window = MainWindow()
window.show()
app.exec_()
And this is the code for both .ui files, just change the filename to home.ui
and second.ui
, and change btn text to see the page change. They are simple widgets with one button each
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>620</height>
</rect>
</property>
<property name="windowTitle">
<string>Application</string>
</property>
<widget class="QWidget" name="centralwidget">
<property name="title" stdset="0">
<string>GroupBox</string>
</property>
<widget class="QPushButton" name="change_btn">
<property name="geometry">
<rect>
<x>285</x>
<y>170</y>
<width>230</width>
<height>40</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>Change page</string>
</property>
</widget>
</widget>
<widget class="QStatusBar" name="statusbar"/>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>26</height>
</rect>
</property>
</widget>
</widget>
<resources/>
<connections/>
</ui>
Upvotes: 1
Views: 8114
Reputation: 48489
What you need to do is to create separate widgets (not windows). While this is already covered in other similar questions (like this, I'll answer anyway due to the different files request.
The solution is still the same, using a QStackedWidget, that allows you to switch between different widgets that occupy the same part of the window, similarly to what QTabWidget does, but without the tab bar.
First, you need to create a main window in designer, add a QStackedWidget there and ensure that you remove all of its pages (right click on the stacked widget, and select "Delete" in the "Page x of x" sub menu).
Then create separate widgets (just select "Widget" in the dialog that appears when creating a new form) for each page.
Finally, use loadUi
on the main window and on each child widget.
I'll recommend you to keep the logic of the page switching in the code of the main window, instead of having it in the different pages, as it's a better and cleaner approach having a "parent" controller when dealing with this situations.
pages.py:
from PyQt5 import uic
from PyQt5.QtWidgets import QApplication, QMainWindow
from first import First
from second import Second
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
uic.loadUi('pages.ui', self)
self.first = First()
self.stackedWidget.addWidget(self.first)
self.first.change_btn.clicked.connect(self.go_to_second)
self.second = Second()
self.stackedWidget.addWidget(self.second)
self.second.change_btn.clicked.connect(self.go_to_first)
def go_to_first(self):
self.stackedWidget.setCurrentIndex(0)
def go_to_second(self):
self.stackedWidget.setCurrentIndex(1)
if __name__ == '__main__':
app = QApplication([])
window = MainWindow()
window.show()
app.exec_()
first.py
from PyQt5 import uic
from PyQt5.QtWidgets import QWidget
class First(QWidget):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
uic.loadUi('first.ui', self)
second.py
from PyQt5 import uic
from PyQt5.QtWidgets import QWidget
class Second(QWidget):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
uic.loadUi('second.ui', self)
There is also the possibility of using QWizard, but it's usually suggested for more complex cases than yours.
Upvotes: 3