使用 QSqlTableModel 的正则表达式自定义 QAbstractItemDelegate

     2023-02-19     107

关键词:

【中文标题】使用 QSqlTableModel 的正则表达式自定义 QAbstractItemDelegate【英文标题】:Custom QAbstractItemDelegate with regex for QSqlTableModel 【发布时间】: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)

【问题讨论】:

【参考方案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)

【讨论】:

使用正则表达式自动向 PDF 文件添加注释 [关闭]

】使用正则表达式自动向PDF文件添加注释[关闭]【英文标题】:AddcommentstoPDFfilesautomagicallywithregularexpressions[closed]【发布时间】:2011-05-2413:04:41【问题描述】:几年来,我一直在为学术论文评分,我开始看到许多拼写和语法错误的... 查看详情

如何使用正则表达式进行电子邮件控制和自定义域控制?

】如何使用正则表达式进行电子邮件控制和自定义域控制?【英文标题】:HowcanIdobothemailcontrolandcustomdomaincontrolwithregex?【发布时间】:2019-09-0714:37:18【问题描述】:我想检查输入表单域的文本。文本必须是有效的电子邮件,并且... 查看详情

Grafana - 在查询中使用自定义变量作为正则表达式

】Grafana-在查询中使用自定义变量作为正则表达式【英文标题】:Grafana-usecustomvariableasregexinquery【发布时间】:2019-08-1019:16:37【问题描述】:我们有普罗米修斯数据源,我一直在尝试使用具有少量值的自定义变量作为逗号分隔值... 查看详情

自定义正则表达式 [关闭]

】自定义正则表达式[关闭]【英文标题】:CustomRegularExpressions[closed]【发布时间】:2013-03-2419:03:58【问题描述】:如何使用正则表达式来分隔BCT34385Z0000N07518ZBCT34395Z0000N07518Z转换成BCT343格式?我正在使用这个magento将2种类型的序列... 查看详情

一个可以使用多个正则表达式进行多次尝试匹配,并进行替换的excelvba自定义函数(ufd)

以下代码可使用多个正则表达式对目标单元格进行多次匹配尝试,如匹配成功,将停止尝试匹配其他正则表达式,并且使用该正则表达式相对应的替换表达式进行替换,返回替换结果。使用前需要做EarlyBinding。即在VBE编辑器中,... 查看详情

干货|logstash自定义正则表达式etl实战

...ok数据结构化ETL实战上,并专注于在Grok中使用自定义正则表达式。有时Logstash没有我们需要的模式。幸运的是,我们有正则表达式库:Oniguruma。Oniguruma是一个灵活的正则表达式库。它包含多种语言的不同正则表达式实现的特性。G... 查看详情

logstash:使用自定义正则表达式模式(代码片段)

有时LogstashGrok没有我们需要的模式。幸运的是我们有正则表达式库:Oniguruma。在很多时候,如果Logstash所提供的正则表达不能满足我们的需求,我们选用定制自己的表达式。定义Logstash是一种服务器端数据处理管道ÿ... 查看详情

用于匹配单词的 javascript 正则表达式模式,具有自定义单词边界

】用于匹配单词的javascript正则表达式模式,具有自定义单词边界【英文标题】:javascriptregexpatterntomatchwords,withcustomwordboundary【发布时间】:2014-09-2909:04:53【问题描述】:我正在尝试使用javascript中的正则表达式匹配字符串中的单... 查看详情

用于自定义电子邮件和域的 C# 正则表达式

】用于自定义电子邮件和域的C#正则表达式【英文标题】:C#Regexforcustomemailanddomain【发布时间】:2021-11-0920:35:14【问题描述】:我有一个带有使用此模式的输入的剃刀视图:pattern="^[a-zA-Z0-9._+-]+&#64mydomain.com"它用作前端验证非... 查看详情

正则表达式

正则表达式1.简单的介绍正则表达式a) 正则表达式就是描述字符串排列模式的一种自定义语法规则b) 如果可以使用字符串函数处理完成的任务,就不要使用正则表达式c) 有一些复杂性的操作,只能用正则表达式来完成d... 查看详情

向自定义正则表达式添加动态错误消息

】向自定义正则表达式添加动态错误消息【英文标题】:Adddynamicerrormessagetocustomregularexpression【发布时间】:2019-12-0504:04:10【问题描述】:我已经建立了一个自定义的正则表达式类。我还有一个数据库值,它是我不希望在我的Web... 查看详情

简析正则表达式

...了处理基于标签的数据提取与数据填充大量的使用了正则表达式,在这里将我将正则表达式的语法和用法进行简单的描述,然后下篇中将介绍在c#中利用正则表达式的方法与代码实例。什么是正则表达式基本说来,正则表达式是... 查看详情

自定义正则表达式不在客户端验证

】自定义正则表达式不在客户端验证【英文标题】:CustomRegularExpressionnotvalidatingontheclientside【发布时间】:2016-04-2516:27:59【问题描述】:我已经构建了一个自定义属性来在客户端验证正十进制值。问题是当我将正则表达式直接应... 查看详情

jquery.validation自定义正则表达式验证

...目时前台表单验证用了jquery.validation插件。发现在做正则表达式验证时没有参数设置可以使用,需要一个个添加方法,比较麻烦。就做了一个简单的分装,也总结了一些正则表达式。/***@anthorycf*@date1017/11/3**本js是对jquery.validator的... 查看详情

flask自定义转换器,实现路由匹配正则表达式参数(代码片段)

...自定义转换器来实现了,而不能向Django那样直接使用正则表达式1#路由传递的参数默认当做string处理2#这里指定int,尖括号中冒号后面的内容是动态的34@app.route(‘/user/<int:id>‘)5defhello_itcast(id):6r 查看详情

02jmeter正则表达式提取器

...e/details/50724313 在使用Jmeter过程中,会经常使用到正则表达式提取器提取器,虽然并不直接涉及到请求的测试,但是对于数据的传递起着很大的作用,本篇博文就是主要讲解关于正则表达式及其在Jmeter的Sampler中的调用。文中... 查看详情

自定义标签中的正则表达式替换

】自定义标签中的正则表达式替换【英文标题】:Regexreplacementinacustomtag【发布时间】:2020-03-2112:19:08【问题描述】:我有一个可能包含以下一个或多个标签的字符串:<CHOICE[somewords][otherwords]>我需要替换(C#)所有出现的这... 查看详情

js自定义日期格式的正则表达式验证

...ormat=currentFormat//优先替换特殊字符,因为后面替换的正则表达式中包含特殊字符.replace(/s/ig,"\s").replace(/ 查看详情