[SOLVED] How to make LineEdit show text in uppercase always



  • Hi all!

    I'm making a gui app which contains some lineedits to let the user introduce some information.I want that If the user write letters with caps lock or not, the line edits should always shows the text in uppercase.

    I tried with an input mask like this one but it doen't work as I want:
    @lineedit_case2->setInputMask(">AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); @

    I tried it with:
    @
    connect(lineedit_Num1, SIGNAL(textChanged(QString)),this, SLOT(toUpper(QString)));

    void Test::toUpper(QString text)
    {
    QLineEdit *le = qobject_cast<QLineEdit *>(sender());
    if (!le)
    return;
    le->setText(text.toUpper()); // found this looking on internet but not sure about how it works
    lineedit_Num1->setText(text.toUpper()); //trying if that works
    }@
    Thank you so much



  • I thought Isolved it with an event filter, but not at all. I have the next code and it works fine with and without caps locks BUT it doesn't if I press shift.

    @ if(key->key() >= Qt::Key_A && key->key() <= Qt::Key_Z &&
    ((key->modifiers() & Qt::ShiftModifier) == false))
    {
    QApplication::sendEvent(obj, new QKeyEvent(QEvent::KeyPress,
    key->key(), key->modifiers() | Qt::ShiftModifier,
    key->text().toUpper()));
    QApplication::sendEvent(obj, new QKeyEvent(QEvent::KeyRelease,
    key->key(), key->modifiers() | Qt::ShiftModifier,
    key->text().toUpper()));
    return true;
    }
    @

    So... Any idea?



  • I don't know if this would be the best way but it might be the easiest. You only need to connect the textChanged(QString&) or textEdited(QString&) signal to a slot that checks the text:

    @
    void MyApp::line_edit_text_changed(const QString &text)
    {
    QString uc_text(text.toUpper());

    if(uc_text != text)
    {
    bool prev_state = line_edit->blockSignals(true);

    line_edit->setText(uc_text);
    
    line_edit->blockSignals(prev_state);
    

    }
    }
    @

    The block signals call keeps this from becoming recursive.

    Edit: On second thought this might be a bad idea. You should avoid trying to 'replace' text entered in a control.



  • Hi Rondog,

    Isn't this like the last thing I posted on my first post? Anyway it seems that my program doesn't pass throw that toUpper slot I did and I don't know why :S

    Edit: the only case where the program shows downcase is if capslock is on but you press shift while writting.



  • You're right, It is basically the same idea. I should have looked closer.

    The slot in your first post should be ::toUpper(const QString &text) and not ::toUpper(QString text). This might be why it isn't called?

    Note. After reflection I think this is a bad approach (changing text after the fact). If you can find a way to either draw the text as upper case only (custom paintEvent()) or a custom keyPress() event which you were looking at this might be better. Changing after the fact is easy and might work but it might also cause other problems if you are not careful.



  • No.I already saw the mistake and tried too but its teh same, that's why I didn't say a thing about it...

    I have this on the constructor:
    @ connect(lineedit_Num1, SIGNAL(textChanged(QString &)),this, SLOT(toUpper(QString &)));@

    And then this, because I take it from an example on itnernet and I don't know how do it works exactly so..
    @
    void Test::toUpper(QString &text)
    {
    // Case for my lineedit I suppose
    QLineEdit *lineedit_Num1= qobject_cast<QLineEdit *>(sender());
    if (!lineedit_Num1)
    return;
    lineedit_Num1->setText(text.toUpper());

    // this is the example i found
    QLineEdit *le = qobject_cast<QLineEdit *>(sender());
    if (!le)
    return;
    le->setText(text.toUpper());
    }
    @



  • This might work but you need to block the signals otherwise it might call recursively (won't on textEdited() but it will on textChanged()).

    Maybe add this to be safe:

    @
    QLineEdit *lineedit_Num1= qobject_cast<QLineEdit *>(sender());
    if (!lineedit_Num1)
    return;

    QString uc_text(text.toUpper());
    if(uc_text != text)
    {
    bool ps = lineedit_Num1->blockSignals(true);
    lineedit_Num1->setText(uc_text);
    lineedit_Num1->blockSignals(ps);
    }
    @



  • So u mean to have:
    @void Test::toUpper(QString &text)
    {
    QLineEdit *lineedit_Num1= qobject_cast<QLineEdit *>(sender());
    if (!lineedit_Num1)
    return;

    lineedit_Num1->setText(text.toUpper());
    

    QString uc_text(text.toUpper());
    if(uc_text != text)
    {
    bool ps = lineedit_Num1->blockSignals(true);
    lineedit_Num1->setText(text.toUpper());
    lineedit_Num1->blockSignals(ps);
    }
    }@

    Its the same but as I said if I debbug I see that the program never passes throw :toUpper() slot/function so the problem should be there but dunno why... I don't understand why dosn't work that connect(). I have more connect() in the same constructor that works fine...



  • This might be a long shot (a very long shot) but the name of the slot 'toUpper' is also the name of a QString function that takes the same input parameters. Maybe a different slot name?

    I assume the class 'Test' is derived properly, has Q_OBJECT declared and the slot 'toUpper(const QString&) declared as a slot (public or private).

    It should call this slot regardless of what you do in the slot itself.


  • Moderators

    I think you're making this harder than it needs to be. A custom validator will suffice:

    @
    class MyValidator: public QValidator {
    public:
    MyValidator(QObject* parent=nullptr): QValidator(parent) {}
    State validate(QString& input, int&) const override {
    input = input.toUpper();
    return QValidator::Acceptable;
    }
    };

    //and then
    auto validator = new MyValidator(parent);
    lineEdit->setValidator(validator);
    @



  • Yeah Chris Kawa! It works perfect now! Thank you so much!! I have a question (I'm still learning how Qt works) and its: why do you put "parent" when u create the new MyValidator???

    Rondog, that is why I specified that I hav eother connects declared the same way and they run well... I still don't undertand why this one doesn't


  • Moderators

    bq. why do you put “parent” when u create the new MyValidator???

    The line edit does not automatically take ownership of the validator object because you can assign a single validator to multiple widgets and ownership would be ambiguous. So normally you would have to delete the validator object yourself at some point, but assigning it a parent will ensure it will be destroyed when the parent is deleted. More on this "here":http://doc.qt.io/qt-5/objecttrees.html.

    If you have a single validator for a single line edit you can use that lineEdit as a parent, and it will be destroyed when the line edit is:
    @
    lineEdit->setValidator(new MyValidator(lineEdit));
    @



  • Ohh I see, thanks for the explanation Chris Kawa. I usually put () or (this) on that cases because it works hehe. Now I have it so much clear :DD


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.