Solved No cursor in QLineEdit after FocusIn event
-
Hi. I have a problem with QLineEdit.
I need to call selectAll() after QLineEdit instance gets focus. So I made a custom class to use the appropriate event.
The problem is, right after the overrided focusInEvent() is inserted into code, the cursor in this LineEdit stops working as it should, and the selection won't show (the one which should appear after selectAll() ). If I click LMB into LineEdit, nothing visibly changes, no cursor. The cursor appears after pressing arrow keys on keyboard, but it doesn't blink. If I click RMB into LineEdit, the selection appears, but the cursor works wrong still.
If I check the cursor's position on focusInEvent, it says it's at the end of a value, as if everything is selected.
I also tried calling a different method instead of selectAll(), namely clear(), and it works.
So I'm wondering if I'm missing something that I should do, or this is potentially a bug.
In this help article, it says that default focus event updates the widget:
"[virtual protected] void QWidget::focusInEvent(QFocusEvent *event)
...
The default implementation updates the widget (except for windows that do not specify a focusPolicy()).
..."
But I tried calling update() for the LineEdit in different ways, and the problem persisted.QApplication::cursorFlashTime() is 400 , if it matters.
Any help would be appreciated.
I'm on Windows 7 64-bit
Qt Creator 4.10, Qt 5.13.1 (MSVC 2017, 32 bit) -
Did you actually call the base class (QLineEdit::focusInEvent())? Please show us some code.
-
The code
mainwindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include "ui_mainwindow.h" #include <QMainWindow> QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); private slots: void on_cmnd_tlk_file_open_triggered(); void on_strings_table_itemSelectionChanged(); void on_cur_str_number_field_returnPressed(); void on_num_field_focus(); // slot to select all in LineEdit private: Ui::MainWindow *ui; }; #endif // MAINWINDOW_H
mainwindow.cpp
#include "main.h" #include "mainwindow.h" #include "ui_mainwindow.h" #include "tlk_functions.h" #include "number_input_field.h" //custom class #include <QSplitter> #include <QDebug> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); QSplitter *window_splitter = new QSplitter(Qt::Vertical, nullptr); window_splitter->addWidget(ui->strings_table); window_splitter->addWidget(ui->text_field); QVBoxLayout *layout_tlk_tab = new QVBoxLayout(ui->tlk_tab); layout_tlk_tab->setMargin(0); layout_tlk_tab->addWidget(window_splitter); QRegExpValidator *numbers_filter = new QRegExpValidator(QRegExp("[0-9]*"), this); ui->cur_str_number_field->setValidator(numbers_filter); //connection of signal to slot connect(ui->cur_str_number_field, SIGNAL( num_field_got_focus() ), this, SLOT( on_num_field_focus() )); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_cmnd_tlk_file_open_triggered() { tlk_file_open(this, ui); } void MainWindow::on_strings_table_itemSelectionChanged() { tlk_string_selected(ui); } void MainWindow::on_cur_str_number_field_returnPressed() { tlk_number_input_finished(ui); } //slot to select all in LineEdit void MainWindow::on_num_field_focus() { qDebug() << "got focus"; ui->cur_str_number_field->selectAll(); }
number_input_field.h (custom class)
#ifndef NUMBER_INPUT_FIELD_H #define NUMBER_INPUT_FIELD_H #include <QLineEdit> class number_input_field : public QLineEdit { Q_OBJECT //added to use signals and slots public: number_input_field(QWidget * = nullptr); signals: void num_field_got_focus(); //my custom signal protected: void focusInEvent(QFocusEvent *event) override; private: }; #endif // NUMBER_INPUT_FIELD_H
number_input_field.cpp (custom class)
#include "mainwindow.h" #include "ui_mainwindow.h" #include "number_input_field.h" #include <QWidget> #include <QFocusEvent> #include <QDebug> number_input_field::number_input_field(QWidget *) { } void number_input_field::focusInEvent(QFocusEvent *event) { emit num_field_got_focus(); event->accept(); }
-
So, as I expected, you don't call the base class impl QLineEdit::focusInEvent() - how do you expect the QLineEdit can do anything then when it not receives the focus in event?
-
@Christian-Ehrlicher
Could you explain where do I call it, i.o.w. what should I change? -
It's c++ basics - when you override a function you should/have to call the base class - otherwise the base class implementation will not get called: https://www.programiz.com/cpp-programming/function-overriding
-
Hi
Read the link @Christian-Ehrlicher gave you as its very good description and not
technically hard to understand.And it goes for most overwrites you do with Widgets. You must call the base class also or something will often break.
void number_input_field::focusInEvent(QFocusEvent *event)
{
QLineEdit::focusInEvent(event);// this call the base and give it the parameter also
emit num_field_got_focus();
event->accept();
}Its a must know/understand c++ thing that you should take the time to study a bit in my opinion as its often needed :)
-
Thank you, problem solved.
-
@rebus_x
Super. Feel free to ask if any doubts about the call the base class thing as you will come across it everwhere in Qt.