How to Change UI in Same Window Using Pyqt5

How to change UI in same window using PyQt5?

You have to use a QStackedWidget

import os
import sys
from PyQt5 import QtCore, QtGui, QtWidgets, uic

ui_folder = os.path.join("frontend", "ui")
about_company_ui, _ = uic.loadUiType(os.path.join(ui_folder, "about_company.ui"))
intern_placement_ui, _ = uic.loadUiType(os.path.join(ui_folder, "intern_placement.ui"))

class InternPlacement(QtWidgets.QMainWindow, intern_placement_ui):
def __init__(self, parent=None):
super(InternPlacement, self).__init__(parent)
self.setupUi(self)

class AboutCompany(QtWidgets.QMainWindow, about_company_ui):
def __init__(self, parent=None):
super(AboutCompany, self).__init__(parent)
self.setupUi(self)

if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
intern_window = InternPlacement()
about_window = AboutCompany()
w = QtWidgets.QStackedWidget()
w.addWidget(intern_window)
w.addWidget(about_window)
intern_window.intern_pushButton.clicked.connect(lambda: w.setCurrentIndex(1))
w.resize(640, 480)
w.show()
sys.exit(app.exec_())

How to change window/widget with PyQt5 using .ui files?

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.

PyQt: Change GUI Layout after button is clicked

The solution I propose is based on the function setupUi() that generates Qt Designer, this is responsible for creating the internal elements of the window.

import sys

from PyQt4.QtGui import QApplication, QMainWindow, QPushButton, QWidget
#For PyQt5 :
#from PyQt5.QWidgets import QApplication , QMainWindow , QPushButton , QWidget
class UIWindow(object):
def setupUI(self, MainWindow):
MainWindow.setGeometry(50, 50, 400, 450)
MainWindow.setFixedSize(400, 450)
MainWindow.setWindowTitle("UIWindow")
self.centralwidget = QWidget(MainWindow)
# mainwindow.setWindowIcon(QtGui.QIcon('PhotoIcon.png'))
self.ToolsBTN = QPushButton('text', self.centralwidget)
self.ToolsBTN.move(50, 350)
MainWindow.setCentralWidget(self.centralwidget)

class UIToolTab(object):
def setupUI(self, MainWindow):
MainWindow.setGeometry(50, 50, 400, 450)
MainWindow.setFixedSize(400, 450)
MainWindow.setWindowTitle("UIToolTab")
self.centralwidget = QWidget(MainWindow)
self.CPSBTN = QPushButton("text2", self.centralwidget)
self.CPSBTN.move(100, 350)
MainWindow.setCentralWidget(self.centralwidget)

class MainWindow(QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.uiWindow = UIWindow()
self.uiToolTab = UIToolTab()
self.startUIWindow()

def startUIToolTab(self):
self.uiToolTab.setupUI(self)
self.uiToolTab.CPSBTN.clicked.connect(self.startUIWindow)
self.show()

def startUIWindow(self):
self.uiWindow.setupUI(self)
self.uiWindow.ToolsBTN.clicked.connect(self.startUIToolTab)
self.show()

if __name__ == '__main__':
app = QApplication(sys.argv)
w = MainWindow()
sys.exit(app.exec_())

Start:

Sample Image

After button clicked:

Sample Image

After another button clicked:

Sample Image

and more elegant solution:

import sys

from PyQt4.QtGui import QApplication, QMainWindow, QPushButton, QWidget
#For PyQt5 :
#from PyQt5.QWidgets import QApplication , QMainWindow , QPushButton , QWidget

class UIWindow(QWidget):
def __init__(self, parent=None):
super(UIWindow, self).__init__(parent)
# mainwindow.setWindowIcon(QtGui.QIcon('PhotoIcon.png'))
self.ToolsBTN = QPushButton('text', self)
self.ToolsBTN.move(50, 350)

class UIToolTab(QWidget):
def __init__(self, parent=None):
super(UIToolTab, self).__init__(parent)
self.CPSBTN = QPushButton("text2", self)
self.CPSBTN.move(100, 350)

class MainWindow(QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setGeometry(50, 50, 400, 450)
self.setFixedSize(400, 450)
self.startUIToolTab()

def startUIToolTab(self):
self.ToolTab = UIToolTab(self)
self.setWindowTitle("UIToolTab")
self.setCentralWidget(self.ToolTab)
self.ToolTab.CPSBTN.clicked.connect(self.startUIWindow)
self.show()

def startUIWindow(self):
self.Window = UIWindow(self)
self.setWindowTitle("UIWindow")
self.setCentralWidget(self.Window)
self.Window.ToolsBTN.clicked.connect(self.startUIToolTab)
self.show()

if __name__ == '__main__':
app = QApplication(sys.argv)
w = MainWindow()
sys.exit(app.exec_())

Affect one window with another in PYQT5

Answering my own question (with the help of musicamante)

Instead of calling the function I use pyqtSignals to send a signal

class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.ui.button_open_settings.clicked.connect
(self.open_settings)

def open_settings(self):
self.settings_window = settings.MainWindow_settings(self)
self.settings_window.toggle_submitter.connect(self.set_toggle_vis)
self.settings_window.show()

def set_toggle_vis(self, toggle):
self.ui.frame_toggle_list.setVisible(toggle)

settings window.py

class MainWindow_settings(QMainWindow):
toggle_submitter = pyqtSignal(int)

def __init__(self, *args, **kwargs):
super(MainWindow_settings, self).__init__(*args,**kwargs)
self.ui = settings_ui.Ui_Form()
self.ui.setupUi(self)

def change_toggle(self)
toggle_enabled = 1
self.toggle_submitter.emit(toggle_enabled)


Related Topics



Leave a reply



Submit