用于十六进制输入的 QValidator
我有一个 Qt 小部件,它应该只接受十六进制字符串作为输入。将输入字符限制为 [0-9A-Fa-f]
非常简单,但我希望它在“字节”之间显示分隔符,例如,如果分隔符是空格,并且用户输入 0011223344
我希望行编辑显示 00 11 22 33 44
现在,如果用户按退格键 3 次,那么我希望它显示00 11 22 3
。
我几乎得到了我想要的,到目前为止,只有一个微妙的错误涉及使用删除键删除分隔符。有谁有更好的方法来实现这个验证器?到目前为止,这是我的代码:
class HexStringValidator : public QValidator {
public:
HexStringValidator(QObject * parent) : QValidator(parent) {}
public:
virtual void fixup(QString &input) const {
QString temp;
int index = 0;
// every 2 digits insert a space if they didn't explicitly type one
Q_FOREACH(QChar ch, input) {
if(std::isxdigit(ch.toAscii())) {
if(index != 0 && (index & 1) == 0) {
temp += ' ';
}
temp += ch.toUpper();
++index;
}
}
input = temp;
}
virtual State validate(QString &input, int &pos) const {
if(!input.isEmpty()) {
// TODO: can we detect if the char which was JUST deleted
// (if any was deleted) was a space? and special case this?
// as to not have the bug in this case?
const int char_pos = pos - input.left(pos).count(' ');
int chars = 0;
fixup(input);
pos = 0;
while(chars != char_pos) {
if(input[pos] != ' ') {
++chars;
}
++pos;
}
// favor the right side of a space
if(input[pos] == ' ') {
++pos;
}
}
return QValidator::Acceptable;
}
};
目前此代码功能足够,但我希望它能够 100% 按预期工作。显然,理想的是将十六进制字符串的显示与 QLineEdit 内部缓冲区中存储的实际字符分开,但我不知道从哪里开始,我想这是一个非-微不足道的事业。
本质上,我想要一个符合此正则表达式的验证器: "[0-9A-Fa-f]( [0-9A-Fa-f])*"
但我不'不希望用户必须键入空格作为分隔符。同样,当编辑他们输入的内容时,应该隐式管理空格。
I have a Qt widget which should only accept a hex string as input. It is very simple to restrict the input characters to [0-9A-Fa-f]
, but I would like to have it display with a delimiter between "bytes" so for example if the delimiter is a space, and the user types 0011223344
I would like the line edit to display 00 11 22 33 44
Now if the user presses the backspace key 3 times, then I want it to display 00 11 22 3
.
I almost have what i want, so far there is only one subtle bug involving using the delete key to remove a delimiter. Does anyone have a better way to implement this validator? Here's my code so far:
class HexStringValidator : public QValidator {
public:
HexStringValidator(QObject * parent) : QValidator(parent) {}
public:
virtual void fixup(QString &input) const {
QString temp;
int index = 0;
// every 2 digits insert a space if they didn't explicitly type one
Q_FOREACH(QChar ch, input) {
if(std::isxdigit(ch.toAscii())) {
if(index != 0 && (index & 1) == 0) {
temp += ' ';
}
temp += ch.toUpper();
++index;
}
}
input = temp;
}
virtual State validate(QString &input, int &pos) const {
if(!input.isEmpty()) {
// TODO: can we detect if the char which was JUST deleted
// (if any was deleted) was a space? and special case this?
// as to not have the bug in this case?
const int char_pos = pos - input.left(pos).count(' ');
int chars = 0;
fixup(input);
pos = 0;
while(chars != char_pos) {
if(input[pos] != ' ') {
++chars;
}
++pos;
}
// favor the right side of a space
if(input[pos] == ' ') {
++pos;
}
}
return QValidator::Acceptable;
}
};
For now this code is functional enough, but I'd love to have it work 100% as expected. Obviously the ideal would be the just separate the display of the hex string from the actual characters stored in the QLineEdit
's internal buffer but I have no idea where to start with that and I imagine is a non-trivial undertaking.
In essence, I would like to have a Validator which conforms to this regex: "[0-9A-Fa-f]( [0-9A-Fa-f])*"
but I don't want the user to ever have to type a space as delimiter. Likewise, when editing what they types, the spaces should be managed implicitly.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
Evan,试试这个:
inputMask 负责间距,“h”代表可选的十六进制字符(“H”代表非可选)。唯一的缺点:您必须提前知道最大输入长度。我上面的例子只允许四个字节。
此致,
罗宾
Evan, try this:
The inputMask takes care of the spacing, and the "h" stands for a optional hex character (the "H" for a non-optional). Only drawback: You have to know the maximum input length in advance. My example above allows only for four bytes.
Best regards,
Robin
我将提出三种方法:
当
QLineEdit
光标左侧的字符是空格时,您可以重新实现QLineEdit::keyPressEvent()
以不同方式处理反斜杠。使用这种方法,您还可以在键入新字符时自动添加空格。另一种方法是创建一个新槽,连接到 QLineEdit::textChanged() 信号。当文本更改时会发出此信号。在此槽中,您可以根据需要处理空间的创建和删除。
最后,您可以创建一个派生自
QLineEdit
的新类,该类重新实现QLineEdit::paintEvent()
方法。通过这种方法,您可以显示未存储在 QLineEdit 缓冲区中的十六进制字之间的空格。I will propose three approaches :
You can reimplement the
QLineEdit::keyPressEvent()
to handle backslash differently when the character just left to theQLineEdit
's cursor is a space. Using this approach, you can also automatically add spaces when a new character is typed.Another approach is to create a new slot, connected to the
QLineEdit::textChanged()
signal. This signal is emitted when the text is changed. In this slot, you can handle the creation and deletion of spaces accordingly to your needs.Finally, you can create a new class, derived from
QLineEdit
that reimplements theQLineEdit::paintEvent()
method. With this approach, you can display space between your hex words that are not stored in theQLineEdit
buffer.Robin 的解决方案很好并且有效。但我认为你可以做到最好!
使用它作为输入掩码:
在 ui 中,R-单击 lineEdit ->转到老虎机... ->文本已更改。
在槽函数中编写以下代码:
现在您有一个带有十六进制输入的 lineEdit,大写,带有破折号分隔符。
祝你代码愉快:)
Robin's solution is good and works. But I think you can do best!
Use this for input mask:
and in the ui, R-click on lineEdit -> Go to Slots... -> textChanged.
In the slot function write this code:
Now you have a lineEdit with Hex input, in uppercase, with dash-separators.
have a good code time :)
我有同样的要求,用空格分隔 2 个十六进制半字节,谷歌搜索让我来到这里。正如Lohrun所建议的,我最初尝试了基于paintEvent的方法,并且它按键盘输入的预期工作。但是,我无法正确处理鼠标点击。接下来,我尝试了他的第一个建议,即重新实现
keyPressEvent
以及mousePressEvent
,我可以使用键盘和鼠标来实现要求。我的实现
QHexTextEdit.cpp
QHexTextEdit.h
I had the same requirement of separating 2 hex nibbles with a space and a Google search landed me here. As suggested by Lohrun, I attempted paintEvent based approach initially and it worked as expected for keyboard inputs. However, I could not handle the mouse clicks properly. Next, I tried his first suggestion of re-implementing the
keyPressEvent
along withmousePressEvent
and I could achieve the requirement with both keyboard and mouse.My implementation
QHexTextEdit.cpp
QHexTextEdit.h