1

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_()
jars121
  • 1,127
  • 2
  • 20
  • 35
  • Not familiar with the eglfs platform but QStackedWidget is not particularly difficult to use. Have you tried to just use it? It all depends on what you exactly want to achieve but in general it should all be doable.You should specify what you mean by multi-paged application. One way of implementing a multi-paged application within a single window is using a QWizard. – NoDataDumpNoContribution Aug 11 '17 at 07:52
  • I wasn't aware of QWizard, so thank you for pointing that out. The sample code I've posted represents the basic multi-page configuration I'm trying to achieve, whereby you have a main page which is shown on application start, with multiple imported, external .py files which are shown on top of the main window. I'd like to still be able to import these external .py files, but nest them within the main window. – jars121 Aug 11 '17 at 12:03
  • I've given this some more thought, and have played around with the above sample code as an example. I think I need to create a single ui_Main.py file, where all the setupUi is contained for all the 'windows', and then have a single class Main(). – jars121 Aug 11 '17 at 22:36

1 Answers1

2

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_())
jars121
  • 1,127
  • 2
  • 20
  • 35