为什么QComboBox.findData()不接受对象作为输入?

时间:2015-12-01 15:54:53

标签: pyside python-3.4 qcombobox

我将一个对象作为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()为对象返回-1?任何可以搜索的提示都值得赞赏!

2 个答案:

答案 0 :(得分:2)

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,它是最常见的Qt数据类型的联合"。因此,数据只能是常见的Qt数据类型,不包括常规的python类。

但是,数据可以是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类型。

答案 1 :(得分:1)

对我也不起作用。

我将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