QChartView setRubberBand prevents mouse events from reaching eventFilter
-
I'm using Qt C++ 6.6.1 and Qt Creator 12.0.2 on Windows 11 for a desktop application. I have a QChartView object in a modal Dialog window for displaying line graphs. The rubber band feature of QChartView allows me to click-and-drag the rubber band to zoom-in on areas of the graph. I also want to be able to <left click> in the graph and execute some application specific code (like display the corresponding value). I have an eventFilter for the Dialog and the 'MousePressEvent' does occur, unless the rubber band is enabled. If the rubber band is enabled then the 'MousePressEvent' does not occur in the eventFilter. This may be consistent with the Qt documentation for 'QChartView::mousePressEvent' which states, "If the left mouse button is pressed and the rubber band is enabled, the event 'event' is accepted ..." Since it 'accepted' the mouse event, that may explain why the eventFilter does not see 'MousePressEvent'.
The rubber band is enabled by the following line of code in the Dialog constructor:
ui->graphicsView->setRubberBand(QChartView::RectangleRubberBand);How do I enable/allow MousePressEvent to reach the eventFilter and have the rubber band enabled?
Here is the code that demonstrates the issue:
In the *.pro file I added 'charts' as follows:QT += core gui chartsmainwindow.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(); private slots: void on_pushButton_clicked(); private: Ui::MainWindow *ui; }; #endif // MAINWINDOW_Hdialog.h:
#ifndef DIALOG_H #define DIALOG_H #include <QChart> #include <QDialog> namespace Ui { class Dialog; } class Dialog : public QDialog { Q_OBJECT public: explicit Dialog(QWidget *parent = nullptr); ~Dialog(); protected: bool eventFilter(QObject *object, QEvent *event) override; private slots: private: Ui::Dialog *ui; }; #endif // DIALOG_Hmain.cpp:
#include "mainwindow.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }mainwindow.cpp
#include "mainwindow.h" #include "ui_mainwindow.h" #include "dialog.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_pushButton_clicked() { Dialog myDialog; myDialog.setModal(true); myDialog.exec(); }diaglog.cpp:
#include "dialog.h" #include "ui_dialog.h" Dialog::Dialog(QWidget *parent) : QDialog(parent) , ui(new Ui::Dialog) { ui->setupUi(this); /***************************************************** * The following line 'setRubberBand' prevents a 'MouseButtonPress' event * from reaching Dialog::eventFilter below. The Qt documentation for * QChartView states, "If the left mouse button is pressed and the rubber * band is enabled, the event 'event' is accepted and the rubber band is * displayed on the screen." ****************************************************/ ui->graphicsView->setRubberBand(QChartView::RectangleRubberBand); ui->graphicsView->installEventFilter(this); } Dialog::~Dialog() { delete ui; } bool Dialog::eventFilter(QObject *object, QEvent *event) { if (event->type() == QEvent::MouseButtonPress) { qDebug("In Dialog:eventFilter - QEvent::MouseButtonPress, objectName = %s", qPrintable(object->objectName())); /* I will add more application software here. */ } // standard event processing return QObject::eventFilter(object, event); }dialog.ui:
<?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>Dialog</class> <widget class="QDialog" name="Dialog"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>822</width> <height>478</height> </rect> </property> <property name="windowTitle"> <string>Dialog</string> </property> <widget class="QChartView" name="graphicsView"> <property name="geometry"> <rect> <x>160</x> <y>80</y> <width>481</width> <height>291</height> </rect> </property> </widget> </widget> <customwidgets> <customwidget> <class>QChartView</class> <extends>QGraphicsView</extends> <header>qcharts.h</header> </customwidget> </customwidgets> <resources/> <connections/> </ui>mainwindow.ui:
<?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>MainWindow</class> <widget class="QMainWindow" name="MainWindow"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>800</width> <height>600</height> </rect> </property> <property name="windowTitle"> <string>MainWindow</string> </property> <widget class="QWidget" name="centralwidget"> <widget class="QPushButton" name="pushButton"> <property name="geometry"> <rect> <x>250</x> <y>200</y> <width>231</width> <height>29</height> </rect> </property> <property name="text"> <string>Open Dialog Window</string> </property> </widget> </widget> <widget class="QMenuBar" name="menubar"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>800</width> <height>26</height> </rect> </property> </widget> <widget class="QStatusBar" name="statusbar"/> </widget> <resources/> <connections/> </ui> -
I'm using Qt C++ 6.6.1 and Qt Creator 12.0.2 on Windows 11 for a desktop application. I have a QChartView object in a modal Dialog window for displaying line graphs. The rubber band feature of QChartView allows me to click-and-drag the rubber band to zoom-in on areas of the graph. I also want to be able to <left click> in the graph and execute some application specific code (like display the corresponding value). I have an eventFilter for the Dialog and the 'MousePressEvent' does occur, unless the rubber band is enabled. If the rubber band is enabled then the 'MousePressEvent' does not occur in the eventFilter. This may be consistent with the Qt documentation for 'QChartView::mousePressEvent' which states, "If the left mouse button is pressed and the rubber band is enabled, the event 'event' is accepted ..." Since it 'accepted' the mouse event, that may explain why the eventFilter does not see 'MousePressEvent'.
The rubber band is enabled by the following line of code in the Dialog constructor:
ui->graphicsView->setRubberBand(QChartView::RectangleRubberBand);How do I enable/allow MousePressEvent to reach the eventFilter and have the rubber band enabled?
Here is the code that demonstrates the issue:
In the *.pro file I added 'charts' as follows:QT += core gui chartsmainwindow.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(); private slots: void on_pushButton_clicked(); private: Ui::MainWindow *ui; }; #endif // MAINWINDOW_Hdialog.h:
#ifndef DIALOG_H #define DIALOG_H #include <QChart> #include <QDialog> namespace Ui { class Dialog; } class Dialog : public QDialog { Q_OBJECT public: explicit Dialog(QWidget *parent = nullptr); ~Dialog(); protected: bool eventFilter(QObject *object, QEvent *event) override; private slots: private: Ui::Dialog *ui; }; #endif // DIALOG_Hmain.cpp:
#include "mainwindow.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }mainwindow.cpp
#include "mainwindow.h" #include "ui_mainwindow.h" #include "dialog.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_pushButton_clicked() { Dialog myDialog; myDialog.setModal(true); myDialog.exec(); }diaglog.cpp:
#include "dialog.h" #include "ui_dialog.h" Dialog::Dialog(QWidget *parent) : QDialog(parent) , ui(new Ui::Dialog) { ui->setupUi(this); /***************************************************** * The following line 'setRubberBand' prevents a 'MouseButtonPress' event * from reaching Dialog::eventFilter below. The Qt documentation for * QChartView states, "If the left mouse button is pressed and the rubber * band is enabled, the event 'event' is accepted and the rubber band is * displayed on the screen." ****************************************************/ ui->graphicsView->setRubberBand(QChartView::RectangleRubberBand); ui->graphicsView->installEventFilter(this); } Dialog::~Dialog() { delete ui; } bool Dialog::eventFilter(QObject *object, QEvent *event) { if (event->type() == QEvent::MouseButtonPress) { qDebug("In Dialog:eventFilter - QEvent::MouseButtonPress, objectName = %s", qPrintable(object->objectName())); /* I will add more application software here. */ } // standard event processing return QObject::eventFilter(object, event); }dialog.ui:
<?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>Dialog</class> <widget class="QDialog" name="Dialog"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>822</width> <height>478</height> </rect> </property> <property name="windowTitle"> <string>Dialog</string> </property> <widget class="QChartView" name="graphicsView"> <property name="geometry"> <rect> <x>160</x> <y>80</y> <width>481</width> <height>291</height> </rect> </property> </widget> </widget> <customwidgets> <customwidget> <class>QChartView</class> <extends>QGraphicsView</extends> <header>qcharts.h</header> </customwidget> </customwidgets> <resources/> <connections/> </ui>mainwindow.ui:
<?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>MainWindow</class> <widget class="QMainWindow" name="MainWindow"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>800</width> <height>600</height> </rect> </property> <property name="windowTitle"> <string>MainWindow</string> </property> <widget class="QWidget" name="centralwidget"> <widget class="QPushButton" name="pushButton"> <property name="geometry"> <rect> <x>250</x> <y>200</y> <width>231</width> <height>29</height> </rect> </property> <property name="text"> <string>Open Dialog Window</string> </property> </widget> </widget> <widget class="QMenuBar" name="menubar"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>800</width> <height>26</height> </rect> </property> </widget> <widget class="QStatusBar" name="statusbar"/> </widget> <resources/> <connections/> </ui>@EricR Problem Solved
Need to call the following:ui->graphicsView->setRubberBand(QChartView::RectangleRubberBand | QChartView::ClickThroughRubberBand);For unknown reason, the compiler (Desktop Qt 6.6.1 MinGW 64-bit) does not like the previous line of code; error message:
error: invalid user-defined conversion from 'int' to 'const RubberBands&Qt ClickThroughRubberBand documentation states: "An option on the above rubber band choices that allows left clicks to be passed on to chart items if those chart items accept clicks. To select this, OR it with one of the rubber band selection modes. since qt version 6.2."
enum RubberBand { NoRubberBand = 0x0, VerticalRubberBand = 0x1, HorizontalRubberBand = 0x2, RectangleRubberBand = 0x3, ClickThroughRubberBand = 0x80 };So I looked in QChartView.h and found the above definitions for ClickThroughRubberBand (0x80) and RectangleRubberBand (0x03) and ORed them together for 0x83.
ui->graphicsView->setRubberBand((QChartView::RubberBand)0x83);Now it works. Problem solved.
-
E EricR has marked this topic as solved on