QEvent
学习一个概念大致 步骤应该是:
- 1.从这个概念是什么
- 2.然后指着一个东西问 这东西是 这个概念吗? 为什么是为什么不是?
- 3.然后拿着东西去用
- 用的 步骤 或者顺序
- 用的时候注意的坑
- 4.然后不断地去深入了解,大致进入迭代,然后回到步骤1的过程
1. Qt的事件 是什么?
Qt事件将windows的消息 封装 成了事件
2. 为什么是? (特征)
- Qt事件是一个QEvent对象
- 描述程序内部或外部发生的 动作
- 任何QObject对象都有具备事件处理能力
2.1 QEvent 与 signal-slot 区别
- 信号的触发不会对程序行为造成影响
- 重写事件处理函数可能改变程序行为
- 事件由QObject对象进行处理
- 信号是主动产生的
- 信号则是QObject对象触发
- 一般,信号在具体的时间处理函数 中产生
3. 使用的大致步骤
3.1 大致原理步骤 (通用~)
- 在自己的类中重新实现event
- 根据event类型判断 自己想修改的事件
- 然后去做相应的事情
//上述步骤转成差不多的伪码
// 源码中的 event:virtual bool event(QEvent *); ----我在QObject类中找到的
bool event(QEvent * e)
{
if (e->type() == (自己想要的类型))
{
// 处理的代码
}
return QWidget::event(e);
}
//这里的QWidget 是因为 我写的继承自QWidget
// 至于为什么要返回QEvent,是因为其他的事件处理,父类里面已经有很多了
3.1.1 使用中对于当前事件的处理
处理的代码写完之后,我们可以将这个事件 进行忽略 或者 继续传递下去
inline void accept() { m_accept = true; }
inline void ignore() { m_accept = false; }
//套入上面框架
bool event(QEvent * e)
{
if (e->type() == (自己想要的类型))
{
//
e->ignore();
}
else
{
return QWidget::event(e);
}
}
3.1 事件处理顺序
3.1.1一般 组件事件处理与信号 顺序
- user做出行为
- OS转化成 Message
- QApplication 封装 Message 成 QEvent
- QApplication 发送 QEvent
- 相应组件 处理 QEvent ,发送相应signal
- QObject Slot
3.1.2父子组件一般顺序
- OS转化成 Message
- QApplication 封装 Message 成 QEvent
- QApplication 发送 QEvent
- Child QWidget 处理 QEvent
使用 事件过滤器 改变处理顺序
类似于家长先看看是不是给小孩儿买东西,再买完给小孩
- QApplication 封装 Message 成 QEvent
- QApplication 发送 QEvent
- 过滤器对象 处理并决定 是否继续 发送
- 如果决定发送 则 相应组件接收
TestEvent::TestEvent(QWidget *parent, Qt::WFlags flags)
: QWidget(parent, flags)
, m_testLineEdit(this)
{
m_testLineEdit.installEventFilter(this);
}
bool TestEvent::eventFilter(QObject * obj, QEvent * e)
{
// false 表示未处理, 继续传递下去, true表示 已处理
bool ret = true;
if ( obj == &m_testLineEdit && e->type() == QEvent::KeyPress)
{
qDebug() << "Widget::eventFilter";
ret = false;
}
else
{
ret = QWidget::eventFilter(obj, e);
}
// return __super::eventFilter(obj, e);
return ret;
}
其他使用注意的地方
一个组件显示的事件顺序
Polish = 75, // widget is polished
Move = 13, // move widget
Resize = 14, // resize widget
Show = 17, // widget is shown
ShowToParent = 26, // widget is shown to parent
WindowActivate = 24, // window was activated
FocusIn = 8, // keyboard focus received
PolishRequest = 74, // widget should be polished
MetaCall = 43, // meta call event
Paint = 12, // paint widget
上述值得我们注意的几个顺序:
Move = 13, // move widget
Resize = 14, // resize widget
Show = 17, // widget is shown
ShowToParent = 26, // widget is shown to parent
Paint = 12, // paint widget
- 为什么要注意显示顺序?
- 有些操作是在显示后做的,例如:某些组件的显示隐藏,需要记录之前的状态,这时候在show之后做,就行了
- 有些数据,我们有时候可以偷懒放在paint里面,但是有时候只是执行一次,所以可以放在show里