Qt——事件
1.常见事件 【1】鼠标事件 (1)坐标 x(),y(), 相对windows globalX() globalY() (2)获得点击 button() 【2】键盘事件 【3】定时器事件 timerID1 = startTimer(time) { if (e->timerId() == timerID1) { } } ? 2. 事件的接受和忽略 示例: 同时设置 mousePressEvent() 和 connect(,clicked,) 当事件发生后, mousePressEvent() 执行,而 connect 没触发 原因: 事件触发后传递给 mousePressEvent,mousePressEvent接受了事件,所以事件没有继续向下传,就没有发出 clicked 信号。 如果希望触发 connect,需要在 mousePressEvent中调用父类的mousePressEvent。 结论: 信号和事件的关系 信号有两种来源:事件生成信号、手动生成信号(emit signal()) 如果自定义控件后,重写事件虚函数,那么会导致信号无法生成,需要再调用基类事件函数以生成信号。 事件的接受和忽略 accept() ignore() 谁的事件产生,谁先得到事件,传递方向是向父控件(不是基类) 事件选择 accpet() ,事件不会传向父控件 事件选择 ignore() , 事件会传递给父控件 默认情况: 实验: myFrame -> QFrame mousePressEvent 子控件 myFrame 父控件继承于 QWidget 结果: 默认情况,没有传递 accept,没有传递 ignore 传递给父控件 再次总结事件和信号 事件由 exec() 监听,谁的事件触发,执行谁的事件处理函数 信号由 emit 以广播形式发出, connect 会监听信号 借助事件处理函数执行 emit signal,实现事件触发信号 3. 事件的过滤 (1)事件的处理流程 不考虑事件过滤器:QApplication::exec()循环监听事件,当事件触发,Qt构造事件对象(所有事件对象都继承与 QEvent),事件对象传递给触发事件的 QObject::event() 函数, event() 不直接处理事件,而是进行事件的转发,事件将由对应的 event handler 处理。 event() bool QObject::event(QEvent *e); 返回值:? true 表示,Qt会认为事件已经被正确处理,不会再将事件传递给父控件对象,而是处理事件队列中的其他事件。 false,事件未被处理,将传递给其他对象。 event()中使用 accpet() 和 ignore 是没有的。 event()是 protect ,意味可以重写该虚函数,实现事件的过滤, 如下,就只关注键入 tab 的事件 bool CustomTextEdit::event(QEvent *e) { if (e->type() == QEvent::KeyPress) { QKeyEvent *keyEvent = static_cast<QKeyEvent *>(e); if (keyEvent->key() == Qt::Key_Tab) { qDebug() << "You press tab."; return true; } } return false; } event的其他用处 如下为 Qt5 的 event() 源码, 可以看出,可以只重写 event() ,就可以完成所有 event handler 的处理。 //!!! Qt5 bool QObject::event(QEvent *e) { switch (e->type()) { case QEvent::Timer: timerEvent((QTimerEvent*)e); break; case QEvent::ChildAdded: case QEvent::ChildPolished: case QEvent::ChildRemoved: childEvent((QChildEvent*)e); break; // ... default: if (e->type() >= QEvent::User) { customEvent(e); break; } return false; } return true; } 总结: event() : 作用:事件的分发 返回值:true ,事件成功分发,不会再传递,false,事件会被传递; accept ignore 无用 用法: 事件过滤,只向下分发需要的事件,其他的则传递给别的对象(即返回 false) event handler的集中处理。 事件过滤器 安装过滤器后,事件的处理流程: exec()监听事件,事件触发,Qt构造事件对象,经过事件过滤器,通过过滤再到 event(),event()分发给event handler。 事件过滤器的好处,可以集中处理控件的事件过滤,避免写多个 event() virtual bool QObject::eventFilter ( QObject * watched,QEvent * event ); 返回值: true 事件被过滤,事件不会传递给目标对象(watched),false事件会传递给目标对象(watched) 调用时机:事件传递给目标对象前 使用方法: 设置一个(生命周期)全局的事件过滤器,一般用 主控件,重写 eventFileter。 需要过滤的对象安装 过滤器 过滤器安装:
void QObject::installEventFilter ( QObject * filterObj )
过滤器移除 QObject::removeEventFilter() 过滤器的执行顺序:如果一个对象安装了多个过滤器,那么后安装先执行。 其他: 过滤器和被过滤对象必须同个线程,否则无用。 过滤器会降低执行速度,慎用 class MainWindow : public QMainWindow { public: MainWindow(); protected: bool eventFilter(QObject *obj,QEvent *event); private: QTextEdit *textEdit; }; MainWindow::MainWindow() { textEdit = new QTextEdit; setCentralWidget(textEdit); textEdit->installEventFilter(this); } bool MainWindow::eventFilter(QObject *obj,QEvent *event) { if (obj == textEdit) { if (event->type() == QEvent::KeyPress) { QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event); qDebug() << "Ate key press" << keyEvent->key(); return true; } else { return false; } } else { // pass the event on to the parent class return QMainWindow::eventFilter(obj,event); } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- win10快捷键大全 win10常用快捷键
- Windows – 如何使用指定的程序从命令行打开文件?
- Tips To Pass Microsoft Azure AZ-301 Exam
- 尝试在Windows 7上安装MinGW和Tk for Perl
- Windows – 如何阻止Microsoft DNS报告版本号?
- windows-phone-8 – WP8实时图块中的计数是否有最大字符限制
- microsoft-office-365 – 在Office 365中验证后,Microsoft
- windows-server-2003 – 什么是QSignoff?
- microsoft-edge – Windows 10 Edge浏览器中的HTML注释解析
- 在Windows 10上安装流星