QT中所有的事件都继承自QEvent,每个 widget 都有一个总的事件处理函数,通过覆写这个基类中虚函数来处理某个事件消息:
bool QWidget::event(QEvent *event);
{
if( event->type() == QEvent::MouseButtonPress )
{
qDebug()<<__FUNCTION__<<endl;
event->accept(); //通常默认该消息 acccept
}
return true; //返回 true && accept() 时表示该消息不往父窗口传递
}
通常情况下是覆写一个具体的事件处理程序来实现某些功能,常用的事件程序如下:
//鼠标事件 event->button() 判断是哪个键
void QWidget::mousePressEvent(QMouseEvent* event);
void QWidget::mouseReleaseEvent(QMouseEvent *event) ;
void QWidget::mouseDoubleClickEvent(QMouseEvent *event) ;
void QWidget::mouseMoveEvent(QMouseEvent *event) ; //通常与 void QWidget::setMouseTracking(bool enable)一起用
void QWidget::wheelEvent(QWheelEvent *event);
void QWidget::enterEvent(QEvent *event);
void QWidget::leaveEvent(QEvent *event);
//键盘事件 event->key() 判断是常规键 ABC..., event->modifiers() 判断组合键,如 Ctrl, Alt
void QWidget::keyPressEvent(QKeyEvent *event);
void QWidget::keyReleaseEvent(QKeyEvent *event);
//Qt中指定置顶窗口接受键盘事件,可通过 setFocus() 来切换其他窗口
*注:经过代码测试发现只要覆写了 bool QWidget::event(QEvent event)后,widget就不再处理以上这些具体的事件
以上这些事件都只能子自己类中处理,比如一个widget中的 button被点击后,默认只有该 button 的鼠标点击事件被触发。
如果需要某个子窗口不被触发某些事件,则需要对它安装事件过滤器。
void QObject::installEventFilter(QObject *filter);
//该函数的调用者为被监控者,filter 为监控者
//如下所示,所有调用 installEventFilter并指定Widget为监控者的object将不会再收到鼠标按下事件
bool Widget::eventFilter(QObject *watched, QEvent *event)
{
if(event‐>type() == QEvent::MouseButtonPress)
{
return true; //过滤掉点击事件,如return则默认返回 true
}
}
QT中的绘画事件
桌面中的所有窗口都是绘制处理,当窗口的形态发生变化时,就会触发 paint 事件,在Qt中称为 QPaintEvent 对应的函数为:
void QWidget::paintEvent(QPaintEvent *event);
可以将绘画分为画笔(QPainter)和画布(QPaintDevice), QPainter有Qpen和QBrush两种(感觉就是填充与否的区别), QPaintDevice有 QPixmap、QPicture、QImage、QWidget。当画布为QWidget的派生类对象时, QPainter只能在QWidget的painteEvent事件处理函数中使用,因为当窗口的形态发生变化时painteEvent会被调用, 其他函数内使用则可能不生效或者被覆盖。也因为这个特点,当我们设置了QPainter的某些属性后,Widget的效果可能没有大声变化,所以需要如下触发函数:
//加入到消息队列中,由消息循环来调度,有时多个update()会合并成一个重绘事件
void QWidget::update();
//当即重绘,并且可以指定重绘区域
void QWidget::repaint();