17

I have created a dialog using QtDesigner. There is a QLineEdit object in the dialog with some default content. When the dialog initializes and the focus goes to the QLineEdit, I want the default content to be auto selected, so once the user start writing, the previous content will be overwritten.

EDIT:

In constructor:

dialog->accept(); 

and

connect( dialog, SIGNAL(accepted()), QlineObj, SLOT( selectAll() ) );
msrd0
  • 7,816
  • 9
  • 47
  • 82
GG.
  • 2,835
  • 5
  • 27
  • 34
  • It is simply a bug. If I do a ui->myedwidget->deselect(); AFTER I have written something in the QLineEdit, it should remove any selection. But it is still there --> BUG. Unfortunately QT is filled with bugs. Because of these, I had to avoid QTableView and use instead QTableWidget. And this is just an example. I am using QT 5.9.5 with QT Creator 4.5.2 on Ubuntu 18.04 LTS. – Vinix May 17 '20 at 14:54
  • It is simply a bug. If I do a ui->myedwidget->deselect(); AFTER I have written something in the QLineEdit, it should remove any selection. But it is still there --> BUG. Unfortunately QT is filled with bugs. Because of these, I had to avoid QTableView and use instead QTableWidget. And this is just an example. I am using QT 5.9.5 with QT Creator 4.5.2 on Ubuntu 18.04 LTS. – Vinix May 17 '20 at 14:54

4 Answers4

13

This is an older question, but nevertheless, I ended up here searching for a solution this exact problem. It can be solved in the following way:

Create a class derived from QLineEdit and override the focusInEvent in the header:

void focusInEvent(QFocusEvent *event) override;

Then implement it like so:

void MyLineEdit::focusInEvent(QFocusEvent *event)
{
    // First let the base class process the event
    QLineEdit::focusInEvent(event);
    // Then select the text by a single shot timer, so that everything will
    // be processed before (calling selectAll() directly won't work)
    QTimer::singleShot(0, this, &QLineEdit::selectAll);
}

Just in case anybody else wonders how this can be done ;-)

Tobias Leupold
  • 1,512
  • 1
  • 16
  • 41
11

Call

lineEdit->selectAll();

after you set the default text. (In the dialog constructor, perhaps.)

andref
  • 4,460
  • 32
  • 45
  • Thanks I already did it ;) dialog->accept(); { in constructor } and connect( dialog, SIGNAL(accepted()), QlineObj, SLOT( selectAll() ) ); – GG. Aug 09 '10 at 03:07
  • 2
    This works in constructor: QTimer::singleShot(0, lineEdit, SLOT(selectAll())); – Zmey Feb 05 '16 at 19:29
8

There is a simpler method to get almost the same behaviour, which is to set the default content using setPlaceholderText() instead of setText(). This will show the default content grayed out and as soon as the QLineEdit gains focus, it will disappear.

Rob
  • 3,418
  • 1
  • 19
  • 27
0

You can use QApplication::focusChanged along with QTimer::singleShot to select all the text on a changed focus.

Normally your QApplication is declared in main, so use QObject::connect there, eg:

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    My_Main_Window w();
    QObject::connect(&a, SIGNAL(focusChanged(QWidget*, QWidget*)),
                     &w, SLOT(my_focus_changed_slot(QWidget*, QWidget*)));
    w.show();

    return a.exec();
}

Remember to make the public slot in the My_Main_Window class:

public slots:
void my_focus_changed_slot(QWidget*, QWidget*);

Then in your definition of my_focus_changed_slot, check if the second QWidget* (which points to the newly focused widget) is the same as the QLineEdit you wish to select all of, and do so using QTimer::singleShot so that the event loop gets called, then the QLineEdit has the selectAll slot called immediately after, eg

void My_Main_Window::focus_changed(QWidget*, QWidget* new_widget) {
    if (new_widget == my_lineedit) {
        QTimer::singleShot(0, my_lineedit, &QLineEdit::selectAll);
    }
}

where my_lineedit is a pointer to a QLineEdit and is part of the My_Main_Window class.

Catcow
  • 7
  • 2
  • Can you please explain more why we needed to use `QTimer::singleShot`? – Praneeth Peiris Mar 31 '21 at 09:31
  • In qt documentation, it mentions QTimer::singleShot(). Basically it has to do with the event loop. Passing in 0 like I do in my example simply let's the event loop pass, then it notices the timer is done and then calls the connected slot https://doc.qt.io/archives/qq/qq27-responsive-guis.html#waitinginalocaleventloop – Catcow Apr 03 '21 at 15:35