使用QStackedWidget进行多窗口PyQt应用程序
问题描述:
我有一个多窗口的PyQt5(Python 3.6.2与Qt 5.9.0)应用程序,它可以在标准桌面(即窗口管理)环境中运行时完美工作。我的目标平台是嵌入式设备(例如Raspberry Pi,i.MX6等),我不会使用X11窗口系统。我目前正在使用不支持多窗口的eglfs平台测试嵌入式设备。我正在考虑使用QtWayland平台,或者修改我的方法来使用QtStackedWidget将'windows'作为单个页面包含在堆栈中。使用QStackedWidget进行多窗口PyQt应用程序
如何修改下面的高级窗口应用程序以利用QStackedWidget安排,以在无窗口环境中实现多页面应用程序?
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_()
答
我已经使用了QStackedLayout嵌套每个“窗口”的单一页面内,然后合并每个外部.py文件的setupUI()功能集成在一个外部文件。下面的文件反映了这种方法,使用我的问题中发布的示例多窗口示例。
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_())
不熟悉eglfs平台,但QStackedWidget不是特别难用。你有没有尝试过使用它?这一切都取决于你想要达到的目标,但总的来说,它应该都是可行的。你应该指定多页面应用程序的含义。在单个窗口中实现多页面应用程序的一种方法是使用QWizard。 – Trilarion
我不知道QWizard,所以谢谢你指出。我发布的示例代码代表了我正在尝试实现的基本多页面配置,从而您在应用程序启动时显示了一个主页面,其中包含多个导入的外部.py文件,这些文件显示在主要窗口。我想仍然可以导入这些外部.py文件,但将它们嵌套在主窗口中。 – jars121
我已经给出了一些更多想法,并以上面的示例代码为例进行了演示。我想我需要创建一个ui_Main.py文件,其中所有的setupUi都包含在所有'windows'中,然后有一个类Main()。 – jars121