c++qtmousehovereventfilter

Qt installEventFilter() for all children of a Tab Page


I am trying to capture hover events for all children of a TabWidget page. I subclassed QObject and reimplemented the eventFilter() to emit a signal to populate a label. The signal sends the name of the target object and a chosen language (e.g."English") as arguments. The label has a slot that takes this information and chooses an appropriate text file to read and display information. It is similar to displaying a tool tip but I need it to be diaplyed within the label. Header:

#include <QEvent>
#include <QObject>

class ToolTipGenerator : public QObject
{
    public:
        ToolTipGenerator();
        void setLanguage(QString lang);

    protected:
        virtual bool eventFilter(QObject *obj, QEvent *event);

    private:
        QString language;

    signals:
        displayToolTip(const QString &lang, const QString &targetName);
        clearToolTip();
};

Source:

#include "ToolTipGenerator.h"

ToolTipGenerator::ToolTipGenerator()
{
    language = "English";
}

void ToolTipGenerator::setLanguage(QString lang)
{
    language = lang;
}

bool ToolTipGenerator::eventFilter(QObject *obj, QEvent *event)
{
    if(event->type() == QEvent::HoverEnter)
        emit displayToolTip(language, obj->objectName());
    else if(event->type() == QEvent::HoverLeave)
        emit clearToolTip();

    return false;
}

MainWindow.cpp:

connect(generator, SIGNAL(displayToolTip(QString,QString)),
            ui->toolTipLabel, SLOT(displayToolTipInLabel(QString,QString)));

void MainWindow::displayToolTipInLabel(const QString &lang,
                                       const QString &targetName)
{
    QFile file(toolTipPath + targetName + "_" + lang + ".txt");
    QString line;

    if (file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        QTextStream stream(&file);
        while (!stream.atEnd())
            line.append(stream.readLine()+"\n");

        if(ui->tabWidgetSensor->currentIndex() == 1)
            ui->toolTipLabelPage1->setText(line);
    }
    file.close();
}

I now have to install the event filter for every child of a tab page. Is there a better way to do this entire thing? Or at least a better way to install event filter for all the children without looping over all of them?


Solution

  • You could install the event filter on the QApplication object so it will see all events.

    Then, in the eventFilter you check if the object in question has your tab widget base as a parent (or generally as an ancestor if you also want to have children's children).

    Something like

    bool ToolTipGenerator::eventFilter(QObject *obj, QEvent *event)
    {
        if (event->type() == QEvent::HoverEnter) {
    
            // compare with your target parent or loop if any ancestor should be checked
            if (obj->parent() == youPage)
                emit displayToolTip(language, obj->objectName());
        }
        // ....
    }