C++ 如何在 Qt 中一次将输入掩码和 QValidator 设置为 QLineEdit?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23166283/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to set Input Mask and QValidator to a QLineEdit at a time in Qt?
提问by QtUser
I want a line edit which accepts an ip address. If I give input mask as:
我想要一个接受 ip 地址的行编辑。如果我将输入掩码设为:
ui->lineEdit->setInputMask("000.000.000.000");
It is accepting values greater than 255. If I give a validator then we have to give a dot(.) after every three digits. What would the best way to handle it?
它接受大于 255 的值。如果我给出一个验证器,那么我们必须在每三位数字后给出一个点(.)。处理它的最佳方法是什么?
回答by lpapp
It is accepting value greater than 255.
它接受大于 255 的值。
Absolutely, because '0' means this:
当然,因为“0”表示此:
ASCII digit permitted but not required.
As you can see, this is not your cup of tea. There are at least the following ways to circumvent it:
正如你所看到的,这不是你的一杯茶。至少有以下方法可以规避:
Write a custom validator
Use regex
Split the input into four entries and validate each entry on its own while still having visual delimiters between the entries.
编写自定义验证器
使用正则表达式
将输入分成四个条目并单独验证每个条目,同时在条目之间仍然有视觉分隔符。
The regex solution would be probably the quick, but also ugliest IMHO:
正则表达式解决方案可能是快速但也是最丑陋的恕我直言:
QString ipRange = "(?:[0-1]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])";
// You may want to use QRegularExpression for new code with Qt 5 (not mandatory).
QRegExp ipRegex ("^" + ipRange
+ "\." + ipRange
+ "\." + ipRange
+ "\." + ipRange + "$");
QRegExpValidator *ipValidator = new QRegExpValidator(ipRegex, this);
lineEdit->setValidator(ipValidator);
Disclaimer: this will only validate IP4 addresses properly, so it will not work for IP6 should you need that in the future.
免责声明:这只会正确验证 IP4 地址,因此如果您将来需要它,它将不适用于 IP6。
回答by AGo
Hi I had almost the same problem. Solutions with inputmask or regExp were unsatisfactory. I decided to make my own bicycle.
嗨,我遇到了几乎同样的问题。使用 inputmask 或 regExp 的解决方案并不令人满意。我决定自己制作自行车。
Header:
标题:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QLineEdit>
#include <QFrame>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
};
//=============================================================================
class CustomIpEditor : public QFrame
{
Q_OBJECT
public:
explicit CustomIpEditor(QWidget *parent = 0);
virtual ~CustomIpEditor() {}
};
//=============================================================================
class CustomLineEdit : public QLineEdit
{
Q_OBJECT
public:
explicit CustomLineEdit(const QString & contents = "", QWidget *parent = 0);
virtual ~CustomLineEdit() {}
signals:
void jumpForward();
void jumpBackward();
public slots:
void jumpIn();
protected:
virtual void focusInEvent(QFocusEvent *event);
virtual void keyPressEvent(QKeyEvent * event);
virtual void mouseReleaseEvent(QMouseEvent *event);
private:
bool selectOnMouseRelease;
};
#endif // MAINWINDOW_H
Source:
来源:
#include <QVBoxLayout>
#include <QKeyEvent>
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
centralWidget()->setLayout(new QVBoxLayout);
CustomIpEditor *myed = new CustomIpEditor;
centralWidget()->layout()->addWidget(myed);
}
MainWindow::~MainWindow()
{
delete ui;
}
//=============================================================================
CustomLineEdit::CustomLineEdit(const QString & contents, QWidget *parent) :
QLineEdit(contents, parent), selectOnMouseRelease(false)
{
QIntValidator *valid = new QIntValidator(0, 255, this);
setValidator(valid);
}
void CustomLineEdit::jumpIn()
{
setFocus();
selectOnMouseRelease = false;
selectAll();
}
void CustomLineEdit::focusInEvent(QFocusEvent *event)
{
QLineEdit::focusInEvent(event);
selectOnMouseRelease = true;
}
void CustomLineEdit::keyPressEvent(QKeyEvent * event)
{
int key = event->key();
int cursorPos = cursorPosition();
// Jump forward by Space
if (key == Qt::Key_Space) {
emit jumpForward();
event->accept();
return;
}
// Jump Backward only from 0 cursor position
if (cursorPos == 0) {
if ((key == Qt::Key_Left) || (key == Qt::Key_Backspace)) {
emit jumpBackward();
event->accept();
return;
}
}
// Jump forward from last postion by right arrow
if (cursorPos == text().count()) {
if (key == Qt::Key_Right) {
emit jumpForward();
event->accept();
return;
}
}
// After key is placed cursor has new position
QLineEdit::keyPressEvent(event);
int freshCurPos = cursorPosition();
if ((freshCurPos == 3) && (key != Qt::Key_Right))
emit jumpForward();
}
void CustomLineEdit::mouseReleaseEvent(QMouseEvent *event)
{
if(!selectOnMouseRelease)
return;
selectOnMouseRelease = false;
selectAll();
QLineEdit::mouseReleaseEvent(event);
}
//=============================================================================
void makeCommonStyle(QLineEdit* line) {
line->setContentsMargins(0, 0, 0, 0);
line->setAlignment(Qt::AlignCenter);
line->setStyleSheet("QLineEdit { border: 0px none; }");
line->setFrame(false);
line->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
}
QLineEdit* makeIpSpliter() {
QLineEdit *spliter = new QLineEdit(".");
makeCommonStyle(spliter);
spliter->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
spliter->setMaximumWidth(10);
spliter->setReadOnly(true);
spliter->setFocusPolicy(Qt::NoFocus);
return spliter;
}
CustomIpEditor::CustomIpEditor(QWidget *parent) :
QFrame(parent)
{
setContentsMargins(0, 0, 0, 0);
setStyleSheet("QFrame { background-color: white; border: 1px solid white; border-radius: 15px; }");
QList <CustomLineEdit *> lines;
QList <CustomLineEdit *>::iterator linesIterator;
lines.append(new CustomLineEdit);
lines.append(new CustomLineEdit);
lines.append(new CustomLineEdit);
lines.append(new CustomLineEdit);
QHBoxLayout *mainLayout = new QHBoxLayout;
mainLayout->setSpacing(0);
setLayout(mainLayout);
for (linesIterator = lines.begin(); linesIterator != lines.end(); ++linesIterator) {
makeCommonStyle(*linesIterator);
mainLayout->addWidget(*linesIterator);
if (*linesIterator != lines.last()) {
connect(*linesIterator, &CustomLineEdit::jumpForward,
*(linesIterator+1), &CustomLineEdit::jumpIn);
mainLayout->addWidget(makeIpSpliter());
}
if (*linesIterator != lines.first()) {
connect(*linesIterator, &CustomLineEdit::jumpBackward,
*(linesIterator-1), &CustomLineEdit::jumpIn);
}
}
}
回答by Arun Kumar K S
The easier method is try inputmask option
更简单的方法是尝试 inputmask 选项
ui->lineEdit_IP->setInputMask( "000.000.000.000" );
and in your validation code use the following simple condition
并在您的验证代码中使用以下简单条件
QHostAddress myIP;
if( myIP.setAddress( ui->lineEdit_IP->text()) )
qDebug()<<"Valid IP Address";
else
qDebug()<<"Invalid IP address";
回答by Gesalat
For those who wonder about the following hint in the QT doku:
对于那些想知道 QT doku 中的以下提示的人:
To get range control (e.g., for an IP address) use masks together with validators.
要获得范围控制(例如,对于 IP 地址),请使用掩码和验证器。
In this case the validator needs to take care of blanks. My solution, adapted from lpapp's answerand this Qt forum post, therefore reads:
在这种情况下,验证器需要处理空白。我的解决方案改编自lpapp 的回答和Qt 论坛帖子,因此内容如下:
QString ipRange = "(([ 0]+)|([ 0]*[0-9] *)|([0-9][0-9] )|([ 0][0-9][0-9])|(1[0-9][0-9])|([2][0-4][0-9])|(25[0-5]))";
// You may want to use QRegularExpression for new code with Qt 5 (not mandatory).
QRegExp ipRegex ("^" + ipRange
+ "\." + ipRange
+ "\." + ipRange
+ "\." + ipRange + "$");
QRegExpValidator *ipValidator = new QRegExpValidator(ipRegex, this);
lineEdit->setValidator(ipValidator);
lineEdit->setInputMask("000.000.000.000");
// Avoid having to move cursor before typing
linEdit->setCursorPosition(0);
I am a beginner at using regular expressions, so feel free to recommend improvements.
我是使用正则表达式的初学者,所以请随时提出改进建议。
回答by ElvisIsAlive
In accordance to Arun Kumar K S's answer:
根据 Arun Kumar KS 的回答:
If myIP.setAddress()
was successfull, you can write the ip back to the line edit as a formatted string:
如果myIP.setAddress()
成功,您可以将 ip 作为格式化字符串写回行编辑:
ui->lineEdit->setText(myIP->toString());
Consequently, you don't neccessarily need to set a mask (nor a validator or regex).
因此,您不需要设置掩码(也不需要验证器或正则表达式)。
NotesetAddress() writes/overwrites your myIP also if it fails to read the ip. Thus, calling toString() in this case results in an empty string.
请注意,如果setAddress() 无法读取 IP,它也会写入/覆盖您的 myIP。因此,在这种情况下调用 toString() 会导致空字符串。