jars121
jars121

Reputation: 1157

Using QStackedWidget for multi-windowed PyQt application

I have a multi-windowed PyQt5 (Python 3.6.2 with Qt 5.9.0) application which works perfectly when run in a standard desktop (i.e. window managed) environment. My target platform is an embedded device (Raspberry Pi, i.MX6, etc. for example), where I won't be using the X11 window system. I'm currently testing the embedded device with the eglfs platform, which doesn't support multiple windows. I'm considering either using the QtWayland platform, or modifying my approach to use a QtStackedWidget to contain the 'windows' as individual pages within the stack.

How can I modify the below high-level windowed application to leverage a QStackedWidget arrangement, to facilitate a multi-paged application in a windowless environment?

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow

from ui_Main import Ui_Main
from ui_Window1 import Ui_Window1
from ui_Window2 import Ui_Window2

class Main(QMainWindow, Ui_Main):
    def __init__(self, parent=None):
        super(Main, self).__init__(parent)
        self.setupUi(self)

        #Initialisation functions

        self.PushButton1.clicked.connect(self.OpenWindow1)
        self.PushButton2.clicked.connect(self.OpenWindow2)

    def OpenWindow1(self):
        showWindow1.show()

    def OpenWindow2(self):
        showWindow2.show()

class Window1(QMainWindow, Ui_Window1):
    def __init__(self, parent=None):
        super(Window1, self).__init__(parent)
        self.setupUi(self)

class Window2(QMainWindow, Ui_Window2):
    def __init__(self, parent=None):
        super(Window2, self).__init__(parent)
        self.setupUi(self)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    showMain = Main()
    showWindow1 = Window1()
    showWindow2 = Window2()
    showMain.show()

    app.exec_()

Upvotes: 1

Views: 9543

Answers (1)

jars121
jars121

Reputation: 1157

I've used a QStackedLayout to nest each of the 'windows' within a single page, and then consolidated each of the setupUI() functions of the external .py files into a single external file. The below files reflect this approach, using the sample multi-window example posted in my question.

ui_Main.py:

from PyQt5 import QtCore, QtGui, QtWidgets

import sys

class Ui_Main(QtWidgets.QWidget):
    def setupUi(self, Main):
        Main.setObjectName("Main")
        Main.resize(800, 480)

        self.QtStack = QtWidgets.QStackedLayout()

        self.stack1 = QtWidgets.QWidget()
        self.stack2 = QtWidgets.QWidget()
        self.stack3 = QtWidgets.QWidget()

        self.Window1UI()
        self.Window2UI()
        self.Window3UI()

        self.QtStack.addWidget(self.stack1)
        self.QtStack.addWidget(self.stack2)
        self.QtStack.addWidget(self.stack3)

    def Window1UI(self):
        self.stack1.resize(800, 480)

        #PushButton1#
        self.PushButton1 = QtWidgets.QPushButton(self.stack1)
        self.PushButton1.setText("BUTTON 1")
        self.PushButton1.setGeometry(QtCore.QRect(10, 10, 100, 100))

        #PushButton2#
        self.PushButton2 = QtWidgets.QPushButton(self.stack1)
        self.PushButton2.setText("BUTTON 2")
        self.PushButton2.setGeometry(QtCore.QRect(150, 150, 100, 100))

    def Window2UI(self):
        self.stack2.resize(800, 480)
        self.stack2.setStyleSheet("background: red")

    def Window3UI(self):
        self.stack3.resize(800, 480)
        self.stack3.setStyleSheet("background: blue")

Main.py:

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow

import sys

from ui_Main import Ui_Main

class Main(QMainWindow, Ui_Main):
    def __init__(self, parent=None):
        super(Main, self).__init__(parent)
        self.setupUi(self)

        self.PushButton1.clicked.connect(self.OpenWindow1)
        self.PushButton2.clicked.connect(self.OpenWindow2)

    def OpenWindow1(self):
        self.QtStack.setCurrentIndex(1)

    def OpenWindow2(self):
        self.QtStack.setCurrentIndex(2)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    showMain = Main()
    sys.exit(app.exec_())

Upvotes: 2

Related Questions