PySide多窗口,让QStackWidget工作

时间:2014-10-30 14:49:36

标签: python constructor parent-child pyside qstackedwidget

我需要创建多窗口GUI,首先我尝试使用QWidgets,但最后我发现了我需要使用的QStackWidget工具。所以我想,但我遇到了一些问题。谢谢你的时间。

class MainWindow(QMainWindow):

    def __init__(self):

        super(MainWindow,self).__init__()

        self.mainWidget = MainWidget()
        self.searchWidget = SearchWidget()
        self.sWidget = QStackedWidget()
        self.sWidget.addWidget(self.mainWidget)
        self.sWidget.addWidget(self.searchWidget)

        self.initUI() 

并从sub_widget类调用setCurrentWidget:

class MainWidget(QWidget):

    def __init__(self, parent=MainWindow):

        super(MainWidget,self).__init__()
        self.initUI()

    def initUI(self):

        searchButton = QPushButton('searchButton',self)
        optionButton = QPushButton('optionButton',self)
        quitButton = QPushButton('quitButton',self)
        listButton = QPushButton('listButton',self)

        searchButton.clicked.connect(self.goSearch)

        hbox = QHBoxLayout()
        hbox.addWidget(listButton)
        hbox.addWidget(quitButton)

        vbox = QVBoxLayout()
        vbox.addStretch(1)
        vbox.addWidget(searchButton)
        vbox.addWidget(optionButton)
        vbox.addLayout(hbox)

        self.setLayout(vbox)

    def goSearch(self):
        self.parent().sWidget.setCurrentWidget(self.parent().searchWidget)

我从IDE收到了这条消息:

  self.parent().sWidget.setCurrentWidget(self.parent().searchWidget)
  AttributeError: 'PySide.QtGui.QStackedWidget' object has no attribute 'sWidget'

我做错了什么?

2 个答案:

答案 0 :(得分:0)

这一行:

    def __init__(self, parent=MainWindow):
当您确实需要实例时,

MainWindow 设置为默认参数。但即使它是一个实例,在下一行中,您也无法将其传递给基类:

    super(MainWidget,self).__init__()

你需要做的是这样的事情:

class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow,self).__init__()
        # pass an instance of MainWindow here
        self.mainWidget = MainWidget(self)
        ...

class MainWidget(QWidget):
    def __init__(self, parent):
        # pass the parent to the base-class
        super(MainWidget, self).__init__(parent)
        ...

<强>更新

stack-widget将重新添加添加到其中的任何窗口小部件,以便 it 成为父窗口。有办法解决这个问题,但我认为代码的真正问题在于你的结构是倒退的。设置当前窗口小部件的按钮应该由主窗口控制,并且堆栈中的窗口小部件应该完全独立地工作。

答案 1 :(得分:0)

我将对您在此处发布的代码发表评论:http://pastebin.com/fBfS1X5m

要知道的一件重要事情是,您可以将小部件放在小部件中等等。例如:

class Widget(QWidget):
    def __init__(self, parent=None):
        layout = QVBoxLayout(self)
        childWidget = QWidget(parent=self)
        layout.addWidget(childWidget)

快速说明:如果您通过docssetLayout传递给主版块构造函数,则不需要self

无论如何,我在这里要说明的是QStackedWidgetSearchWidget真的不应该成为MainWindow的一部分,但应该活着在他们自己的相关小部件中,它将处理QStackedWidget页面之间的切换。

例如,MainWindow.__init__只会如下所示:

class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()

        self.mainWidget = MainWidget(self)
        self.setCentralWidget(self.mainWidget)

        self.initUI()

您的MainWidget看起来像是:

class MainWidget(QtGui.QWidget):
    ...

    def initUI(self):
        ...

        self.stack = QtGui.QStackedWidget(parent=self)

        self.searchWidget = SearchWidget(parent=self)
        self.searchWidget.searchButton.clicked.connect(self.goSearch)
        self.backWidget = BackWidget(parent=self)
        self.backWidget.backButton.clicked.connect(self.goBack)

        ...

    def goSearch(self):
        self.stack.setCurrentWidget(self.backWidget)

    def goBack(self):
        self.stack.setCurrentWidget(self.searchWidget)

我已经重命名了一些课程名称以使其更有意义(至少对我而言)。 SearchWidget是您的旧MainWidgetBackWidget是您的旧SearchWidget。这些更改SearchWidget看起来与旧的MainWidget相同,但有一个例外 - 我们保存对搜索按钮的引用,以便我们可以在MainWidget类中访问它,如上所示(当我们将他们的信号连接到我们的插槽)。我们对BackWidget中的按钮执行相同操作。

两个改名为'#34;孩子&#34;窗口小部件:

class SearchWidget(QtGui.QWidget):
    ...

    def initUI(self):
        self.searchButton = QtGui.QPushButton('searchButton', parent=self)
        optionButton = QtGui.QPushButton('optionButton', parent=self)
        quitButton = QtGui.QPushButton('quitButton', parent=self)
        listButton = QtGui.QPushButton('listButton', parent=self)

        vbox = QtGui.QVBoxLayout(self)
        vbox.addStretch(1)
        vbox.addWidget(self.searchButton)
        vbox.addWidget(optionButton)

        hbox = QtGui.QHBoxLayout()
        hbox.addWidget(listButton)
        hbox.addWidget(quitButton)

        vbox.addLayout(hbox)

class BackWidget(QtGui.QWidget):
    ...

    def initUI(self):
        self.backButton = QtGui.QPushButton('GoBack', parent=self)

现在我们有类似的东西:

MainWindow  
   |---MainWidget  
          |---QStackedWidget  
                 |---SearchWidget  
                 |---BackWidget  

您可以找到完整的工作代码here