Python:如何使用ListWidget项目存储和检索对象:简单

1 投票
4 回答
6136 浏览
提问于 2025-04-18 00:02

在使用QListWidget和其他类似的列表控件后,我终于找到了一个简单的方法来存储和获取列表项的类(QListWidgetItem)。我之前遇到的问题是,我以为QListWidgetItem只能用来存储它的标签名称(就是在列表中显示的那个名字)。当QListWidget被填充了QListWidgetItems后,我不得不声明一个字典,其中每个键都是项的标签名称,而值则是对应的对象(这种方法有点危险,因为两个或多个项可能有相同的名字,而字典中同一个名字只能有一个键)。然后,当点击某个项时,我会捕获那个列表项的标签(名字),然后在字典的键中查找对应的对象。如果我声明一个自己的自定义类myItem(),并让它继承自QListWidgetItem,这样就可以轻松避免这些问题。现在,当点击某个列表项时,我可以直接从中获取对象,就像调用.getTime()方法一样。如果在我决定在代码中使用这种方法之前,有什么我遗漏或误解的地方,请告诉我。

from PyQt4 import QtGui, QtCore
import sys, os


class myItem(QtGui.QListWidgetItem):
    def __init__(self, name):
        super(myItem, self).__init__()
        self.name=name
    def getTime(self):
        import datetime
        return datetime.datetime.now()   

class Dialog_01(QtGui.QMainWindow):
    def __init__(self):
        super(QtGui.QMainWindow,self).__init__()

        myQWidget = QtGui.QWidget()
        myBoxLayout = QtGui.QVBoxLayout()
        myQWidget.setLayout(myBoxLayout)
        self.setCentralWidget(myQWidget)

        self.listWidget = QtGui.QListWidget()

        self.listWidget.currentItemChanged.connect(self.item_clicked)

        for i in range(12):
            name='Item '+str(i)
            my_item=myItem(name)
            my_item.setText('Item '+str(i))
            self.listWidget.addItem(my_item)

        myBoxLayout.addWidget(self.listWidget)

    def item_clicked(self, arg=None):
        print arg.text(), arg.getTime()


if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    dialog_1 = Dialog_01()
    dialog_1.show()
    dialog_1.resize(480,320)
    sys.exit(app.exec_())

4 个回答

0

我逐个尝试了QVariant类中所有以'to'开头的方法:

'toBool', 'toByteArray', 'toChar', 'toDate', 'toDateTime', 'toDouble', 'toEasingCurve', 'toFloat', 'toHash', 'toInt', 'toLine', 'toLineF', 'toList', 'toLocale', 'toLongLong', 'toMap', 'toModelIndex', 'toPoint', 'toPointF', 'toPyObject', 'toReal', 'toRect', 'toRectF', 'toRegExp', 'toSize', 'toSizeF', 'toString', 'toStringList', 'toTime', 'toUInt', 'toULongLong', 'toUrl', 'toUuid'

我发现toPyObject()方法返回的对象和当初创建时存储在列表项中的对象完全一样(下面的例子中是MyClass()的实例):

        myObject=MyClass()            
        my_item.setData(QtCore.Qt.UserRole, myObject)

这是对我有效的代码。如果我说错了,请纠正我。

from PyQt4 import QtGui, QtCore
import sys, os

class MyClass(object):
    def __init__(self):
        super(MyClass, self).__init__()
    def getTime(self):
        import datetime
        return datetime.datetime.now()         

