Change color of a section of a QLineEdit
-
I am in need of displaying to the user which part of the
QLineEditis wrong, to do that i would like to change the color of those parts in red, right now i change the entireQLineEditin red but i would like to be more precise in the display.What would be the approach if even possible ?
P.S. i can't use
QTextEditbecause i am actually working with aQKeySequenceEdit, so i am stuck with its internalQLineEdit. -
Hi
We cannot replace the internal QLineEdit with our own custom LineEdit , so extra painting is not easy.
What about just placing a QLabel under it and write there which part is wrong ? -
Hi
We cannot replace the internal QLineEdit with our own custom LineEdit , so extra painting is not easy.
What about just placing a QLabel under it and write there which part is wrong ?@mrjj The thing is i have a lot of
QKeySequenceEditon top of each others already, they represent all the keybinds my application have, also eachQKeySequenceEditcan have more than one "error", so it can add up pretty fast to a lot of labels which will extend the interface quite a lot.Right now i just put the text in red and add a tooltip but it is not optimal, i don't like the feel of it, tooltip takes too much time to appear, disappears on its own even without any delay.
I guess i would need to create my own tooltip or something.
-
@mrjj The thing is i have a lot of
QKeySequenceEditon top of each others already, they represent all the keybinds my application have, also eachQKeySequenceEditcan have more than one "error", so it can add up pretty fast to a lot of labels which will extend the interface quite a lot.Right now i just put the text in red and add a tooltip but it is not optimal, i don't like the feel of it, tooltip takes too much time to appear, disappears on its own even without any delay.
I guess i would need to create my own tooltip or something.
@reonZ
well it is possible to adjust tooltip timeout time but
http://doc.qt.io/qt-5/qtooltip.html#showText-2
but im not sure it works that much better anyway.Lets pretend we could paint on the LineEdit.
How would we know where the faulty part is ? -
@reonZ
well it is possible to adjust tooltip timeout time but
http://doc.qt.io/qt-5/qtooltip.html#showText-2
but im not sure it works that much better anyway.Lets pretend we could paint on the LineEdit.
How would we know where the faulty part is ?@mrjj Regular expression can capture the faulty parts, with that we can find at which index it starts and the length.
Right now i am doing that
void SettingsWindowKeybinds::validateKeySequenceEdits() { static const QMap<QString, QString> conflictingKeybindList = { { "Ctrl\\+(Alt\\+|Shift\\+){0,2}C", "Ctrl+C" }, { "Ctrl\\+(Alt\\+|Shift\\+){0,2}F", "Ctrl+F" }, { "Esc", "Esc" }, { "F1($|,)", "F1" }, { "F12", "F12" } }; QList<QKeySequenceEdit *> keySequenceEditList = findChildren<QKeySequenceEdit *>(); for (QKeySequenceEdit *keySequenceEdit : keySequenceEditList) { QKeySequence keySequence = keySequenceEdit->keySequence(); if (!keySequence.count()) continue; QStringList tooltip; for (QKeySequenceEdit *otherKeySequenceEdit : keySequenceEditList) { if (keySequenceEdit == otherKeySequenceEdit) continue; QKeySequence otherKeySequence = otherKeySequenceEdit->keySequence(); if (keySequence == otherKeySequence) { tooltip.append(QString("- Multiple '%1' keybinds found").arg(keySequence.toString())); } else if (otherKeySequence.count() == 1 && keySequence[0] == otherKeySequence[0]) { tooltip.append(QString("- '%1' exist, can not start with that combination") .arg(otherKeySequence.toString())); } for (const QString &conflinctingKeybind : conflictingKeybindList.keys()) { QRegularExpression regEx(conflinctingKeybind); QRegularExpressionMatch match = regEx.match(keySequence.toString()); if (match.hasMatch()) tooltip.append(QString("- '%1' conflict with known keybind") .arg(conflictingKeybindList.value(conflinctingKeybind))); } } if (!tooltip.count()) keySequenceEdit->setStyleSheet("QLineEdit { color: black; }"); else keySequenceEdit->setStyleSheet("QLineEdit { color: red; }"); keySequenceEdit->setToolTip(tooltip.join("\n")); } } -
@mrjj Regular expression can capture the faulty parts, with that we can find at which index it starts and the length.
Right now i am doing that
void SettingsWindowKeybinds::validateKeySequenceEdits() { static const QMap<QString, QString> conflictingKeybindList = { { "Ctrl\\+(Alt\\+|Shift\\+){0,2}C", "Ctrl+C" }, { "Ctrl\\+(Alt\\+|Shift\\+){0,2}F", "Ctrl+F" }, { "Esc", "Esc" }, { "F1($|,)", "F1" }, { "F12", "F12" } }; QList<QKeySequenceEdit *> keySequenceEditList = findChildren<QKeySequenceEdit *>(); for (QKeySequenceEdit *keySequenceEdit : keySequenceEditList) { QKeySequence keySequence = keySequenceEdit->keySequence(); if (!keySequence.count()) continue; QStringList tooltip; for (QKeySequenceEdit *otherKeySequenceEdit : keySequenceEditList) { if (keySequenceEdit == otherKeySequenceEdit) continue; QKeySequence otherKeySequence = otherKeySequenceEdit->keySequence(); if (keySequence == otherKeySequence) { tooltip.append(QString("- Multiple '%1' keybinds found").arg(keySequence.toString())); } else if (otherKeySequence.count() == 1 && keySequence[0] == otherKeySequence[0]) { tooltip.append(QString("- '%1' exist, can not start with that combination") .arg(otherKeySequence.toString())); } for (const QString &conflinctingKeybind : conflictingKeybindList.keys()) { QRegularExpression regEx(conflinctingKeybind); QRegularExpressionMatch match = regEx.match(keySequence.toString()); if (match.hasMatch()) tooltip.append(QString("- '%1' conflict with known keybind") .arg(conflictingKeybindList.value(conflinctingKeybind))); } } if (!tooltip.count()) keySequenceEdit->setStyleSheet("QLineEdit { color: black; }"); else keySequenceEdit->setStyleSheet("QLineEdit { color: red; }"); keySequenceEdit->setToolTip(tooltip.join("\n")); } }@reonZ
Ok, thats how we can detect any issues
but we would not really have an idea where the LineEdit have painted that part.But lets say we could. Would yo u then put red rectangle on the part of how to show it to the user?
Its not an option to color the text as that is not possible. -
@reonZ
Ok, thats how we can detect any issues
but we would not really have an idea where the LineEdit have painted that part.But lets say we could. Would yo u then put red rectangle on the part of how to show it to the user?
Its not an option to color the text as that is not possible.@mrjj Well i am ready to do anything that can isolate the faulty parts yes, so it could be background-color, or a rectangle, as long as it make it obvious to the user what is wrong here.
But if it is really too much of a hassle, then i will stick with that, at least for now.
-
@mrjj Well i am ready to do anything that can isolate the faulty parts yes, so it could be background-color, or a rectangle, as long as it make it obvious to the user what is wrong here.
But if it is really too much of a hassle, then i will stick with that, at least for now.
-
@reonZ
Well we could use an overlay widget we put on top of the LineEdit and draw on that
but its not without issues if the window can resize and QKeySequenceEdit would change size. -
hi
Helps a lot if no resize as code get waaaay smaller.
Did a fast test#include <QPainter> #include <QWidget> class SeqErrorOverlay : public QWidget { Q_OBJECT public: explicit SeqErrorOverlay(QWidget *parent = nullptr) : QWidget(parent) { setAttribute(Qt::WA_TranslucentBackground); setAttribute(Qt::WA_TransparentForMouseEvents); } void paintEvent(QPaintEvent *) override { QPainter p(this); p.fillRect(rect(), Qt::transparent ); p.setPen(QColor(255, 0, 0, 255)); p.drawRect(0, 0, 30, height()); } }; --- to set it up if (LineEdit) { SeqErrorOverlay *ov = new SeqErrorOverlay(LineEdit); ov->resize(LineEdit->width(), LineEdit->height());
so should work if you can place the rects in right places.
-
hi
Helps a lot if no resize as code get waaaay smaller.
Did a fast test#include <QPainter> #include <QWidget> class SeqErrorOverlay : public QWidget { Q_OBJECT public: explicit SeqErrorOverlay(QWidget *parent = nullptr) : QWidget(parent) { setAttribute(Qt::WA_TranslucentBackground); setAttribute(Qt::WA_TransparentForMouseEvents); } void paintEvent(QPaintEvent *) override { QPainter p(this); p.fillRect(rect(), Qt::transparent ); p.setPen(QColor(255, 0, 0, 255)); p.drawRect(0, 0, 30, height()); } }; --- to set it up if (LineEdit) { SeqErrorOverlay *ov = new SeqErrorOverlay(LineEdit); ov->resize(LineEdit->width(), LineEdit->height());
so should work if you can place the rects in right places.
-
@mrjj But i have no way to know how large the rectangle should be, i can't translate a
QStringindex and number of character into a width. -
@reonZ
Well you actually can. But it might not be enough.QString str("I wonder how wide this is?"); QFontMetrics fm(LineEdit->font()); // we must use same font as LineEdit int width=fm.width(str);@mrjj Alright i will try to work this out, but it might cause issues when the content of
QLineEditgoes out of bounds though.As for displaying the error messages, i removed the tooltip and now place them in the context menu instead:

Thanks for your help.
-
@mrjj Alright i will try to work this out, but it might cause issues when the content of
QLineEditgoes out of bounds though.As for displaying the error messages, i removed the tooltip and now place them in the context menu instead:

Thanks for your help.