0

I want to grab the focus on a QLineEdit control. In order to do that, I reimplemented the focusInEvent in my subclassed control. The problem is, that it works only for focusing with keyboard, aka. using the TAB. If I click it with the mouse or tap it (since it's an embedded app) it doesn't seem to grab the event at all.

I already tried setting the focusPolicy but without any luck.

.cpp file:

#include "foolineedit.h"
#include "ui_foolineedit.h"
#include <QDebug>
#include <QFocusEvent>

fooLineEdit::fooLineEdit(QWidget *parent) :
    QLineEdit(parent),
    ui(new Ui::fooLineEdit)
{
    ui->setupUi(this);
    this->setFocusPolicy(Qt::ClickFocus);
}

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

void fooLineEdit::focusInEvent(QFocusEvent *e)
{
    qDebug() << e->reason();
    QLineEdit::focusInEvent(e);
    emit(focused(true));
}

.h file:

#include <QWidget>
#include <QLineEdit>

namespace Ui {
class fooLineEdit;
}

class fooLineEdit : public QLineEdit
{
    Q_OBJECT

public:
    explicit fooLineEdit(QWidget *parent = 0);
    ~fooLineEdit();
signals:
    void focused(bool hasFocus);
protected:
    virtual void focusInEvent(QFocusEvent *e);
private:
    Ui::fooLineEdit *ui;
};

Any ideas about what am I doing wrong?


EDIT:

Because it was mentioned in comments I add the code listing for the ui header

ui_foolineedit.h

class Ui_fooLineEdit
{
public:
    QLineEdit *lineEdit;

    void setupUi(QWidget *fooLineEdit)
    {
        if (fooLineEdit->objectName().isEmpty())
            fooLineEdit->setObjectName(QStringLiteral("fooLineEdit"));
        fooLineEdit->resize(151, 21);
        lineEdit = new QLineEdit(fooLineEdit);
        lineEdit->setObjectName(QStringLiteral("lineEdit"));
        lineEdit->setGeometry(QRect(0, 0, 151, 21));
        lineEdit->setFocusPolicy(Qt::ClickFocus);

        retranslateUi(fooLineEdit);

        QMetaObject::connectSlotsByName(fooLineEdit);
    } // setupUi

    void retranslateUi(QWidget *fooLineEdit)
    {
        fooLineEdit->setWindowTitle(QApplication::translate("fooLineEdit", "Form", Q_NULLPTR));
    } // retranslateUi

};

namespace Ui {
    class fooLineEdit: public Ui_fooLineEdit {};
} // namespace Ui
Foufoutos
  • 17
  • 5
  • Is there a specific reason to implement a custom QLineEdit in editor? – p-a-o-l-o Feb 13 '18 at 13:12
  • Yes, I think so. My goal is to have a virtual keyboard show up each time a QLineEdit gets focus in, and hide it on focus out. – Foufoutos Feb 13 '18 at 13:15
  • Check if `Qt::MouseFocusReason` helps as in this [post](https://stackoverflow.com/questions/21155148/how-to-use-focusinevent-and-focusoutevent) – Mohammad Kanan Feb 13 '18 at 13:15
  • @MohammadKanan I already came across that post. Unfortunately, the if statement isn't even being evaluated, since the event does not fire at all. – Foufoutos Feb 13 '18 at 13:29
  • No, sorry, I mean: *why this custom QLineEdit has a Ui all for itself*? – p-a-o-l-o Feb 13 '18 at 13:30
  • 1
    In other words: what's going on inside `ui->setupUi(this)`? Are there children added to the QLineEdit? – p-a-o-l-o Feb 13 '18 at 13:39
  • Oh, sorry I didn't get it. Well, that's a good point, but I think for no apparent reason. Does this matter though? **EDIT:** I get your point. No children in it however – Foufoutos Feb 13 '18 at 13:42
  • Yes there is a child. See my answer for a better explanation. – p-a-o-l-o Feb 13 '18 at 14:40

1 Answers1

1

You basically add a

QLineEdit *lineEdit;

to your fooLineEdit, which in turn is just another QLineEdit.

This happens in setupUi:

lineEdit = new QLineEdit(fooLineEdit);

and I think this is enough to mess things up (the event handler of fooLineEdit waits forever for an event which is very likely to occur inside the inner QLineEdit).

Try implementing a QLineEdit subclass without using an ui.

Header:

class fooLineEdit : public QLineEdit
{
    Q_OBJECT

public:
    explicit fooLineEdit(QWidget *parent = 0);
signals:
    void focused(bool hasFocus);
protected:
    virtual void focusInEvent(QFocusEvent *e);
};

Source:

fooLineEdit::fooLineEdit(QWidget *parent) :
    QLineEdit(parent)
{
    this->setFocusPolicy(Qt::ClickFocus);
}
void fooLineEdit::focusInEvent(QFocusEvent *e)
{
    qDebug() << e->reason();
    QLineEdit::focusInEvent(e);
    emit(focused(true));
}

And see if the issue is gone.

p-a-o-l-o
  • 9,807
  • 2
  • 22
  • 35