赞
踩
操作系统发送的消息如何转变为 Qt 信号?
Qt 事件是一个 QEvent 对象
Qt 事件用于描述程序内部或外部发生的动作
任意的 QObject 对象都具有事件处理的能力
1. Qt 事件产生后立即分发到 QWidget 对象
2. QWidget 中的 event(QEvent*) 进行事件处理
3. event() 根据事件的类型调用不同的事件处理函数
4. 在事件处理函数中发送 Qt 中预定义的信号
5. 调用信号关联的槽函数
1. 接收到鼠标事件
2. 调用 event(QEvent*) 函数
3. 调用 mouseReleaseEvent(QMouseEvent*) 成员函数
4. 调用 click() 成员函数
5. 触发信号 SIGNAL(clicked())
QmyPushButton.h
- #ifndef QMYPUSHBUTTON_H
- #define QMYPUSHBUTTON_H
-
- #include <QWidget>
- #include <QPushButton>
-
- typedef void(QButtonListener)(QWidget *, QMouseEvent *);
-
- class QmyPushButton : public QPushButton
- {
- Q_OBJECT
- protected:
- QButtonListener* m_listen;
-
- /* 子类重写父类的虚函数 */
- void mouseReleaseEvent(QMouseEvent *e);
- public:
- explicit QmyPushButton(QWidget *parent = nullptr, QButtonListener *listen = nullptr);
-
- signals:
-
- };
-
- #endif // QMYPUSHBUTTON_H
QmyPushButton.cpp
- #include "QmyPushButton.h"
- #include <QMouseEvent>
- QmyPushButton::QmyPushButton(QWidget *parent, QButtonListener *listen) : QPushButton(parent)
- {
- m_listen = listen;
- }
-
- void QmyPushButton::mouseReleaseEvent(QMouseEvent *e)
- {
- if(m_listen != NULL)
- {
- m_listen(this, e);
-
- /* 标记当前的事件已经被处理 */
- e->accept();
-
- /* 设置按钮弹起 */
- setDown(false);
- }
- else
- {
- QPushButton::mouseReleaseEvent(e);
- }
- }
Widget.h
- #ifndef WIDGET_H
- #define WIDGET_H
-
- #include <QWidget>
- #include <QPushButton>
- #include "QmyPushButton.h"
-
- class Widget : public QWidget
- {
- Q_OBJECT
- private slots:
- void buttonClicked();
- private:
- QmyPushButton myButton;
-
- public:
- Widget(QWidget *parent = nullptr);
- ~Widget();
- };
- #endif // WIDGET_H
Widget.cpp
- #include "Widget.h"
- #include <QPushButton>
- #include <QDebug>
- #include <QMouseEvent>
-
- void func(QWidget *w, QMouseEvent *e)
- {
- qDebug() << "void func(QWidget *w, QMouseEvent *e)";
- }
-
- Widget::Widget(QWidget *parent)
- : QWidget(parent), myButton(this, func)
- {
- myButton.setText("myButton");
- connect(&myButton, &QPushButton::clicked, this, &Widget::buttonClicked);
- }
-
- void Widget::buttonClicked()
- {
- qDebug() << "void Widget::buttonClicked()";
- }
-
- Widget::~Widget()
- {
- }
当 QmyPushButton 被按下后松开后,会调用其 mouseReleaseEvent 函数。
事件由具体对象进行处理
信号由具体对象主动产生
改写事件处理函数可能导致程序行为发生改变
信号是否存在对应的槽函数不会改变程序行为
一般而言,信号在具体的事件处理函数中产生
事件被组件对象处理后可能传递到其父组件对象
void ignore();
void accept();
bool isAccepted();
MyLineEdit.h
- #ifndef MYLINEEDIT_H
- #define MYLINEEDIT_H
-
- #include <QLineEdit>
-
- class MyLineEdit : public QLineEdit
- {
- Q_OBJECT
- protected:
- bool event(QEvent* e);
- void keyPressEvent(QKeyEvent* e);
-
- public:
- explicit MyLineEdit(QWidget* parent = nullptr);
-
- signals:
-
- };
-
- #endif // MYLINEEDIT_H
MyLineEdit.cpp
- #include "MyLineEdit.h"
- #include <QDebug>
- #include <QEvent>
- #include <QKeyEvent>
-
- MyLineEdit::MyLineEdit(QWidget *parent) : QLineEdit(parent)
- {
-
- }
-
- bool MyLineEdit::event(QEvent *e)
- {
- if(e->type() == QEvent::KeyPress)
- {
- qDebug() << "MyLineEdit::event";
- }
-
- return QLineEdit::event(e);
- }
-
- void MyLineEdit::keyPressEvent(QKeyEvent *e)
- {
- qDebug() << "MyLineEdit::keyPressEvent";
-
- QLineEdit::keyPressEvent(e);
-
- //e->ignore();
- }
Widget.h
- #ifndef WIDGET_H
- #define WIDGET_H
-
- #include <QWidget>
- #include <MyLineEdit.h>
- #include <QEvent>
-
- class Widget : public QWidget
- {
- Q_OBJECT
- private:
- MyLineEdit myLineEdit;
-
- protected:
- bool event(QEvent *e);
- void keyPressEvent(QKeyEvent *e);
-
- public:
- Widget(QWidget *parent = nullptr);
- ~Widget();
- };
- #endif // WIDGET_H
Widget.cpp
- #include "Widget.h"
- #include <QDebug>
- #include <QEvent>
- #include <QKeyEvent>
-
- Widget::Widget(QWidget* parent)
- : QWidget(parent), myLineEdit(this)
- {
-
- }
-
- bool Widget::event(QEvent* e)
- {
- if(e->type() == QEvent::KeyPress)
- {
- qDebug() << "Widget::event";
- }
-
- return QWidget::event(e);
- }
-
- void Widget::keyPressEvent(QKeyEvent* e)
- {
- qDebug() << "Widget::keyPressEvent";
-
- QWidget::keyPressEvent(e);
- }
-
- Widget::~Widget()
- {
- }
在单行文本框输入字符时,首先会调用 Event 函数,接下来 Event 函数会调用 keyPressEvent 函数。
事件过滤器可以对其它组件接收到的事件进行监控
任意的 QObject 对象都可以作为事件过滤器使用
事件过滤器需要重写 eventFilter() 函数
组件通过 installEventFilter() 函数安装事件过滤器
Widget.cpp
- #include "Widget.h"
- #include <QDebug>
- #include <QEvent>
- #include <QKeyEvent>
-
- Widget::Widget(QWidget* parent)
- : QWidget(parent), myLineEdit(this)
- {
- myLineEdit.installEventFilter(this);
- }
-
- bool Widget::eventFilter(QObject* obj, QEvent* e)
- {
- bool ret = true;
- if((obj == &myLineEdit) && (e->type() == QEvent::KeyPress))
- {
- qDebug() << "Widget::eventFilter";
-
- QKeyEvent* key = dynamic_cast<QKeyEvent*>(e);
-
- switch(key->key())
- {
- case Qt::Key_0:
- case Qt::Key_1:
- case Qt::Key_2:
- case Qt::Key_3:
- case Qt::Key_4:
- case Qt::Key_5:
- case Qt::Key_6:
- case Qt::Key_7:
- case Qt::Key_8:
- case Qt::Key_9:
- ret = false;
- break;
- default:
- break;
- }
- }
- else
- {
- ret = QWidget::eventFilter(obj, e);
- }
-
- return ret;
- }
-
- bool Widget::event(QEvent* e)
- {
- if(e->type() == QEvent::KeyPress)
- {
- qDebug() << "Widget::event";
- }
-
- return QWidget::event(e);
- }
-
- void Widget::keyPressEvent(QKeyEvent* e)
- {
- qDebug() << "Widget::keyPressEvent";
-
- QWidget::keyPressEvent(e);
- }
-
- Widget::~Widget()
- {
- }
-
在使用事件过滤器之前,需要事件过滤的对应组件需要安装事件过滤器;然后重写 eventFilter 函数,eventFilter 返回 true 表示将当前事件过滤;返回 false 表示这个事件会正常传递到目标组件。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。