为什么我的第二个 window 有不同的布局?

Why does my second window have a different layout?

我正在使用 PyQt5 创建多个 windows。这些 windows 应该能够在不弹出新 windows 的情况下更改视图。但是,当使用完全相同的布局和按钮向主 window 添加另一个 window 时,window 布局会有所不同。

我想要的是使用与 Main window 完全相同的布局选项。我的代码可以在下面找到:

from PyQt5 import QtWidgets, QtCore, QtGui
from PyQt5.QtCore import Qt
import sys

class mainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        # MAIN WINDOW SETTINGS
        self.central_widget = QtWidgets.QStackedWidget()
        self.setGeometry(400, 150, 1200, 700)
        self.setWindowTitle('Main window')
        
        # COMPOSE MAIN WINDOW
        self.settings = {'grid': {'row': [5,0,0,0,1], 'column': [1,3,1,1]}}
        self.grid = QtWidgets.QGridLayout()
        self.grid.setVerticalSpacing(20)
        for row, stretch in enumerate(self.settings['grid']['row']):
            self.grid.setRowStretch(row, stretch)
        for column, stretch in enumerate(self.settings['grid']['column']):
            self.grid.setColumnStretch(column, stretch)
            
        self.b1 = QtWidgets.QPushButton("Button 1")
        self.b1.clicked.connect(lambda: self.b1_handler('second window'))
        self.b2 = QtWidgets.QPushButton("Button 2")
        self.b2.clicked.connect(self.b2_handler)
        self.b3 = QtWidgets.QPushButton("Button 3")
        self.b3.clicked.connect(self.b3_handler)
        self.b4 = QtWidgets.QPushButton("Button 4")
        self.b4.clicked.connect(self.b4_handler)
        self.b5 = QtWidgets.QPushButton("Button 5")
        self.b5.clicked.connect(self.b5_handler)       
        
        self.grid.addWidget(self.b1, 1, 1)
        self.grid.addWidget(self.b2, 1, 2)
        self.grid.addWidget(self.b3, 2, 1)
        self.grid.addWidget(self.b4, 3, 1)
        self.grid.addWidget(self.b5, 4, 3)
        
        self.main_window = QtWidgets.QWidget()
        self.main_window.setLayout(self.grid)
        
        # TEST WINDOW
        self.second_window = Second_window(self)
        
        # FINISH MAIN WINDOW AND SHOW INITIAL SCREEN
        self.central_widget.addWidget(self.main_window)
        self.central_widget.addWidget(self.second_window)
        self.setCentralWidget(self.central_widget)
        self.current_window = self.main_window
    def b1_handler(self, to_window):
        if to_window == 'second window':
            self.current_window.hide()
            self.second_window.show()
            self.current_window = self.second_window
        elif to_window == 'main window':
            self.current_window.hide()
            self.main_window.show()
            self.current_window = self.main_window
            
    def b2_handler(self):
        pass
    def b3_handler(self):
        pass
    def b4_handler(self):
        pass
    def b5_handler(self):
        pass

class Second_window(QtWidgets.QWidget):
    def __init__(self, parent):
        super().__init__()
        self.parent = parent
        # Create grid
        self.settings = {'grid': {'row': [5,0,0,0,1], 'column': [1,3,1,1]}}
        self.grid = QtWidgets.QGridLayout()        
        self.grid.setVerticalSpacing(20)
        for row, stretch in enumerate(self.settings['grid']['row']):
            self.grid.setRowStretch(row, stretch)
        for column, stretch in enumerate(self.settings['grid']['column']):
            self.grid.setColumnStretch(column, stretch)
        
        # CREATE WIDGETS ON PAGE
        self.b1 = QtWidgets.QPushButton("Button 1")
        self.b1.clicked.connect(self.b1_handler)
        self.b2 = QtWidgets.QPushButton("Button 2")
        self.b2.clicked.connect(self.b2_handler)
        self.b3 = QtWidgets.QPushButton("Button 3")
        self.b3.clicked.connect(self.b3_handler)
        self.b4 = QtWidgets.QPushButton("Button 4")
        self.b4.clicked.connect(self.b4_handler)
        self.b5 = QtWidgets.QPushButton("Button 5")
        self.b5.clicked.connect(self.b5_handler)
        
        self.grid.addWidget(self.b1, 1, 1)
        self.grid.addWidget(self.b2, 1, 2)
        self.grid.addWidget(self.b3, 2, 1)
        self.grid.addWidget(self.b4, 3, 1)
        self.grid.addWidget(self.b5, 4 ,3)
        
        # SET LAYOUT
        self.setLayout(self.grid)
    def b1_handler(self):
        pass 
    def b2_handler(self):
        pass
    def b3_handler(self):
        pass
    def b4_handler(self):
        pass
    def b5_handler(self):
        self.parent.b1_handler('main window')

def main():
    app = QtWidgets.QApplication(sys.argv)
    App = mainWindow()
    App.show()
    # sys.exit(app.exec_())
    currentExitCode = app.exec_()

if __name__ == '__main__':
    main()

使用这段代码,我的 windows 看起来像这样:

主要window:

第二个window:

从主要 window,我使用按钮 1 导航到第二个 window。从第二个 window,我使用按钮 5 导航回主 window。我有什么地方没看懂吗?

强制显示添加到 QStackedWidget 的小部件不是显示它们的正确方法,因为堆叠布局不会收到有关更改的通知,也无法正确中继调整大小事件。

要在小部件之间切换,您必须使用 class 提供的功能,如 QStackedWidget 的主要文档中所述:

The index of the widget that is shown on screen is given by currentIndex() and can be changed using setCurrentIndex(). In a similar manner, the currently shown widget can be retrieved using the currentWidget() function, and altered using the setCurrentWidget() function.

更改为:

    def b1_handler(self, to_window):
        if to_window == 'second window':
            self.central_widget.setCurrentWidget(self.second_window)
        elif to_window == 'main window':
            self.central_widget.setCurrentWidget(self.main_window)

您也不需要对当前页面的引用,因为 currentWidget() 已经动态提供了。