PyQT QWizard - 在QComboBox的userData上的registerField而不是文本或索引?

时间:2012-10-29 18:18:26

标签: pyqt wizard qcombobox

我正在创建一个QWizard&想要一个代表文件的组合框。组合框将显示文件名,但我需要整个路径,因此我将路径存储在组合框的userData中。为了访问另一个向导页面中的组合框数据,我使用registerField。组合框没有currentData方法,就像它有currentIndex或currentText一样,所以我创建了自己的组合框,它有一个currentData方法(在我的例子中,我将总是返回一个QString,所以我称之为currentStringData)。当我将这个新函数名称作为“property”参数传递给registerField时,我没有得到任何结果。

在谷歌上搜索,我在QtCentre上找到了别人的问题 - 他们有同样的问题,但它是用C ++编写的,而且我很难从C ++示例转换为python。 http://www.qtcentre.org/threads/13858-QWizard-QComboBox-and-registerField()-issue。我相信我错过了派生类的排放,但我不确定是否是这种情况或如何做。

任何人都知道如何在Python中执行此操作?

我创建了一个非常简单的python脚本来演示我的问题。

#!/usr/bin/env python

from PyQt4 import QtCore,QtGui

class QIComboBox(QtGui.QComboBox):
    def __init__(self,parent=None):
        super(QIComboBox, self).__init__(parent)

    def currentStringData(self):
        return self.itemData(self.currentIndex()).toString()


class VariantWizard(QtGui.QWizard):
    def __init__(self, parent=None):
        super(VariantWizard, self).__init__(parent)

        self.addPage(Page1())
        self.addPage(Page2())

        self.setWindowTitle("QVariant Test")
        self.resize(640,480)

class Page1(QtGui.QWizardPage):
    def __init__(self, parent=None):
        super(Page1, self).__init__(parent)

        self.version_combo = QIComboBox(self)
        self.version_combo.addItem("foo","/path/to/foo")
        self.version_combo.addItem("bar","/path/to/bar")

        self.registerField("version",self.version_combo,"currentStringData")

        layout = QtGui.QVBoxLayout()
        layout.addWidget(self.version_combo)
        self.setLayout(layout)

class Page2(QtGui.QWizardPage):
    def __init__(self, parent=None):
        super(Page2, self).__init__(parent)

        path = self.field("version")
        label1 = QtGui.QLabel("raw path is '%s'" % path)
        label2 = QtGui.QLabel("string path is '%s'" % path.toString())

        layout = QtGui.QVBoxLayout()
        layout.addWidget(label1)
        layout.addWidget(label2)
        self.setLayout(layout)

if __name__ == '__main__':
    import sys
    app = QtGui.QApplication(sys.argv)
    wizard = VariantWizard()
    wizard.show()
    sys.exit(app.exec_())

在这个例子中,我希望第二页上的第一个标签是“raw path is'/ path / to / foo'”或“raw path is'/ path / to / bar'”,具体取决于在Page1上选择了哪个组合框项目。 我希望第二个标签是一个错误,因为currentStringData应该已经返回一个QString。

相反,我得到的是“raw path is '<PyQt5.QtCore.QVariant object....>'”和“string path is ''”。

1 个答案:

答案 0 :(得分:1)

您在这里遗漏了几个重要的细节。首先,如果您不打算通过field()读取小部件现有属性,那么您必须定义自己的属性(在这种情况下为currentItemData)。您可以通过@pyqtProperty decorator执行此操作,如here所述。在您的情况下,新属性应在QIComboBox类中定义。其次,当要显示页面时,您必须调用其(重新实现的)initializePage()方法,该方法将根据其他页面字段初始化页面内容(您可以看到示例here)。

您的代码的工作版本如下:

#!/usr/bin/env python

from PyQt4 import QtCore
from PyQt4 import QtGui
from PyQt4.QtCore import pyqtProperty

class QIComboBox(QtGui.QComboBox):
    def __init__(self,parent=None):
        super(QIComboBox, self).__init__(parent)

    @pyqtProperty(str)
    def currentItemData(self):
        return self.itemData(self.currentIndex()).toString()

class VariantWizard(QtGui.QWizard):
    def __init__(self, parent=None):
        super(VariantWizard, self).__init__(parent)
        self.addPage(Page1(self))
        self.addPage(Page2(self))
        self.setWindowTitle("QVariant Test")
        self.resize(640,480)

class Page1(QtGui.QWizardPage):
    def __init__(self, parent=None):
        super(Page1, self).__init__(parent)
        self.version_combo = QIComboBox(self)
        self.version_combo.addItem("filename1","/path/to/filename1")
        self.version_combo.addItem("filename2","/path/to/filename2")
        layout = QtGui.QVBoxLayout()
        layout.addWidget(self.version_combo)
        self.setLayout(layout)

        self.registerField("version",self.version_combo, "currentItemData")

class Page2(QtGui.QWizardPage):
    def __init__(self, parent=None):
        super(Page2, self).__init__(parent)
        self.label1 = QtGui.QLabel()
        self.label2 = QtGui.QLabel()
        layout = QtGui.QVBoxLayout()
        layout.addWidget(self.label1)
        layout.addWidget(self.label2)
        self.setLayout(layout)

    def initializePage(self):
        path = self.field("version")
        self.label1.setText("raw path is '%s'" % path.toString())
        self.label2.setText("string path is '%s'" % path)

if __name__ == '__main__':
    import sys
    app = QtGui.QApplication(sys.argv)
    wizard = VariantWizard()
    wizard.show()
    sys.exit(app.exec_())