PyQt:在QStyledItemDelegate中使用QTextEdit作为编辑器

时间:2015-06-03 08:46:44

标签: python qt pyqt4

我正在寻找干净方式来在我的QStyledItemDelegate中使用多行文本编辑。通过返回QTextEdit实例

,createEditor实现非常简单
def createEditor(self, parent, option, index):
    return QtGui.QTextEdit("Some text")

但是setModelData期望从QWidget派生的编辑窗口小部件作为参数而不是QTextEdits基础QScrollArea。 Qt文档还tells me(至少在PyQt Doc中)setModelData函数试图从QWidget UserData字段获取数据。但是,如果没有从QWidget派生的编辑窗口小部件,则无法设置数据。目前它会抛出AttributeError,因为它无法在编辑器中找到text()

是否有一些经过验证的方法可以使用非QWidget编辑器?或者我只是缺少一些Widget来做到这一点?

目前,我通过使用QLineEdit的{​​{1}}数据设置QTextEdit并将其传递给toPlainText()来快速解决问题。很哈克!我也可以使用duck typing并在setModelData派生上实现text()方法。但仍然不是一个好方法,不是吗?在C ++中用这种方法做什么?

2 个答案:

答案 0 :(得分:1)

所以我花了一些时间深入研究这个问题。实际上有多种清洁解决方案:

  1. 实施财产 我通过在QTextEdit的子类上实现QProperty来使其正常工作,该子类将text属性作为USER属性添加到对象。这是我的代码:

    class DelegatableTextEdit(QtGui.QTextEdit):
    
        @pyqtProperty(str, user=True)
        def text(self):
    
            return self.toPlainText()
    
        @text.setter
        def text(self, text):
    
            self.setText(text)
    
  2. 使用工厂 似乎有一种方法可以通过使用Delegates setDefaultFactory()方法来解决这个问题,然后使用QItemEditorFactory函数将registerEditor()注册到自定义编辑器创建者。您可以在那里注册QItemEditorCreatorBase类的自定义实现,该实现具有覆盖createWidget方法(如果需要还需要valuePropertyName函数)。但我还没有尝试过这个

  3. 我决定采用第一个只需要自定义QTextEdit和覆盖createEditor()功能的解决方案。两者都应该在C ++中工作

答案 1 :(得分:1)

项目委托的最低要求非常简单。您需要做的就是重新实现createEditorsetEditorDatasetModelData

class Delegate(QStyledItemDelegate):

    def createEditor(self, parent, options, index):
        return QtGui.QTextEdit(parent)

    def setEditorData(self, editor, index):
        editor.setText(index.data())

    def setModelData(self, editor, model, index):
        model.setData(index, editor.toPlainText())

使用此解决方案,可以通过同一代理轻松支持多种不同类型的编辑器。例如,isinstance检查可用于决定使用哪种类型的编辑器:

    def setModelData(self, editor, model, index):
        if isinstance(editor, QtGui.QTextEdit):
            model.setData(index, editor.toPlainText())
        elif isinstance(editor, QtGui.QComboBox):
            model.setData(index, editor.currentText())
        else:
            super(Delegate, self).setModelData(editor, model, index)

有关C ++示例,请参阅A Simple Delegate中的Model/View Overview部分。