Python:如何使用ListWidget项目存储和检索对象:简单
在使用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 个回答
我逐个尝试了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_())
这里有一个关于相同概念的实际例子(在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_())
谢谢!这是我的尝试。首先,我给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_())
你可以通过 QListWidgetItem.setData (self, role, value)
来设置 QListWidgetItem 的用户数据。
你可以定义自己的角色,这样就可以直接把特定的数据添加到这个小部件里。
要获取这些数据,可以使用 QListWidgetItem.data (self, role)
,记得要用正确的角色。