Python QDataWidgetMapper和验证
我有一个有几列的树状视图。我使用QDataWidgetMapper将每个列与侧栏上的几个小部件中的一个连接起来。可以通过双击树状视图中的单元格或使用侧边栏上的小部件来更改数据 我的一列包含需要验证的字符串数据。我创建了一个自定义委托,并将其附加到树视图和数据小部件映射器。它有一个QRegExpValidator,用于防止用户键入时输入无效。此外,在setModelData()中,一旦用户按下“Enter”键,它将进行不同的验证检查。对于树状视图,此委托工作正常。对于映射的QLineEdit,存在两个问题:Python QDataWidgetMapper和验证,python,qt,pyside,Python,Qt,Pyside,我有一个有几列的树状视图。我使用QDataWidgetMapper将每个列与侧栏上的几个小部件中的一个连接起来。可以通过双击树状视图中的单元格或使用侧边栏上的小部件来更改数据 我的一列包含需要验证的字符串数据。我创建了一个自定义委托,并将其附加到树视图和数据小部件映射器。它有一个QRegExpValidator,用于防止用户键入时输入无效。此外,在setModelData()中,一旦用户按下“Enter”键,它将进行不同的验证检查。对于树状视图,此委托工作正常。对于映射的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)以下是我的想法。我不知道这是否是最好的解决方案,但它对我的情况有效
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():
# The new value is not valid. Set the data back to the original value.
self.setEditorData(editor, qModelIndex)
print 'That name already exists: {0}'.format(newValue)
return False
else:
return model.setData(qModelIndex, newValue)
else:
return True
QDataWidgetMapper
用于将模型数据映射到现有小部件。因此,正如您所提到的,从未调用委托方法createEditor
。说明了另一种方法:QDataWidgetMapper
与视图一起使用,而不是使用委托方法createEditor
。另一种方法是为侧边栏创建视图,向其注册代理(以便视图调用createEditor
),并共享tableView
的选择机制。看setModelData
返回false的事件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():
# The new value is not valid. Set the data back to the original value.
self.setEditorData(editor, qModelIndex)
print 'That name already exists: {0}'.format(newValue)
return False
else:
return model.setData(qModelIndex, newValue)
else:
return True