【发布时间】:2014-05-16 16:16:33
【问题描述】:
我有一个包含几列的树视图。我使用 QDataWidgetMapper 将每一列与侧边栏上的几个小部件之一连接起来。可以通过双击树视图中的单元格或使用侧边栏上的小部件来更改数据。
我的一个专栏包含需要验证的字符串数据。我创建了一个自定义委托,我将它附加到树视图和数据小部件映射器。它有一个 QRegExpValidator,以防止用户在输入时出现无效输入。此外,在 setModelData() 中,一旦用户按下“Enter”,它就会进行不同的验证检查。对于树视图,此委托工作正常。对于映射的QLineEdit,有两个问题:
- 没有调用 QRegExpValidator(可能是因为 createEditor() 没有用于侧边栏小部件);因此用户可以在 QLineEdit 中输入错误的输入。
- 如果数据在 setModelData() 期间检查失败,QLineEdit 中的文本不会切换回原始文本。因此,当用户单击 QLineEdit 以外的其他内容时,错误消息会再次打印出来。
我是不是走错路了?
这是一个简化的例子。为简单起见,我用列表视图替换了树视图:
class TestWidgetMapperValidate(QtGui.QMainWindow):
def __init__(self, parent=None):
super(TestWidgetMapperValidate, self).__init__(parent)
self.centralWidget = QtGui.QWidget()
self.setCentralWidget(self.centralWidget)
self.mainLayout = QtGui.QVBoxLayout(self.centralWidget)
# Set up the list view
self.listView = QtGui.QListView()
self.listModel = QtGui.QStringListModel(['aaa', 'bbb', 'ccc', 'ddd'])
self.listView.setModel(self.listModel)
# Set up the delegate
self.testDelegate = TestDelegate()
self.listView.setItemDelegateForColumn(0, self.testDelegate)
self.lineEdit = QtGui.QLineEdit()
self.mainLayout.addWidget(self.listView)
self.mainLayout.addWidget(self.lineEdit)
# Set up the QDataWidgetMapper
self.mapper = QtGui.QDataWidgetMapper()
self.mapper.setModel(self.listModel)
self.mapper.addMapping(self.lineEdit, 0)
self.mapper.setItemDelegate(self.testDelegate)
self.listView.selectionModel().currentChanged.connect(self.mapper.setCurrentModelIndex)
class TestDelegate(QtGui.QStyledItemDelegate):
def __init__(self, parent=None):
super(TestDelegate, self).__init__(parent)
def createEditor(self, parentWidget, option, qModelIndex):
editor = QtGui.QLineEdit(parentWidget)
nameRegex = QtCore.QRegExp('[a-zA-Z][a-zA-Z0-9_]+')
editor.setValidator(QtGui.QRegExpValidator(nameRegex))
return editor
def setEditorData(self, editor, qModelIndex):
value = qModelIndex.data(QtCore.Qt.DisplayRole)
editor.setText(value)
def setModelData(self, editor, model, qModelIndex):
if not editor.hasAcceptableInput():
return False
oldValue = qModelIndex.data(QtCore.Qt.DisplayRole)
newValue = editor.text()
if oldValue != newValue:
if newValue in model.stringList():
print 'That name already exists: {0}'.format(newValue)
return False
else:
return model.setData(qModelIndex, newValue)
else:
return True
(注意:我使用的是 PySide 和 Python 2.7)
【问题讨论】: