我正在寻找干净方式来在我的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 ++中用这种方法做什么?
答案 0 :(得分: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)
使用工厂
似乎有一种方法可以通过使用Delegates setDefaultFactory()
方法来解决这个问题,然后使用QItemEditorFactory
函数将registerEditor()
注册到自定义编辑器创建者。您可以在那里注册QItemEditorCreatorBase
类的自定义实现,该实现具有覆盖createWidget
方法(如果需要还需要valuePropertyName
函数)。但我还没有尝试过这个
我决定采用第一个只需要自定义QTextEdit
和覆盖createEditor()
功能的解决方案。两者都应该在C ++中工作
答案 1 :(得分:1)
项目委托的最低要求非常简单。您需要做的就是重新实现createEditor
,setEditorData
和setModelData
:
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部分。