[Solved] Declaring virtual event() in class causes widget to disappear?
-
wrote on 13 Oct 2012, 12:08 last edited by
I am creating a simple custom event that detects when the QLineEdit's text is "Hello".
I have the following code:
HelloWidget.h:
@
class HelloWidget : public QLineEdit
{
Q_OBJECT
public:
explicit HelloWidget(QWidget *parent = 0);
~HelloWidget();virtual void handleHelloEvent(); bool event(QEvent* eventFired);
signals:
public slots:
void checkForHello();private:
QTimer* iterator;};
@HelloWidget.cpp:
@
HelloWidget::HelloWidget(QWidget *parent) :
QLineEdit(parent), iterator(new QTimer)
{
connect(iterator, SIGNAL(timeout()), this, SLOT(checkForHello()));
iterator->start();
}HelloWidget::~HelloWidget()
{
delete iterator;
}void HelloWidget::checkForHello()
{
if (this->text() == "Hello")
{
HelloTyped* eventFired = new HelloTyped;
QCoreApplication::postEvent(this, eventFired);
}
}bool HelloWidget::event(QEvent* eventFired)
{
if (eventFired->type() == HelloTyped::HELLO_TYPED_TYPE)
{
this->handleHelloEvent();
return true;
}return QObject::event(eventFired); // handle global events?
}
void HelloWidget::handleHelloEvent()
{
qDebug() << "Hello typed!";
disconnect(iterator, SIGNAL(timeout()), this, SLOT(checkForHello()));
}
@However, whenever I declared the event() function, the QLineEdit would no longer appear when I run the application! I've tried testing the program without the event() function's code (just empty brackets {}), but the QLineEdit would still not appear on the screen.
Any solutions?
-
wrote on 13 Oct 2012, 12:44 last edited by
You should call the event() implementation of your direct base, not QObject.
@
bool HelloWidget::event(QEvent* eventFired)
{
...return QLineEdit::event(eventFired); // handle global events?
}
@ -
wrote on 13 Oct 2012, 12:49 last edited by
It worked!! How/why though?
-
wrote on 13 Oct 2012, 12:57 last edited by
HelloWidget is-a QLineEdit is-a QWidget is-a QObject.
All of these four have their own implementation of event(). The bottom-most event() method is called and is reponsible to call the direct base class implementation so the code there is executed as well.
If you now skip QLineEdit::event() and QWidget::event() your widget won't be shown, because the responsible code, in this case in QWidget::event(), isn't executed.
-
wrote on 13 Oct 2012, 14:57 last edited by
In particular, QObject::event() has no idea how to handle a paint event whereas QWidget does. This is exactly how control ends up in the paintEvent() function of widgets which then use QPainter to draw the widget.
-
wrote on 13 Oct 2012, 17:04 last edited by
Makes sense.
Just wondering, does QLineEdit's paintEvent() function do anything different than QWidget's? I can return QWidget::event(eventFired) and the program will work fine.
-
wrote on 13 Oct 2012, 17:13 last edited by
It very well could, yes. However, perhaps in this case it works, due the fact that the actual painting is done using QStyle, and not by QLineEdit directly.
In general, you should always call the implementation of the direct base class, not of one of the classes above that. You just don't know what important stuff goes on there (and that could change between versions too), so better safe than sorry.
One way to do this, is to get into the habbit of doing this:
@
MyClass: public QSomeClass
{
typedef QSomeClass BaseClass; //BaseClass is always te direct base class of the class//...
}
@And use BaseClass to call functions in the base implementation everywhere. That way, you don't easily fall to the temptation to call QWidget:: or even QObject:: if these are not the direct base class. Also, it makes it easier to change the code later on, because the information on what the base class is is only in one place: the top of the class declaration. So, if you later decide you want to put another class in between in your hierarchy, you only need to change your .h in two lines and be done with it.
-
wrote on 13 Oct 2012, 17:20 last edited by
Cool, thanks everyone!
7/8