访问变量而不使用列表。动态访问变量名称

时间:2017-03-02 18:55:00

标签: python python-3.x pyqt4

我发现的所有答案都只是说使用字典或列表。 我正在制作一个应用程序,并且GUI正在QT创建者中进行设计。有一系列复选框(21),在Qt Creator中都标有cb0 .... cb20。我有一个21元素列表,表示是否应该选中复选框。有没有办法循环变量名称?伪代码:

for i in range(21):
    if cbList[i]:
        cb'i'.setChecked=True
    else:
        cb'i'.setChecked=False

如何让cb'i'将i翻译成变量名?

为清晰起见添加: 我不想创建字典,然后将字典值设置为true或false。变量已经存在。它们是GUI中的复选框。所有复选框都是名称cb0 ... cb20。它们具有我希望为复选框的每个实例调用的函数setChecked。例如,cb0.setChecked(False)将禁用该复选框。我有一个与每个复选框对应的列表。我试图避免为所有21个复选框写cb1.setChecked(True)

3 个答案:

答案 0 :(得分:5)

这是一个糟糕的主意。要找出原因,请阅读article

而是使用列表或字典选项。

cb = defaultdict(dict)
for i in range(21):
    if cbList[i]:
        cb[i]['setChecked'] = True
    else:
        cb[i]['setChecked'] = False

使用字典可以使用“关联存储器”或“关联数组”调用变量,而不必知道数组中对象的索引。要实现您想要的效果,请按以下方式提供字典键:

cb["cb%s"%(i)]

这样,如果需要,您可以将特定变量4称为:cb['cb4']

编辑: 我刚刚意识到你的意思是你试图打电话给QT复选框。在这种情况下,我建议您不要使用复选框列表,而是可以使用字典,其中字典的键是复选框ID的名称,值是QT对象本身。

cb = {}
for i in range(21):
    cb['cb%s'%i] = getattr(self.ui, 'cb%s'%i)

现在,当您想要将特定复选框设置为true或false时,您只需调用:

cb['cb3'].setChecked(True)

为什么这是一个更好的编码实践:你只需要为每个复选框迭代一次getattr(当你最初设置字典时)。此外,如果进行单个更改,则可以直接获取要操作的对象。

答案 1 :(得分:2)

如果复选框是在Qt Designer中创建的,它们最终将作为顶级窗口或ui命名空间的属性。

鉴于此,正确的解决方案是使用getattr

class MainWindow(QtGui.QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        ...
        for i in range(21):
            checkbox = getattr(self.ui, 'cb%s' % i)
            if cbList[i]:
                checkbox.setChecked(True)
            else:
                checkbox.setChecked(False)

答案 2 :(得分:0)

您应该使用QT的内置数据结构,在这里您可以获得可索引和可​​迭代的数据结构,就像上面带有列表和词典的示例一样。

以下是QListWidget

的示例
import sys
from PyQt4.QtGui import *

app = QApplication(sys.argv)

listWidget = QListWidget()

for i in range(10):
    item = QListWidgetItem("Item %i" % i)
    listWidget.addItem(item)

listWidget.show()
sys.exit(app.exec_())

虽然在某些语言中可以使用变量名称连接,但它主要取决于是否有一个额外的终端(如PHP中的$)来表示变量。语法解析器不会故意理解变量名称连接。这实际上是为了帮助您避免手工制作意大利面。