简体   繁体   中英

mouse press event inside Qpushbutton in QT

I am using qt creator to make a calculator. There is a default mainwindow form that has the gui. And in mainwindow.cpp, i have set setMouseTracking(true) , to get mouse coordinates when clicked. But i get the mouse coordinates only when a click is made outside any button in the mainwindow form. I guess this has something to do with the fact that when a button is clicked, already a mouse event of some sort is being generated to handle that click. I need to get the coordinates when clicked inside a button. How do I do that?

First thing first: this is a bad idea : )

What you are trying to do is to capture an event that is sent to a child object. A way to do this is to re-implement event handler of the children objects. But when you use the designer to construct your interface, this becomes a little hard. You have to promote all your widgets to re-implemented versions of them.

Another method is to use "even filter" feature of the Qt. You implement an QObject based class which implements a generic event handler function. Then you install this object as an "event filter" on the target object. A simple even filter class looks like this;

class Filter : public QObject
{
protected:
    bool eventFilter(QObject *obj, QEvent *ev)
    {
        // obj : original receiver of the event
        // ev : any event that is sent to 'obj'
        QObject::event(obj, ev);
    }
};

And its usage:

Filter filterObject;
targetObject.installEventFilter(filterObject);

Normally you have to install this event filter to all objects (widgets) in your user interface. But instead of going one by one, if you install this filter to your QApplication instance, it will capture all events in your application. After capturing, you can filter the event by it's type and originator.

Here is a more complete example that will capture all mouse press events in your application;

class ClickFilter : public QObject
{
protected:
    bool eventFilter(QObject *obj, QEvent *ev)
    {
        if (ev->type() == QEvent::MouseButtonPress && obj->inherits("QWidgetWindow"))
        {
            QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(ev);
            qDebug() << "clicked:" << mouseEvent->pos();
        }
        return QObject::eventFilter(obj, ev);
    }
};

You should install this event filter object on your QApplication instance, presumably in main function;

QApplication a(argc, argv);
ClickFilter cf;
a.installEventFilter(&cf);

This will capture all events in your application (that includes all windows - if your application has multiple main windows), then filter them by type and originator objects type.

But there is a problem with this code. I've used the QWidgetWindow type to check for events originator. Thats because if an event is not processed by a child widget, it's propagated to its parent. So, in some cases ClickFilter::eventFilter is called multiple times for the same click event. I picked QWidgetWindow because it looked like an easy way of doing it. Problem is; QWidgetWindow is an internal Qt type. It's not a good idea to use it in your application. I'm sure there is another way of preventing duplicates.

More importantly it's not a good idea to install an event filter on your QApplication instance, it may cause performance problems. But on the other hand, in my application I've used this method to easily add keyboard shortcuts of a toolbar button to it's tooltip throughout all application. You can see it here .

It's a little late but the solution is the solution. someone takes advantage.

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMouseEvent> // important!!!
#include <QEvent> // important!!!

//..... bla bla
//..... bla bla

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:

//..... bla bla

protected:
    bool eventFilter(QObject *watched, QEvent *event); // important!!!

//..... bla bla

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>

//..... bla bla
    
MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
       qApp->installEventFilter(this); // important!!!
    
 //..... bla bla
    
    bool MainWindow::eventFilter(QObject *watched, QEvent *event){
        
        if(  event->type() == QEvent::MouseButtonPress){
            qDebug() << watched->objectName() << event->type();
            QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
            qDebug() << "clicked:" << mouseEvent->pos();
            return true;
        }
        return false;
    }

thats it!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM