【问题标题】:Custom QAbstractItemDelegate with regex for QSqlTableModel使用 QSqlTableModel 的正则表达式自定义 QAbstractItemDelegate
【发布时间】:2015-03-11 20:00:52
【问题描述】:

我正在尝试创建一个自定义委托,以便我可以使用 Regex 来验证正在输入到表中的数据,但由于某种原因,我的代码不断抛出错误,有没有一个好的结构化示例?

这是我目前遇到的两个错误,当我使用 QLineEdit.setText 修复 AttributeError: 'QLineEdit' object has no attribute 'set' 时,我的正则表达式不起作用,它允许添加任何值。

Traceback (most recent call last):
  File "F:\Computing\Program V3\stockGui.py", line 23, in setEditorData
    editor.set(text)
AttributeError: 'QLineEdit' object has no attribute 'set'
Traceback (most recent call last):
  File "F:\Computing\Program V3\stockGui.py", line 29, in setModelData
    model.setData(index, QVariant(editor.text()))
NameError: name 'QVariant' is not defined






class ProductDelegate(QtSql.QSqlRelationalDelegate):
    def __init__(self):
        super().__init__()      

    def createEditor(self, parent, option, index):
        if index.column() == 1:
            editor = QtGui.QLineEdit(parent)
            regex = QtCore.QRegExp(r"(?:[A-Z|\s]+)")
            validator = QtGui.QRegExpValidator(regex,parent)
            editor.setValidator(validator)
            return editor
        else:
            return QtSql.QSqlRelationalDelegate.createEditor(self, parent, option, index)

    def setEditorData(self, editor, index):
        if index.column() == 1:
            text = index.model().data(index, QtCore.Qt.DisplayRole)
            editor.set(text)
        else:
            QtSql.QSqlRelationalDelegate.setEditorData(self, editor,index)

    def setModelData(self, editor, model, index):
        if index.column() == 1:
            model.setData(index, QVariant(editor.text()))
        else:
            QtSql.QSqlRelationalDelegate.setModelData(self, editor, model, index)

【问题讨论】:

    标签: python regex pyqt4 qsqltablemodel


    【解决方案1】:

    正如您所发现的,setText 不进行任何验证。所以,改为使用insert

        text = index.model().data(index, QtCore.Qt.DisplayRole)
        editor.clear()
        editor.insert(text)
    

    另一个错误是因为你没有导入QVariant,所以你不能使用它。最简单的解决方法是完全省略它(PyQt 会自动将参数转换为 QVariant 在适当的地方):

        model.setData(index, editor.text())
    

    (注意:如果您使用的是 Python 3,则默认情况下,QVariant 始终会自动与等价的 Python 类型相互转换)。

    【讨论】:

    • 谢谢!这行得通,但是因为我删除了 QVariant,它不会以一种或另一种方式影响输入吗?我不确定 QVariant 的用途吗?
    • @Inthuson。有关QVariant 的更多详细信息,请参阅this other answer of mine
    • 谢谢!这真的很有帮助:)
    【解决方案2】:

    上述解决方案对我不起作用。

    这个解决方案对我有用:http://nullege.com/codes/show/src@p@y@PyQt4-HEAD@examples@tools@settingseditor@settingseditor.py/626/PyQt4.QtGui.QRegExpValidator

        # This ensure that validation passes.
        text = editor.text()
        validator = editor.validator()
        if validator is not None:
            state, text = validator.validate(text, 0)
            if state != QtGui.QValidator.Acceptable:
                return
    
    class Delegate(QtSql.QSqlRelationalDelegate):
    """
    Delegate class handles the delegate. This allows for custom editing within
    the GUI. QtSql.QSqlRelationalDelegate is being subclassed to support custom editing.
    
    Methods that are being overridden are:
        createEditor
        setEditorData
        setModelData
    """
    
    
    def __init__(self, parent = None):
        """Class constructor."""
    
        super(Delegate, self).__init__(parent)
    
    
    def createEditor(self, parent, option, index):
        """
        This creates the editors in the delegate, which is reimplemented from
        QAbstractItemDelegate::createEditor(). It returns the widget used to edit
        the item specified by index for editing. The parent widget and style option
        are used to control how the editor widget appears.
    
        """
    
        column = index.column()
        if column == 1:
            editor = QtGui.QLineEdit(parent)
            regex = QtCore.QRegExp(r"[a-zA-Z][a-zA-Z0-9_]{3,60}")
            validator = QtGui.QRegExpValidator(regex,parent)
            editor.setValidator(validator)
            return editor
    
        # Else return the base editor. This will handle all other columns.
        else:
            return super(AppDelegate, self).createEditor(parent, option, index)
    
    
    def setEditorData(self, editor, index):
        """
         Once the editor has been created and given to the view, the view calls
         setEditorData(). This gives the delegate the opportunity to populate the
         editor with the current data, ready for the user to edit.
    
        Sets the contents of the given editor to the data for the item
        at the given index.
    
        Note that the index contains information about the model being used.
    
        The base implementation does nothing.
        If you want custom editing you will need to reimplement this function.
        """
    
        column = index.column()
    
        # Get the data value from the model.
        text = index.model().data(index, QtCore.Qt.DisplayRole).toString()
    
        # Set the editors text to be the text from the model.
        if column == 1:
            editor.setText(text)
    
    
        # Else return the base setEditorData method.
        # This is not strictly needed because in flags the ID column is set
        # to be selectable only so it should never call setEditorData.
        else:
            return super(AppDelegate, self).setEditorData(self, editor, index)
    
    
    def setModelData(self, editor, model, index):
        """
        Sets the data for the item at the given index in the model
        to the contents of the given editor. The base implementation does
        nothing.
        If you want custom editing you will need to reimplement this method.
    
        If the user confirms their edit the editor's data must be written
        back to the model. The model will then notify the views that the item
        has changed, and those views that are showing the item
        will request fresh data to display.
    
        In each case we simply retrieve the value from the appropriate editor,
        and call setData (), passing the values as QVariants.
        """
    
        column = index.column()
    
        # Test if the editor has been modified.
        if not editor.isModified():
            return
    
        # This ensure that validation passes.
        text = editor.text()
        validator = editor.validator()
        if validator is not None:
            state, text = validator.validate(text, 0)
            if state != QtGui.QValidator.Acceptable:
                return
    
        if column == 1:
            # Call model.setData and set the data to the text in the QLineEdit.
            # After the user confirms the edit then set the model data to the
            # new user input.
            model.setData(index, QtCore.QVariant(editor.text()))
    
        # else return the base setModelData method.
        else:
            super(AppDelegate, self).setModelData(self, editor, model, index)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-12-29
      • 2016-07-22
      • 1970-01-01
      • 2015-02-27
      • 2013-03-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多