【问题标题】:PySide - QStackedLayout.setCurrentIndex() does not work as expected when it's inside a for-loopPySide - QStackedLayout.setCurrentIndex() 在 for 循环内时无法按预期工作
【发布时间】:2016-06-18 02:20:50
【问题描述】:

我正在实现一个 UI,它在顶部包含几个按钮,并且在这些按钮下有一个 QStackedLayout 对象,单击不同按钮的目的应该自动切换到其关联的 QWidget,它位于 QStackedLayout 对象内。并且按钮的数量及其关联的 QWidget 是动态添加的。

例如,这里我想实现一个简单的窗口,它包含两个按钮'a'和'b',理想情况下,当点击'a'按钮时,你应该看到下面的标签'a',这意味着QStackedLayout设置为包含 QLabel 'a' 的适当小部件,类似的规则也应适用于按钮 'b'。所以我写了以下代码:

import sys

from PySide.QtCore import *
from PySide.QtGui import * 

class main_gui(QWidget):

    def __init__(self, parent = None):
        super(main_gui, self).__init__(parent)

        #create a root level widget 
        self.main_widget = QWidget()
        #create a root level layout that holds all the child widgets
        self.main_layout = QVBoxLayout(self.main_widget)      

        # widgets for buttons layout
        self.asset_type_buttons_widget = QWidget()
        # layout for all buttons
        self.asset_type_buttons_layout = QHBoxLayout(self.asset_type_buttons_widget)

        # now create the stack layout
        self.asset_stacked_widget = QWidget()
        self.asset_stacked_layout = QStackedLayout(self.asset_stacked_widget)

        # add the buttons and stack layout into the root level layout
        self.main_layout.addWidget(self.asset_type_buttons_widget)
        self.main_layout.addWidget(self.asset_stacked_widget)    

        #dynamically adds buttons and stacked widgets, here we're going to add 2 buttons, which their labels are 'a' and 'b'
        self.create_asset_sections(self.asset_stacked_layout, self.asset_type_buttons_layout, 'a','b')    

        self.main_widget.show()

    def create_asset_sections(self, stack_layout, parent_buttons_layout, *asset_types):
        # asset_types represents any arbitrary number of buttons and their associated stacked widgets
        for type in asset_types:

            index = asset_types.index(type)

            self.type_top_button = QPushButton(type)

            parent_buttons_layout.addWidget(self.type_top_button)     

            self.type_top_widget = QWidget()
            self.type_top_layout = QVBoxLayout(self.type_top_widget)

            i = stack_layout.insertWidget(index, self.type_top_widget)   

            self.test_label = QLabel(type)
            self.type_top_layout.addWidget(self.test_label)

            self.type_top_button.clicked.connect(lambda: stack_layout.setCurrentIndex(i))

app = QApplication(sys.argv)         
gui = main_gui()          
app.exec_()

但是执行上面的代码你应该注意到标签'a'只出现一次,那么无论你点击按钮'a'或按钮'b',标签'b'总是显示在按钮下方。

我也尝试修改代码然后使用 QStackedLayout.setCurrentWidget() 方法,这里是另一个版本的 create_asset_sections()

def create_asset_sections(self, stack_layout, parent_buttons_layout, *asset_types):
    # create a dictionary that holds the buttons and their associated stack widgets
    self.map_buttons_widgets = {}

    for type in asset_types:

        self.type_top_button = QPushButton(type)

        parent_buttons_layout.addWidget(self.type_top_button)     

        self.type_top_widget = QWidget()
        self.type_top_layout = QVBoxLayout(self.type_top_widget)

        stack_layout.addWidget(self.type_top_widget)   

        self.test_label = QLabel(type)
        self.type_top_layout.addWidget(self.test_label)

        self.map_buttons_widgets[self.type_top_button] = self.type_top_widget

    for btn, wigt in self.map_buttons_widgets.iteritems():

        btn.clicked.connect(lambda: stack_layout.setCurrentWidget(wigt))

所以用上面的方法代替之前的方法也无助于达到我的初衷。

有什么想法吗?提前感谢您的回答。

【问题讨论】:

标签: python-2.7 pyside


【解决方案1】:

看到这个question。这是一个不同的问题,但他们基本上有相同的问题。这行是问题

self.type_top_button.clicked.connect(lambda: stack_layout.setCurrentIndex(i))

具体

lambda: stack_layout.setCurrentIndex(i)

问题是i 的值在您创建 lambda 函数时未计算。它在调用 lambda 函数时进行评估,到那时,循环已经完成,每个 lambda 将在循环结束时使用完全相同的 i 值,而不是 i 时的值lambda 已创建。

您可以通过两种方式解决此问题。第一种是在lambda 中使用默认参数,这会强制在创建函数时评估i 的值。

lambda i=i: stack_layout.setCurrentIndex(i) 

或者,您可以使用functools.partial

from functools import partial

self.type_top_button.clicked.connect(partial(layout.setCurrentIndex, i))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-26
    • 1970-01-01
    • 2022-01-09
    • 1970-01-01
    • 2021-04-13
    • 1970-01-01
    • 2021-07-31
    • 1970-01-01
    相关资源
    最近更新 更多