PDA

View Full Version : QLineEdit keep cursor active.



bunjee
2nd September 2009, 10:43
Hey Guys,

I want the "QLineEdit cursor" to stay active no matter if QLineEdit has focus or not.

How would you guys do that ?

victor.fernandez
2nd September 2009, 11:44
Reimplement focusOutEvent() (http://qt.nokia.com/doc/4.5/qwidget.html#focusOutEvent) to ignore that event and post QFocusEvent with type QEvent::FocusIn in your constructor to let the widget believe it has the focus. This way the widget will never know it doesn't have the focus.

bunjee
2nd September 2009, 12:20
Thanks.



lineEdit->installEventFilter(this);

bool qkWebShell::eventFilter(QObject * object, QEvent * event)
{
if (event->type() == QEvent::FocusOut) return true;
}

EDIT: This screws the QWidget focus policy.

victor.fernandez
2nd September 2009, 12:51
Of course it screws the focus policy for the widget because the idea is not to let the widget know it has lost the focus.

If you do it using event filters, don't forget to call your parent class' eventFilter() method to pass the event to it, in case it wanted to filter something:


bool qkWebShell::eventFilter(QObject * object, QEvent * event)
{
if (event->type() == QEvent::FocusOut) return true;

return this->QLineEdit::eventFilter(object, event);
}

wysota
2nd September 2009, 12:51
Obviously your code does something completely different than the solution suggested. You are just ignoring all focus out events which is incorrect. If this is to work at all, you have to handle the event but immediately send another one to fool the widget.

But it's probably better to subclass the line edit and change the drawing routine to convince QStyle that the widget has focus and the cursor should be drawn.

Edit: Actually QTextLine not QStyle.

victor.fernandez
2nd September 2009, 13:04
I agree. It would be better to subclass QLineEdit and reimplement paintEvent() but also more difficult. If you do so, take a look at the source code of qlineedit.cpp. At the end of paintEvent() you have:


if (d->cursorVisible && !d->readOnly && !d->hideCursor)
d->textLayout.drawCursor(&p, topLeft, cursor, style()->pixelMetric(QStyle::PM_TextCursorWidth));

You would remove d->cursorVisible from the if(). Keep in mind you can't access the private object so you may either find another way to get that information or copy its implementation an rename it.

bunjee
2nd September 2009, 13:28
Keep in mind you can't access the private object

Are you sure about that?

victor.fernandez
2nd September 2009, 13:48
If you include qlineedit_p.h you can but you shouldn't because it's an internal file and it may be changed at any time.

From qlineedit_p.h:


// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.

bunjee
2nd September 2009, 14:03
Feels like using a tank to kill a fly.

What would you do ?

victor.fernandez
2nd September 2009, 14:07
Yes it is. But if you don't do so, you have the risk that your application doesn't compile with future versions of Qt without changing the source code.

wysota
2nd September 2009, 15:50
It's not that easy. If you include lineedit_p.h, you have to include qwidget_p.h and qobject_p.h. They in turn need a bunch of other includes.

It's much easier to construct QTextLine and QTextLayout yourself and use them to draw the line of text with the cursor. It's really simple.