为什么 QComboBox.findData() 不接受对象作为输入?
Why doesn't QComboBox.findData() accept an object as input?
我将对象作为 UserData 附加到 QStandardItem,该对象被添加到 QComboBox 模型。如果我随后使用 findData() 方法搜索它,我将得不到任何结果。如果我对一个简单的 int 做同样的事情,我会得到一个结果。我想这是 PySide 相关的,但我在源代码中找不到包装器。这是一个(有点)最小的例子:
import sys
from PySide import QtGui
class Foo(object):
def __init__(self, value):
self.value = value
class MyCombo(QtGui.QWidget):
def __init__(self, *args):
QtGui.QWidget.__init__(self, *args)
combo = QtGui.QComboBox()
combo.addItem(str(1), Foo(1))
combo.addItem(str(2), 2)
data = combo.itemData(0)
print(data) # prints the object repr
print(combo.findData(data)) # returns -1 -> not found
data = combo.itemData(1)
print(data) # prints 2
print(combo.findData(data)) # returns 1 -> found
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
w = MyCombo()
w.show()
sys.exit(app.exec_())
为什么对象的 findData() return -1?任何关于可以搜索的内容的提示都将受到赞赏!
QT C++ doc 提供了解释。这是 findData
的定义,强调我的:
int QComboBox::findData(const QVariant & data, int role =
Qt::UserRole, Qt::MatchFlags flags = static_cast (
Qt::MatchExactly | Qt::MatchCaseSensitive )) const
组合框中的数据只能是QVariant,也就是"a union for the most common Qt data types"。所以data只能是普通的Qt数据类型,不包括正则pythonclass。
不过,数据可以是QtCore.QObject
,所以你的问题很容易解决:
class Foo(QtCore.QObject):
def __init__(self, value,parent=None):
super(Foo,self).__init__(parent)
self.value = value
class MyCombo(QtGui.QWidget):
def __init__(self, *args):
QtGui.QWidget.__init__(self, *args)
combo = QtGui.QComboBox()
combo.addItem(str(1),Foo(1,self) )
data = combo.itemData(0)
print("data",data) # prints the object repr
print(combo.findData(data)) # returns 0 -> found
注意:QVariant
在 C++ 中使用,因为您需要用类型定义每个值(如 int i=0;
)。在 python 中,您不需要这个,因为值可以随时更改类型。所以在 PySide 中,QVariant
没有实现,而是使用常规的 python 类型或 Qt 类型。
也不适合我。
我将 QComboBox 子类化以自己编写 findData
方法:
from PySide import QtGui
class QComboBox(QtGui.QComboBox):
def findData(self, data):
for index in range(self.count()):
if self.itemData(index) == data:
return index
return -1
我将对象作为 UserData 附加到 QStandardItem,该对象被添加到 QComboBox 模型。如果我随后使用 findData() 方法搜索它,我将得不到任何结果。如果我对一个简单的 int 做同样的事情,我会得到一个结果。我想这是 PySide 相关的,但我在源代码中找不到包装器。这是一个(有点)最小的例子:
import sys
from PySide import QtGui
class Foo(object):
def __init__(self, value):
self.value = value
class MyCombo(QtGui.QWidget):
def __init__(self, *args):
QtGui.QWidget.__init__(self, *args)
combo = QtGui.QComboBox()
combo.addItem(str(1), Foo(1))
combo.addItem(str(2), 2)
data = combo.itemData(0)
print(data) # prints the object repr
print(combo.findData(data)) # returns -1 -> not found
data = combo.itemData(1)
print(data) # prints 2
print(combo.findData(data)) # returns 1 -> found
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
w = MyCombo()
w.show()
sys.exit(app.exec_())
为什么对象的 findData() return -1?任何关于可以搜索的内容的提示都将受到赞赏!
QT C++ doc 提供了解释。这是 findData
的定义,强调我的:
int QComboBox::findData(const QVariant & data, int role = Qt::UserRole, Qt::MatchFlags flags = static_cast ( Qt::MatchExactly | Qt::MatchCaseSensitive )) const
组合框中的数据只能是QVariant,也就是"a union for the most common Qt data types"。所以data只能是普通的Qt数据类型,不包括正则pythonclass。
不过,数据可以是QtCore.QObject
,所以你的问题很容易解决:
class Foo(QtCore.QObject):
def __init__(self, value,parent=None):
super(Foo,self).__init__(parent)
self.value = value
class MyCombo(QtGui.QWidget):
def __init__(self, *args):
QtGui.QWidget.__init__(self, *args)
combo = QtGui.QComboBox()
combo.addItem(str(1),Foo(1,self) )
data = combo.itemData(0)
print("data",data) # prints the object repr
print(combo.findData(data)) # returns 0 -> found
注意:QVariant
在 C++ 中使用,因为您需要用类型定义每个值(如 int i=0;
)。在 python 中,您不需要这个,因为值可以随时更改类型。所以在 PySide 中,QVariant
没有实现,而是使用常规的 python 类型或 Qt 类型。
也不适合我。
我将 QComboBox 子类化以自己编写 findData
方法:
from PySide import QtGui
class QComboBox(QtGui.QComboBox):
def findData(self, data):
for index in range(self.count()):
if self.itemData(index) == data:
return index
return -1