首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >QStackedWidget打开多个窗口

QStackedWidget打开多个窗口
EN

Stack Overflow用户
提问于 2020-08-01 08:05:17
回答 1查看 487关注 0票数 0

我使用PyQt构建了一个小型应用程序,据我所知,QStackedWidget用于制作多页应用程序。问题是它正在打开多个页面,而且我也无法使用class Abc中的按钮重定向到class Abc

main.py

代码语言:javascript
复制
from PyQt4 import QtGui, QtCore
import sys

class Window(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(Window, self).__init__(parent)

        self.stacked_widget = QtGui.QStackedWidget()

        layout = QtGui.QVBoxLayout()
        layout.setContentsMargins(0,0,0,0)
        layout.addWidget(self.stacked_widget)

        widget = QtGui.QWidget()
        widget.setLayout(layout)
        self.setCentralWidget(widget)

        widget_1 = Abc(self.stacked_widget)
        widget_2 = Xyz(self.stacked_widget)

        self.stacked_widget.addWidget(widget_1)
        self.stacked_widget.addWidget(widget_2)

        self.showMaximized()

class Abc(QtGui.QWidget):
    def __init__(self, stacked_widget, parent=None):
        super(Abc, self).__init__(parent)
        
        self.stacked_widget = stacked_widget

        self.frame = QtGui.QFrame()
        self.frame_layout = QtGui.QVBoxLayout()
        self.button = QtGui.QPushButton('Click me!')
        self.button.clicked.connect(self.click)
        self.frame_layout.addWidget(self.button)
        self.frame.setLayout(self.frame_layout)

        self.layout = QtGui.QVBoxLayout()
        self.layout.addWidget(self.frame)
        self.setLayout(self.layout)

        self.showMaximized()

    def click(self):
        print("You clicked me!")
        self.stacked_widget.setCurrentIndex(1)

class Xyz(QtGui.QWidget):
    def __init__(self, parent=None):
        super(Xyz, self).__init__(parent)

        self.frame_layout = QtGui.QStackedLayout()
        self.page1 = Page("Page 1", self.frame_layout)
        self.page2 = Page("Page 2", self.frame_layout)
        self.frame_layout.addWidget(self.page1)
        self.frame_layout.addWidget(self.page2)


class Page(QtGui.QWidget):
    def __init__(self, text, frame_layout, parent=None):
        super(Page, self).__init__(parent)

        print(self.width(), self.height())
        self.frame_layout = frame_layout

        self.frame = QtGui.QFrame()
        self.frame_layout = QtGui.QVBoxLayout()
        self.frame.setStyleSheet("background-color: rgb(191, 191, 191)")
        self.label = QtGui.QLabel()
        self.label.setText(text)
        self.frame_layout.addWidget(self.label, alignment=QtCore.Qt.AlignCenter)
        self.frame.setLayout(self.frame_layout)

        self.layout = QtGui.QVBoxLayout()
        self.layout.addWidget(self.frame)
        self.layout.setContentsMargins(0,0,0,0)
        self.setLayout(self.layout)

        self.showMaximized()
        print(self.width(), self.height())


if __name__ == "__main__":
    app = QtGui.QApplication([])
    window = Window()
    window.show()
    sys.exit(app.exec_())
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-08-02 20:07:28

主要问题是,您没有为QStackedLayout小部件设置Xyz,结果是所有页面实际上都将显示为顶级窗口。

当一个小部件被添加到一个布局中时,它获得了它的所有权;如果布局已经设置为一个小部件,那么添加到布局中的小部件就会被另一个小部件修复。如果之后设置布局,也会发生同样的情况。

为什么它将第一页显示为一个单独的窗口?为什么它不显示第二个呢?

当创建一个没有父级的新小部件时,它就变成了一个顶层窗口;当一个小部件被添加到一个新的堆叠布局中时,Qt会自动尝试显示它;您没有将布局设置为任何东西(这将像前面解释的那样重新创建它),结果就是第一个页面显示为一个独立窗口。

现在,由于第一次只显示第一个“屏幕”,您可以将该小部件设置为中心小部件,然后将Xyz实例(实际上是一个QStackedWidget子类)设置为一个新的中心小部件。

注意,您不需要使用QWidget来添加一个QFrame,如果这是显示的唯一父小部件:您可以只是子类QFrame。

这是一个更简单、更简洁的代码版本:

代码语言:javascript
复制
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_())
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63203087

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档