事件机制
当 obj 收到任何事件时,这些事件将首先被传递给 this(MyWidget)的 eventFilter 方法。
例如 btn->installEventFilter(this);
返回值:
if you want to filter the event out, i.e. stop it being handled further, return true; otherwise return false.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 class MyWidget : public QWidget{ public : explicit MyWidget () { this ->installEventFilter (this ); } protected : bool eventFilter (QObject *obj, QEvent *event) override { if (event->type () == QEvent::MouseButtonPress) { qDebug () << "eventfilter" ; return true ; } return QWidget::eventFilter (obj, event); } bool event (QEvent *eve) override { if (eve->type () == QEvent::MouseButtonPress) qDebug () << "Event()" ; return QWidget::event (eve); } }; int main (int argc, char *argv[]) { QApplication a (argc, argv) ; auto *w = new MyWidget (); w->setGeometry (200 , 200 , 1000 , 800 ); w->show (); return a.exec (); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 QPushButton { min-height : 20px ; max-height : 60px ; margin : 5px ; padding : 20px ; margin :20px ; font-size : 20px ; color : white; background-color : black; border : 1px solid black; border-radius :10px ; } QPushButton:pressed{ color :green; padding :20px ; margin :15px ; border-radius :10px ; }
事件传播 当MainWindow中的Gbutton发生mousePressEvent 事件后,QPushButton默认实现不会传播到MainWindow的mousePressEvent,只有调用event->ignore();并且不能再调用QPushButton::mousePressEvent();否则仍然会accept();
那么我认为一切event先考虑设置成accept也就是不会传播,再考虑交给其他组件处理,这样保证不会出太大问题
才会传播到父组件,默认也就是event->accept();等价于 setAccepted(true)
通过event()函数编写处理代码是要通过返回值告诉调用者是否被接收,accept() or ignore() 没有意义
Calling accept () or ignore () on an event from event() is pointless
void GButton::mousePressEvent(QMouseEvent *e) { e->ignore(); INFO(“[button]clicked”); QPushButton::mousePressEvent(e); 如果调用基类的处理函数,那么会默认accept }
Qt is designed in such a way that you normally never need to call them. The default value is “accept”, and the default event handler implementations in QWidget call ignore()
Qt 默认是accept也就是不会传播,但是QWidget的实现是ignore(),也就是会传播
Another Look at Events
qevent.html#ignore
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 namespace Ui {class MainWindow ;} QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public : MainWindow (QWidget *parent = nullptr ); ~MainWindow (); protected : void mouseMoveEvent (QMouseEvent *event) override ; bool event (QEvent *e) override ; void mousePressEvent (QMouseEvent *) override ; private : bool isMenuVisible; void initMenu () ; Ui::MainWindow *ui; }; #include "mainwindow.h" #include "gbutton.h" #include "logger.h" #include "ui_mainwindow.h" #include <QMetaEnum> #include <QMetaObject> #include <QMouseEvent> #include <QTimer> MainWindow::MainWindow (QWidget *parent) : QMainWindow (parent), ui (new Ui::MainWindow) { ui->setupUi (this ); auto btn = new GButton (); btn->setParent (this ); btn->move (geometry ().center () - btn->geometry ().center ()); INFO (__PRETTY_FUNCTION__); initMenu (); setMouseTracking (true ); } MainWindow::~MainWindow () { delete ui; } void MainWindow::mouseMoveEvent (QMouseEvent *event) { QMainWindow::mouseMoveEvent (event); } bool MainWindow::event (QEvent *e) { return QMainWindow::event (e); } void MainWindow::mousePressEvent (QMouseEvent *event) { if (event->button () == Qt::LeftButton) { qDebug () << "[mainwindow] left clicked" ; } return QMainWindow::mousePressEvent (event); } void MainWindow::initMenu () { connect (ui->file_open_action, &QAction::triggered, this , [](bool check) { INFO ("file_open_action triggered " << (check ? "checked" : "unchecked" )); }); connect (ui->backup_action, &QAction::triggered, this , [](bool check) { INFO ("backup_action triggered" << (check ? "checked" : "unchecked" )); }); } #include <QPushButton> class GButton : public QPushButton {public : explicit GButton () ; protected : bool event (QEvent *e) override ; void mousePressEvent (QMouseEvent *e) override ; }; #include "gbutton.h" #include "logger.h" #include <QMouseEvent> GButton::GButton () { setFixedSize ({300 , 100 }); setText ("button clicked" ); } bool GButton::event (QEvent *e) { return QPushButton::event (e); } void GButton::mousePressEvent (QMouseEvent *e) { e->ignore (); INFO ("[button]clicked" ); }