概述
概述:
事件(event)是由系统或者 Qt 本身在不同的时刻发出的。当用户按下鼠标、敲下键盘,或者是窗口需要重新绘制的时候,都会发出一个相应的事件。一些事件在对用户操作做出响应时发出,如 键盘事件等;另一些事件则是由系统自动发出,如计时器事件。有一点"软中断"的意味。
事件和信号槽:
在 Qt 中,事件的概念似乎同信号槽类似。的确如此,一般来说,使用 Qt 组件时,我们并不会把主要精力放在事件上。因为在 Qt 中,我们关心的更多的是事件关联的一个信号。比如,对于 QPushButton
的鼠标点击,我们不需要关心这个鼠标点击事件,而是关心它的 clicked
() 信号的发出。 但是,Qt 中的事件和信号槽却并不是可以相互替代的。
事件和信号槽的区别:
信号由具体的对象发出,然后会马上交给由 connect
() 函数连接的槽进行处理;
而对于事件,Qt 使用一个事件队列对所有发出的事件进行维 护,当新的事件产生时,会被追加到事件队列的尾部。前一个事件完成后,取出后面的事件进行处理。但是,必要的时候,Qt 的事件也可以不进入事件队列,而是直接处理。
所以说,信号一旦发出,对应 的槽函数一定会被执行。但是,事件则可以使用“事件过滤器”进行过滤,对于有些事件进行额外的处理,另外的事件则不关心。总的来说,如果我们使用使 组件,我们关心的是信号槽;如果我们自 定义定 组件,我们关心的是事件。
事件的处理过程:
当事件发生时,Qt 将创建一个事件对象。Qt 中所有事件类都继承于 QEvent
。在事件对象创建完毕后,Qt 将这个事件对象传递给 QObject
的 event
() 函数。event
() 函数并不直接处理事件,而是按照事件对象的类型分派给特定的事件处理函数(event handler)(使用switch…case…)。 在所有组件的父类 QWidget 中,定义了很多事件处理的回调函数,如 keyPressEvent()、keyReleaseEvent()、mouseDoubleClickEvent()、mouseMoveEvent ()、mousePressEvent()、 mouseReleaseEvent() 等。这些函数都是 protected virtual
的,也就是说,我们可以在子类中重写这些函数。
鼠标事件函数重写举例:
使用Qlabel
类派生一个子类Mylabel
显示鼠标状态:
/*t头文件声明要重写的函数*/
protected:
/*鼠标点击事件*/
void mousePressEvent(QMouseEvent *ev);/*不能改变任何东西在Qwidget*/
/*鼠标释放*/
void mouseReleaseEvent(QMouseEvent *ev) ;
/*鼠标移动*/
void mouseMoveEvent(QMouseEvent *ev) ;
/*进入窗口区域*/
void enterEvent(QEvent *);
/*离开窗口区域*/
void leaveEvent(QEvent *);
/*源文件实现重写函数*/
/*判断按下的是键的位置*/
void mylabel::mousePressEvent(QMouseEvent *ev)
{
/*获取鼠标目前坐标*/
int i = ev->x();
int j = ev->y();
if(ev->button() == Qt::LeftButton)
{
/*按下的是鼠标左键*/
}else if(ev->button() == Qt::RightButton)
{
/*按下的是鼠标右键*/
}else if(ev->button() == Qt::MidButton)
{
/*按下的是中间按键*/
}
QString text = QString("<center><h1>Mouse Press : (%1 , %2)</h1></center>")
.arg(i).arg(j);
this->setText(text);
}
/*鼠标释放的时候显示坐标*/
void mylabel::mouseReleaseEvent(QMouseEvent *ev)
{
/*加粗居中显示鼠标坐标*/
QString text = QString("<center><h1>Mouse Release : (%1 , %2)</h1></center>")
.arg(ev->x()).arg(ev->y());
/*在标签上面显示坐标*/
this->setText(text);
}
/*鼠标移动的时候显示坐标*/
void mylabel::mouseMoveEvent(QMouseEvent *ev)
{
QString text = QString("<center><h1>Mouse Move : (%1 , %2)</h1></center>")
.arg(ev->x()).arg(ev->y());
this->setText(text);
}
/*鼠标进入窗口事件*/
void mylabel::enterEvent(QEvent *)
{
QString text = QString("<center><h1>Mouse Enter!</h1></center>");
this->setText(text);
}
/*鼠标离开窗口事件*/
void mylabel::leaveEvent(QEvent *)
{
QString text = QString("<center><h1>Mouse Leave!</h1></center>");
this->setText(text);
}
注:如果不把移动事件坐标显示的话是不容易看到进入窗口和离开窗口的现象的。并且对于鼠标移动来说如果不开启鼠标追踪,则只有点击鼠标之后才能显示移动坐标
如下:
this->setMouseTracking(true);//追踪鼠标
效果如下:
定时器事件重写
还有一些本身发出的时间比如定时器时间如下:
/*声明要重写的定时器时间函数*/
void timerEvent(QTimerEvent *e);
/*初始化定时时间*/
id = this->startTimer(1000);//ms级别
/*重写时间函数*/
void Widget::timerEvent(QTimerEvent *e)
{
if(e->timerId() == this->id)
{
static int sec = 0;
ui->label->setText(QString("<center><h1>Timer : %1</h1></center>").arg(sec++));
if(8 == sec)
{
sec = 0;
/*关闭对应ID的定时器*/
// this->killTimer(this->id);
}
}
}
最后
以上就是落寞耳机为你收集整理的Qt中的事件(一)的全部内容,希望文章能够帮你解决Qt中的事件(一)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复