我有QLineEdit
QRegularExpressionValidator
,其中允许的输入为:
^(?<sign>[<>=]|>=|<=)(?<value>\d+\.?\d*)(?<unit>[mc]{0,1}m[²2]\/s|St|cSt)$
例如:
"<15m²/s" // good
">=3.14cSt" // good
"27mm2/s" // bad
我根据此正则表达式搜索填充QCompleter
的方法
因此,如果光标在空QLineEdit
上,则完成者建议:
>
,<
,=
,>=
或<=
。
在签名之后,建议不做任何事情,在最后一个号码之后,建议:
mm²/s
,cm²/s
,m²/s
,St
或cSt
我需要通过阅读正则表达式的允许QStringList
和sign
部分来创建unit
,并将此QStringList
插入QCompleter
,因为它基于QAbstractItemModel
。
答案 0 :(得分:0)
我通过继承QLineEdit
找到了一种解决方法,但它不是最好的解决方案。如果有人有更好的,我会接受
lineeditregexgroup.h
:
#ifndef LINEEDITREGEXGROUP_H
#define LINEEDITREGEXGROUP_H
#include <QLineEdit>
#include <QMap>
class QCompleter;
class QStringListModel;
class QRegularExpression;
class QRegularExpressionValidator;
class LineEditRegexGroup : public QLineEdit
{
Q_OBJECT
public:
LineEditRegexGroup(const QString pattern, QWidget *parent = Q_NULLPTR);
~LineEditRegexGroup();
static QMap<QString, QStringList> mapCompleter;
public slots:
void checkValidity(const QString &text);
protected:
virtual void mouseReleaseEvent(QMouseEvent *e);
private:
QString curGroup;
QCompleter *completer;
QStringListModel *listCompleter;
QRegularExpression *regex;
QRegularExpressionValidator *validator;
};
#endif // LINEEDITREGEXGROUP_H
lineeditregexgroup.cpp
:
#include "lineeditregexgroup.h"
#include <QCompleter>
#include <QStringListModel>
#include <QRegularExpression>
#include <QRegularExpressionValidator>
#include <QAbstractItemView>
QMap<QString, QStringList> LineEditRegexGroup::mapCompleter = {
{ "sign", QStringList() << "<" << ">" << "=" << "<=" << ">=" },
{ "unit", QStringList() << "mm²/s" << "cm²/s" << "m²/s" << "St" << "cSt" }
};
LineEditRegexGroup::LineEditRegexGroup(const QString pattern, QWidget *parent)
: QLineEdit(parent)
{
completer = new QCompleter(this);
listCompleter = new QStringListModel(completer);
regex = new QRegularExpression(pattern, QRegularExpression::NoPatternOption);
validator = new QRegularExpressionValidator(*regex, this);
completer->setModel(listCompleter);
completer->setCompletionMode(QCompleter::UnfilteredPopupCompletion);
setCompleter(completer);
setValidator(validator);
curGroup = regex->namedCaptureGroups().at(1);
connect(this, SIGNAL(textEdited(QString)), this, SLOT(checkValidity(QString)));
}
LineEditRegexGroup::~LineEditRegexGroup()
{
// dtor ...
}
void LineEditRegexGroup::checkValidity(const QString &text)
{
bool valid = true;
int nbCapture = 0;
QRegularExpressionMatch match = regex->match(text);
for (int i=1; i<=regex->captureCount() && valid; i++){
/* +1 to check only groups, not the global string */
valid &= !match.captured(i).isEmpty();
if (valid)
nbCapture++;
curGroup = regex->namedCaptureGroups().at(i);
if (curGroup == "value")
curGroup = regex->namedCaptureGroups().at(i-1);
}
if (nbCapture < regex->captureCount()){
QStringList new_model = mapCompleter.value(curGroup);
if (curGroup == regex->namedCaptureGroups().at(regex->captureCount())){
new_model.replaceInStrings(QRegularExpression("^(.*)$"), text+"\\1");
}
listCompleter->setStringList(new_model);
completer->complete();
}
}
void LineEditRegexGroup::mouseReleaseEvent(QMouseEvent *e)
{
QLineEdit::mouseReleaseEvent(e);
if (text().isEmpty())
checkValidity("");
}
并称之为:
new LineEditRegexGroup(
"^(?:(?<sign>[<>=]|>=|<=|)"
"(?:(?<value>\\d+\\.?\\d*)"
"(?:(?<unit>[mc]{0,1}m[²2]\\/s|St|cSt))?)?)?$",
parent
);