PySide:创建复选框列表

4
我正在尝试在PySide中创建一个复选框列表。这些复选框将位于一个框架内部的网格中。
由于我需要超过一百个复选框,所以我认为最好将这些复选框存储在一个列表中。在class Ui_MainWindow(object)中,有def setupUi(self, MainWindow),在其中调用我的方法myChanges,使用self.myChanges(MainWindow, self.customCheckBoxes, self.frame, self.gridLayout)。在那之上,我创建了一个空列表,尝试在其中存储对象,使用self.customCheckBoxes = []
在Ui_MainWindow类外面,我有一个名为CreateCheckbox的单独类,它尝试在框架下创建一个复选框,设置对象名称,在网格中添加它并设置其文本。从我所看到的情况来看,它可以完美地执行前两个步骤,问题出现在self.grid.addWidget(self.checkBox, gridPlace, 1, 1, 1)行上。更具体地说,它与grid有问题,并抛出此错误:AttributeError: 'CreateCheckbox' object has no attribute 'grid'
我的问题是:
1. 我是否使用了不正确的方式? 2. 当我传入时,我是否不允许在grid周围使用点? 3. 如何解决此问题,使所有复选框都沿着网格向下的单个文件行? 4. 我的CreateCheckbox类或myChanges方法放错位置了吗?我应该把它们放在哪里?
编辑:我想我找到了我做错的地方。在class CreateCheckbox中,应该没有self.在self.grid.addWidget(self.checkBox, gridPlace, 1, 1, 1)中,因为网格不是CreateCheckbox类的实例。
编辑2:如果有人想让文本正常工作,请在self.checkBox.setText(QtGui.QApplication.translate(MainWindow, text, None, QtGui.QApplication.UnicodeUTF8))中将MainWindow用引号括起来,这样你就有了self.checkBox.setText(QtGui.QApplication.translate("MainWindow", text, None, QtGui.QApplication.UnicodeUTF8))
以下是完整代码:
from PySide import QtCore, QtGui


class Ui_MainWindow(object):
    def myChanges(self, MainWindow, checkboxes, frame, grid):
        for j in range(100):
            checkboxes.append(CreateCheckbox(MainWindow, frame, grid, "Test", j))

    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.frame = QtGui.QFrame(self.centralwidget)
        self.frame.setGeometry(QtCore.QRect(180, 90, 371, 311))
        self.frame.setFrameShape(QtGui.QFrame.StyledPanel)
        self.frame.setFrameShadow(QtGui.QFrame.Raised)
        self.frame.setObjectName("frame")
        self.gridLayout_2 = QtGui.QGridLayout(self.frame)
        self.gridLayout_2.setObjectName("gridLayout_2")
        self.gridLayout = QtGui.QGridLayout()
        self.gridLayout.setObjectName("gridLayout")
        self.gridLayout_2.addLayout(self.gridLayout, 0, 0, 1, 1)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtGui.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtGui.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

        # Create list holding checkbox objects
        self.customCheckBoxes = []
        self.myChanges(MainWindow, self.customCheckBoxes, self.frame, self.gridLayout)

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))


class CreateCheckbox(object):
    def __init__(self, MainWindow, frame, grid, text, gridPlace):
        # 1. Create under appropriate frame
        self.checkBox = QtGui.QCheckBox(frame)
        # 2. Set its name
        #    Although the designer does this, pretty sure this is unneccesary
        self.checkBox.setObjectName(chr(gridPlace))
        # 3. Add it to the appropriate spot in the grid
        self.grid.addWidget(self.checkBox, gridPlace, 1, 1, 1)
        # 4. Set text that user sees
        # For now, I'm just sending 'Test'
        self.checkBox.setText(QtGui.QApplication.translate(MainWindow, text, None, QtGui.QApplication.UnicodeUTF8))

if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    MainWindow = QtGui.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())
2个回答

1
错误提示您的CreateCheckbox没有名为grid的成员。
我认为您想引用传递到类构造函数(__init__)中的变量grid。
class CreateCheckbox(object):
    def __init__(self, MainWindow, frame, grid, text, gridPlace):
        #################
        self.grid = grid
        #################

        # 1. Create under appropriate frame
        self.checkBox = QtGui.QCheckBox(frame)
        # 2. Set its name
        #    Although the designer does this, pretty sure this is unneccesary
        self.checkBox.setObjectName(chr(gridPlace))
        # 3. Add it to the appropriate spot in the grid
        self.grid.addWidget(self.checkBox, gridPlace, 1, 1, 1)
        # 4. Set text that user sees
        # For now, I'm just sending 'Test'
        self.checkBox.setText(QtGui.QApplication.translate(MainWindow, text, None, QtGui.QApplication.UnicodeUTF8))

1
是的,你说得对。我为什么要使用'self.grid = grid'而不是grid.addWidget...等等? - Arda Arslan
是的,如果您打算在CreateCheckbox.__init__之外的任何地方引用网格对象。 - shrewmouse

1

我认为你的代码表明你期望 CreateCheckBox 返回一个 QCheckBox 对象,但实际上并不是这样。

def myChanges(self, MainWindow, checkboxes, frame, grid):
    for j in range(100):
        checkboxes.append(CreateCheckbox(MainWindow, frame, grid, "Test", j))

CreateCheckbox 应该是一个返回 QCheckBox 对象的函数或者从 QCheckBox 派生的类。
def CreateCheckbox(MainWindow, frame, grid, text, gridPlace):
        # 1. Create under appropriate frame
        checkBox = QtGui.QCheckBox(frame)
        # 2. Set its name
        #    Although the designer does this, pretty sure this is unneccesary
        checkBox.setObjectName(chr(gridPlace))
        # 3. Add it to the appropriate spot in the grid
        grid.addWidget(checkBox, gridPlace, 1, 1, 1)
        # 4. Set text that user sees
        # For now, I'm just sending 'Test'
        checkBox.setText(QtGui.QApplication.translate(MainWindow, text, None, QtGui.QApplication.UnicodeUTF8))
        return checkBox

或者你可以把CreateCheckbox写成一个方法:

class Ui_MainWindow(object):
    def CreateCheckbox(self, MainWindow, frame, grid, text, gridPlace):
        # 1. Create under appropriate frame
        checkBox = QtGui.QCheckBox(frame)
        # 2. Set its name
        #    Although the designer does this, pretty sure this is unneccesary
        checkBox.setObjectName(chr(gridPlace))
        # 3. Add it to the appropriate spot in the grid
        grid.addWidget(checkBox, gridPlace, 1, 1, 1)
        # 4. Set text that user sees
        # For now, I'm just sending 'Test'
        checkBox.setText(QtGui.QApplication.translate(MainWindow, text, None, QtGui.QApplication.UnicodeUTF8))
        return checkBox

2
你是对的,我完全忘记了返回复选框。 - Arda Arslan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接