来自其类外部的 QStackedWidget 的 setCurrentIndex

Posted

技术标签:

【中文标题】来自其类外部的 QStackedWidget 的 setCurrentIndex【英文标题】:setCurrentIndex of QStackedWidget from outside its class 【发布时间】:2018-07-26 02:24:19 【问题描述】:

我正在尝试从其类外部设置 StackedWidget 的索引,但收到对象没有属性的错误。我的代码如下(我为混乱的缩进道歉,它没有正确粘贴):

import sys
from functools import partial
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5 import QtCore, QtWidgets, QtGui

class MainWindow(QMainWindow):
  def __init__(self, parent=None):

    QMainWindow.__init__(self, parent)
    self.setWindowTitle('Sample')
    self.resize(400,400)
    qr = self.frameGeometry()  
    cp = QDesktopWidget().availableGeometry().center()  
    qr.moveCenter(cp)  
    self.move(qr.topLeft())  

    self.central_widget = QStackedWidget()
    self.setCentralWidget(self.central_widget)
    self.start_screen = ut_Screen1()
    self.central_widget.addWidget(self.start_screen)
    self.central_widget.setCurrentWidget(self.start_screen)

class ut_Screen1(QWidget):
  def __init__ ( self ):
    super ( ut_Screen1, self ).__init__ ()

    nav_layout = QVBoxLayout()
    nav_layout.setSpacing(0)
    nav_layout.setContentsMargins(0,0,0,0)
    self.setLayout(nav_layout)
    self.frame_top = QFrame()
    self.frame_top.setMinimumSize(QtCore.QSize(400,100))
    self.frame_top.setMaximumSize(QtCore.QSize(400, 100))
    self.frame_top.setStyleSheet("background-color: rgb(100, 100, 255)")

    self.frame_top.stack_t1 = ut_Nav()
    self.frame_top.StackTop = QStackedWidget(self)
    self.frame_top.StackTop.addWidget(self.frame_top.stack_t1)
    layout_top_h = QVBoxLayout(self.frame_top)
    layout_top_h.addWidget(self.frame_top.StackTop)

    self.stack_b1 = ut_Bottom1()
    self.stack_b2 = ut_Bottom2()
    self.StackBot = QStackedWidget(self)
    self.StackBot.addWidget(self.stack_b1)
    self.StackBot.addWidget(self.stack_b2)

    nav_layout.addWidget(self.frame_top)
    nav_layout.addWidget(self.StackBot)


class ut_Bottom1(QWidget):
 def __init__(self):
    super(ut_Bottom1, self).__init__()

    selection_layout = QVBoxLayout()
    self.setLayout(selection_layout)
    self.frame_bot = QFrame()
    selection_layout.addWidget(self.frame_bot)
    self.lblBottom1 = QLabel ( 'Bottom1', self.frame_bot )
    self.lblBottom1.move ( 50, 50 )

class ut_Bottom2(QWidget):
  def __init__(self):
    super(ut_Bottom2, self).__init__()

    selection_layout = QVBoxLayout()
    self.setLayout(selection_layout)
    self.frame_bot = QFrame()
    selection_layout.addWidget(self.frame_bot)
    self.lblBottom1 = QLabel ( 'Bottom2', self.frame_bot )
    self.lblBottom1.move ( 50, 50 )

class ut_Nav(QWidget):
  clicked = pyqtSignal ()
   def __init__ ( self ):
    super ( ut_Nav, self ).__init__ ()

    nav_layout = QVBoxLayout()
    self.setLayout(nav_layout)
    self.frame_nav = QFrame()
    nav_layout.addWidget(self.frame_nav)
    b1 = QtWidgets.QPushButton ("Button1", self.frame_nav )
    b1.setObjectName ('Button1')
    b1.clicked.connect (partial(ut_ButtonClicked, b1.objectName()))

def ut_ButtonClicked(name):
    try:
     if name == "Button1":
        ut_Screen1.StackBot.setCurrentIndex(1)
    except Exception as e:
      print(e)

  if __name__ == '__main__':

app = QApplication(sys.argv)
myWindow = MainWindow()
myWindow.show ()
sys.exit(app.exec_())

点击按钮时出现错误:

类型对象“ut_Screen1”没有属性“StackBot”

提前感谢您的任何指导。

【问题讨论】:

【参考方案1】:

我认为你对 OOP 的了解很差,所以我建议你复习一下。

类是一个抽象概念,它只对使用该类创建的对象的行为进行建模,因此 ut_Screen1 不是对象而是类的名称。只有对象可以使用类的非静态方法。总之,您不应该使用 ut_Screen1。

一种可能的解决方案是使用 MainWindow 类的 myWindow 对象来访问 ut_Screen1 类的名为 start_screen 的对象:

def ut_ButtonClicked(name):
    try:
        if name == "Button1":
            myWindow.start_screen.StackBot.setCurrentIndex(1)
    except Exception as e:
        print(e)

【讨论】:

首先,再次感谢完美的解决方案。其次,您对我缺乏 OOP 知识的看法是绝对正确的。我试图感受差距。非常感谢您的帮助。在不使用类 ut_Screen1 的情况下完成我想要做的事情的“最佳实践替代方案”是什么? @goryef 我不知道你想做什么。 ;) 您说我不应该在我提供的示例中使用 ut_Screen1。实现相同功能的最佳方法是什么? @goryef 这是我在回答中展示的那个。你明白为什么你不应该使用 ut_Screen1 吗? :) 我了解您的解决方案。它非常适合我。我以为你是在说我使用类的整个方法都是错误的。

以上是关于来自其类外部的 QStackedWidget 的 setCurrentIndex的主要内容,如果未能解决你的问题,请参考以下文章

在运行时更新 QStackedWidget 内容

如何将 QStackedWidget 大小设置为子小部件的最小尺寸?

QStackedWidget::setCurrentIndex() 改变场景视口

滑动 QStackedWidget 页面

PyQt5组件之QStackedWidget

将 QStackedWidget 调整为打开的页面[重复]