Search code examples
qteventfilter

How to install an event filter on all components inside a QWidget


I have my software with a lot of components ( textbox, checkbox, slider, ...). What i need to do is to install a filter to record all events done by the user ( click on checkbox, slide sliders, ...) save them and replay them later.

I first tryed to install the filter on all component, exemple :

MainGui::MainGui( QWidget* parent ) :
QMainWindow( parent ),
ui( new Ui::MainWindow ),
m_console( new Console( this ) ),
m_serial( &port_qt::get() ),
m_status( new QLabel( "Bienvenue sur STEG.", this ) ),
m_mainLayout( new QHBoxLayout() ){

ui->setupUi( this );
QWidget* centralWidget = new QWidget();
centralWidget->setLayout( m_mainLayout );
setCentralWidget( centralWidget );


addAction( m_console->action() );

statusBar()->addWidget( m_status );
statusBar()->layout()->setMargin( 9 );

QCheckBox *checkbox_1 = new QCheckBox("check 1");
checkbox_1->setChecked (true);

addWidgetToColumn(1,checkbox_1);
m_recorder.setObj(checkbox_1); // Install filter here

.......;}

This code works fine and i can succesfully record and replay a click on this checkbox. Unfortunatly, i need to install a filter which will work on ALL components inside the "centralWidget" and when i put the filter on it, i don't get any event related to the checkbox.

So i'm looking for a solution to install a general filter. Thanks you.

Edit:

Using qApp, i can succesfully get all events, but my problem now is to replay those events. I'm using qApp->postEvent(m_App, clonedEvent); (m_App is qApp). Events are sent but doesn't change Checkbox check status as it should.


Solution

  • I've tested this code and it should do what you want

    file mainwindow.h
    
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    
    QT_BEGIN_NAMESPACE
    namespace Ui { class MainWindow; }
    QT_END_NAMESPACE
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        MainWindow(QWidget *parent = nullptr);
        ~MainWindow();
    
    protected:
        bool eventFilter(QObject *obj, QEvent *event);
    
    private:
        Ui::MainWindow *ui;
    };
    #endif // MAINWINDOW_H
    
    
    file mainwindow.cpp
    
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    #include <QApplication>
    #include <QEvent>
    #include <QDebug>
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        qApp->installEventFilter(this);
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    bool MainWindow::eventFilter(QObject *obj, QEvent *event)
    {
    
        const QObjectList& list = ui->centralwidget->children(); // or centralwidget->children();
        if(list.contains(obj))
        {
            if(event->type() == QEvent::MouseButtonPress)
            {
                qDebug() << "QEvent::MouseButtonPress";
                if(obj == ui->pushButton)
                    qDebug() << "pushButton";
                else if(obj == ui->checkBox)
                    qDebug() << "checkBox";
            }
        }
    
        return QObject::eventFilter(obj, event);
    }
    

    Tell me if you have any problems with it.