Основная проблема заключается в том, что вы не устанавливаете QStackedLayout для виджета Xyz
, в результате все страницы фактически отображаются как верхний уровень windows.
Когда виджет добавляется в макет, он становится его владельцем; если макет уже настроен на виджет, то виджет, который был добавлен в макет, становится родителем другого. То же самое произойдет, если вы установите макет , а затем .
Почему первая страница отображается как отдельное окно? И почему не показывает второе? Когда новый виджет создается без родителя, он становится окном верхнего уровня; когда виджет добавляется к новому составному макету, Qt автоматически пытается его показать; вы не установили макет ни на что (что изменило бы его, как объяснялось ранее), и в результате первая страница отображается как отдельное окно.
Теперь, поскольку первый "экран" чтобы он отображался только в первый раз, вы можете установить этот виджет как центральный виджет, а затем установить экземпляр Xyz (который на самом деле является подклассом QStackedWidget) как новый центральный виджет.
Обратите внимание, что вам не нужно использовать QWidget для добавления QFrame, если это единственный показанный родительский виджет: вы можете просто создать подкласс QFrame.
Это гораздо более простая и чистая версия вашего кода:
from PyQt4 import QtGui, QtCore
class Window(QtGui.QMainWindow):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
self.startPage = Abc()
self.setCentralWidget(self.startPage)
self.startPage.startRequest.connect(self.buildPages)
def buildPages(self):
self.pages = Xyz()
self.setCentralWidget(self.pages)
class Abc(QtGui.QFrame):
startRequest = QtCore.pyqtSignal()
def __init__(self, parent=None):
super(Abc, self).__init__(parent)
layout = QtGui.QVBoxLayout(self)
self.button = QtGui.QPushButton('Click me!')
self.button.clicked.connect(self.startRequest)
layout.addWidget(self.button)
class Xyz(QtGui.QStackedWidget):
def __init__(self, parent=None):
super(Xyz, self).__init__(parent)
self.page1 = Page("Page 1")
self.page2 = Page("Page 2")
self.addWidget(self.page1)
self.addWidget(self.page2)
self.page1.switchRequest.connect(lambda: self.setCurrentIndex(1))
self.page2.switchRequest.connect(lambda: self.setCurrentIndex(0))
class Page(QtGui.QFrame):
switchRequest = QtCore.pyqtSignal()
def __init__(self, text, parent=None):
super(Page, self).__init__(parent)
layout = QtGui.QVBoxLayout(self)
# set the background only for QFrame subclasses (which also includes
# QLabel), this prevents setting the background for other classes,
# such as the push button
self.setStyleSheet('''
QFrame {
background-color: rgb(191, 191, 191)
}
''')
# when adding a widget to a layout, the layout tries to automatically
# make it as big as possible (based on the widget's sizeHint); so you
# should not use the alignment argument for layout.addWidget(), but for
# the label instead
self.label = QtGui.QLabel(text, alignment=QtCore.Qt.AlignCenter)
layout.addWidget(self.label)
self.switchButton = QtGui.QPushButton('Switch')
layout.addWidget(self.switchButton)
self.switchButton.clicked.connect(self.switchRequest)
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())