PDA

View Full Version : There is a bug on QlineEdit?



glafauci
20th November 2012, 15:34
Hi, folks.
I'm in trouble from yesterday for a strange behavior of QLineEdit.
I need to keep trace (and manage) the moment when this widget (QLineEdit) lose its focus. I need three consecutive QlineEdit widgets, and I must control the FocusOut event of every widget.

I followed two lines:

1. install the InstallEventFilter for each widget, and then declare and code the EventFilter method for the window that manage the events

or

2. subclass QLineEdit and, within the QLineEdit::FocusOut event, emit a new signal. This signal is linked through a connection to a slot, in the window where I need to manage the event.

Both lines had the same problem: when one widget loses the focus, two event raises: the first from the next widget (!!), then the correct one. This behavior repeats for every widget.

To better explain, suppose we have three consecutive QLineEdit widget, named Line1, Line2 and Line3. When Line1 loses focus, first raise Line2 event and then Line1 event.
When Line2 loses focus, first raise Line3 event and then Line2 event.
When Line3 loses focus, first raise Line1 event and then Line2 event.

This strange behavior ceases when beneath the three widgets I insert other widgets that don't handle their events.
Why?

I attach to this post one example project that explaines what I say.
To point out this problem, switch the three TextLabel widgets in the main window Designer file (MainWindow.ui) from focusPolicy::NoFocus to focusPolicy::StrongFocus. When the focus policy is set to NoFocus the error raises, but when the focus policy is set to StrongFocus all goes well.

Notice that the same problem raises if I subclass QLineEdit, managing a new signal from FocusOut event.

ChrisW67
21st November 2012, 01:49
I really don't see the point of a QLineEdit that cannot have focus; without focus editing it will be difficult. I see no focus in or out events for such widgets. This is the case with your example as modified:


#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->lineEdit_1->installEventFilter(this);
ui->lineEdit_2->installEventFilter(this);
ui->lineEdit_3->installEventFilter(this);
ui->lineEdit_1->setFocusPolicy(Qt::NoFocus);
ui->lineEdit_2->setFocusPolicy(Qt::NoFocus);
ui->lineEdit_3->setFocusPolicy(Qt::NoFocus);
}

MainWindow::~MainWindow()
{
delete ui;
}

bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::FocusOut)
qDebug() << "Focus out" << obj;
else if (event->type() == QEvent::FocusIn)
qDebug() << "Focus in" << obj;
return false;
}

With the default StrongFocus policy on the line edits is see correct behaviour: one focus out followed by one focus in.

What are you trying to achieve by setting StrongFocus on the labels?

glafauci
21st November 2012, 10:52
Hi, Chris.
Perhaps I didn't explain well the problem.
In my project, attached to the first message, I have one Designer file, mainwindow.ui. If you open this file with QtDesigner, you have three QLineEdit objects and three TextLabel objects.
Don't modify the QlineEdit: first you run the project (with QtCreator is the best) setting the three TextLine objects focusPolicy property on NoFocus. With this settings the executable highlights the problem.
Afterwards modify the focusPolicy on the three TextLabels only to StrongFocus. Now the program runs fine.
My question is: why?
Below I show the file I created with QtDesigner:

8446

and this is the code I wrote on mainwindow.cpp:


#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->lineEdit_1->installEventFilter(this);
ui->lineEdit_2->installEventFilter(this);
ui->lineEdit_3->installEventFilter(this);
}

MainWindow::~MainWindow()
{
delete ui;
}

bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::FocusOut)
{
if (obj == ui->lineEdit_1)
QMessageBox::information(this, "", "line1");

if (obj == ui->lineEdit_2)
QMessageBox::information(this, "", "line2");

if (obj == ui->lineEdit_3)
QMessageBox::information(this, "", "line3");

}

return false;
}


Don't modify the code: simply download the file I attached to the first message and run it on QtCreator, switching only the focusPolicy property on the three TextLabels and you have the strange behavior of the QLineEdit widget.

Now I'm attaching two zipped files, with the two different settings and that show the behaviors.

Or, if in your code change the lines:



ui->lineEdit_1->setFocusPolicy(Qt::NoFocus); // line 14
ui->lineEdit_2->setFocusPolicy(Qt::NoFocus); // line 15
ui->lineEdit_3->setFocusPolicy(Qt::NoFocus); // line 16


with these:



ui->label->setFocusPolicy(Qt::NoFocus); // line 14
ui->label_2->setFocusPolicy(Qt::NoFocus); // line 15
ui->label_3->setFocusPolicy(Qt::NoFocus); // line 16


or



ui->label->setFocusPolicy(Qt::StrongFocus);
ui->label_2->setFocusPolicy(Qt::StrongFocus);
ui->label_3->setFocusPolicy(Qt::StrongFocus);


and have what I say without modify the .ui file.

Added after 17 minutes:

Ok, I'm a troll, I admit it. :rolleyes:

The bug is only in my code.

When I add the QMessageBox on the handling of the FocusOut event, happens what follows:

1. the focus is passed from the actual widget (e.g. Line_1) to the next QLineEdit widget (e.g. Line_2);
2. QMessageBox got the focus;
3. Line_2 lose focus and throw the event message (Line_2::FocusOut);
4. I close the QMessageBox;
5. Line_1::FocusOut event, queued from Qt to Line_2::FocusOut, is thrown;
6. and so on.

The bottom line is:
in the management function of a focus event, never use an object that manages the focus!!

Thank you, Chris, examining your code I understand my fault.

------------------------------------------------
A genius learns from the mistakes of others, a smart man learns from their own, the fool never learns.