[Solved] Declaring virtual event() in class causes widget to disappear?



  • 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?



  • You should call the event() implementation of your direct base, not QObject.
    @
    bool HelloWidget::event(QEvent* eventFired)
    {
    ...

    return QLineEdit::event(eventFired); // handle global events?
    

    }
    @



  • It worked!! How/why though?



  • 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.



  • 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.



  • 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.



  • 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.



  • Cool, thanks everyone!


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.