class Dialog_01(QtGui.QMainWindow):
    def __init__(self):
        super(QtGui.QMainWindow,self).__init__()

        myQWidget = QtGui.QWidget()
        myBoxLayout = QtGui.QVBoxLayout()
        myQWidget.setLayout(myBoxLayout)
        self.setCentralWidget(myQWidget)

        self.listWidget = QtGui.QListWidget()

        self.listWidget.currentItemChanged.connect(self.item_clicked)

        for i in range(12):
            name='Item '+str(i)
            my_item=QtGui.QListWidgetItem()
            my_item.setText('Item '+str(i))
            self.listWidget.addItem(my_item)

            myObject=MyClass()            
            my_item.setData(QtCore.Qt.UserRole, myObject)

        myBoxLayout.addWidget(self.listWidget)

        Button_01 = QtGui.QPushButton("Get Items")
        Button_01.clicked.connect(self.getListItemsFromQListWidget)               
        myBoxLayout.addWidget(Button_01)

    def item_clicked(self, arg=None):
        myObject = arg.data(QtCore.Qt.UserRole)
        print myObject.toPyObject().getTime()

    def getListItemsFromQListWidget(self):
        for i in range(self.listWidget.count()):
            print self.listWidget.item(i).data(QtCore.Qt.UserRole).toPyObject().getTime()

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    dialog_1 = Dialog_01()
    dialog_1.show()
    dialog_1.resize(480,320)
    sys.exit(app.exec_())
0

这里有一个关于相同概念的实际例子(在Qt项目中存储数据)。这次是用在下拉框(ComboBox)里的:

from PyQt4 import QtGui, QtCore
import sys, os

class MyClass(object):
    def __init__(self):
        super(MyClass, self).__init__()
        self.myAttr=None
    def getTime(self):
        import datetime
        return datetime.datetime.now() 

class Dialog_01(QtGui.QMainWindow):
    def __init__(self):
        super(QtGui.QMainWindow,self).__init__()

        myQWidget = QtGui.QWidget()
        myBoxLayout = QtGui.QVBoxLayout()
        myQWidget.setLayout(myBoxLayout)
        self.setCentralWidget(myQWidget)

        self.ComboBox = QtGui.QComboBox() 
        for i in range(12):
            name='Item '+str(i)
            myObject=MyClass()
            self.ComboBox.addItem( name, myObject )

        self.ComboBox.currentIndexChanged.connect(self.combobox_selected)
        myBoxLayout.addWidget(self.ComboBox)

    def combobox_selected(self, index):
        myObject=self.ComboBox.itemData(index).toPyObject()
        print myObject.getTime()

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    dialog_1 = Dialog_01()
    dialog_1.show()
    dialog_1.resize(480,320)
    sys.exit(app.exec_())
1

谢谢!这是我的尝试。首先,我给myObject赋值:

my_item.setData (QtCore.Qt.UserRole, myObject)

然后在点击的时候,用下面的方式把它取回来:

myObject = arg.data(QtCore.Qt.UserRole)

在item_clicked时得到的myObject是。请问哪里出错了?

from PyQt4 import QtGui, QtCore
import sys, os


class MyClass(object):
    def __init__(self):
        super(MyClass, self).__init__()
    def getTime(self):
        import datetime
        return datetime.datetime.now()         


class Dialog_01(QtGui.QMainWindow):
    def __init__(self):
        super(QtGui.QMainWindow,self).__init__()

        myQWidget = QtGui.QWidget()
        myBoxLayout = QtGui.QVBoxLayout()
        myQWidget.setLayout(myBoxLayout)
        self.setCentralWidget(myQWidget)

        self.listWidget = QtGui.QListWidget()

        self.listWidget.currentItemChanged.connect(self.item_clicked)

        for i in range(12):
            name='Item '+str(i)
            my_item=QtGui.QListWidgetItem()
            my_item.setText('Item '+str(i))
            self.listWidget.addItem(my_item)

            myObject=MyClass()
            my_item.setData (QtCore.Qt.UserRole, myObject)

        myBoxLayout.addWidget(self.listWidget)

    def item_clicked(self, arg=None):
        myObject = arg.data(QtCore.Qt.UserRole)
        print dir(myObject)

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    dialog_1 = Dialog_01()
    dialog_1.show()
    dialog_1.resize(480,320)
    sys.exit(app.exec_())
2

你可以通过 QListWidgetItem.setData (self, role, value) 来设置 QListWidgetItem 的用户数据。

你可以定义自己的角色,这样就可以直接把特定的数据添加到这个小部件里。

要获取这些数据,可以使用 QListWidgetItem.data (self, role),记得要用正确的角色。

撰写回答