1#!/usr/bin/env python 2 3#============================================================================# 4# PyQt5 port of the designer/containerextension example from Qt v5.x # 5#----------------------------------------------------------------------------# 6from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QSize 7from PyQt5.QtWidgets import (QApplication, QComboBox, QLabel, QStackedWidget, 8 QVBoxLayout, QWidget) 9 10 11#============================================================================# 12# Implementation of a MultiPageWidget using a QComboBox and a QStackedWidget # 13#----------------------------------------------------------------------------# 14class PyMultiPageWidget(QWidget): 15 16 currentIndexChanged = pyqtSignal(int) 17 18 pageTitleChanged = pyqtSignal(str) 19 20 def __init__(self, parent=None): 21 super(PyMultiPageWidget, self).__init__(parent) 22 23 self.comboBox = QComboBox() 24 # MAGIC 25 # It is important that the combo box has an object name beginning 26 # with '__qt__passive_', otherwise, it is inactive in the form editor 27 # of the designer and you can't change the current page via the 28 # combo box. 29 # MAGIC 30 self.comboBox.setObjectName('__qt__passive_comboBox') 31 self.stackWidget = QStackedWidget() 32 self.comboBox.activated.connect(self.setCurrentIndex) 33 self.layout = QVBoxLayout() 34 self.layout.addWidget(self.comboBox) 35 self.layout.addWidget(self.stackWidget) 36 self.setLayout(self.layout) 37 38 def sizeHint(self): 39 return QSize(200, 150) 40 41 def count(self): 42 return self.stackWidget.count() 43 44 def widget(self, index): 45 return self.stackWidget.widget(index) 46 47 @pyqtSlot(QWidget) 48 def addPage(self, page): 49 self.insertPage(self.count(), page) 50 51 @pyqtSlot(int, QWidget) 52 def insertPage(self, index, page): 53 page.setParent(self.stackWidget) 54 self.stackWidget.insertWidget(index, page) 55 title = page.windowTitle() 56 if title == "": 57 title = "Page %d" % (self.comboBox.count() + 1) 58 page.setWindowTitle(title) 59 self.comboBox.insertItem(index, title) 60 61 @pyqtSlot(int) 62 def removePage(self, index): 63 widget = self.stackWidget.widget(index) 64 self.stackWidget.removeWidget(widget) 65 self.comboBox.removeItem(index) 66 67 def getPageTitle(self): 68 cw = self.stackWidget.currentWidget() 69 return cw.windowTitle() if cw is not None else '' 70 71 @pyqtSlot(str) 72 def setPageTitle(self, newTitle): 73 cw = self.stackWidget.currentWidget() 74 if cw is not None: 75 self.comboBox.setItemText(self.getCurrentIndex(), newTitle) 76 cw.setWindowTitle(newTitle) 77 self.pageTitleChanged.emit(newTitle) 78 79 def getCurrentIndex(self): 80 return self.stackWidget.currentIndex() 81 82 @pyqtSlot(int) 83 def setCurrentIndex(self, index): 84 if index != self.getCurrentIndex(): 85 self.stackWidget.setCurrentIndex(index) 86 self.comboBox.setCurrentIndex(index) 87 self.currentIndexChanged.emit(index) 88 89 pageTitle = pyqtProperty(str, fget=getPageTitle, fset=setPageTitle, stored=False) 90 currentIndex = pyqtProperty(int, fget=getCurrentIndex, fset=setCurrentIndex) 91 92 93#============================================================================# 94# Main for testing the class # 95#----------------------------------------------------------------------------# 96if __name__ == "__main__": 97 import sys 98 app = QApplication(sys.argv) 99 widget = PyMultiPageWidget() 100 widget.addPage(QLabel('This is page #1')) 101 widget.addPage(QLabel('This is page #2')) 102 widget.show() 103 sys.exit(app.exec_()) 104 105#============================================================================# 106# EOF # 107#----------------------------------------------------------------------------# 108