Qt学习之路(19): 事件(event)

前面说了几个标准对话框,下面不打算继续说明一些组件的使用,由于这些使用很难讲完,不少东西都是与实际应用相关的。实际应用的复杂性决定了咱们根本不可能把全部组件的全部使用方法都说明白。此次来讲说Qt相对高级一点的特性:事件。
 
事件(event)是有系统或者Qt自己在不一样的时刻发出的。当用户按下鼠标,敲下键盘,或者是窗口须要从新绘制的时候,都会发出一个相应的事件。一些事件是在对用户操做作出响应的时候发出,如键盘事件等;另外一些事件则是由系统自动发出,如计时器事件。
 
通常来讲,使用Qt编程时,咱们并不会把主要精力放在事件上,由于在Qt中,须要咱们关心的事件总会发出一个信号。好比,咱们关心的是QPushButton的鼠标点击,但咱们不须要关心这个鼠标点击事件,而是关心它的clicked()信号。这与其余的一些框架不一样:在Swing中,你所要关心的是JButton的ActionListener这个点击事件。
 
Qt的事件很容易和信号槽混淆。这里简单的说明一下,signal由具体对象发出,而后会立刻交给由connect函数链接的slot进行处理;而对于事件,Qt使用一个事件队列对全部发出的事件进行维护,当新的事件产生时,会被追加到事件队列的尾部,前一个事件完成后,取出后面的事件进行处理。可是,必要的时候,Qt的事件也是能够不进入事件队列,而是直接处理的。而且,事件还可使用“事件过滤器”进行过滤。总的来讲,若是咱们 使用组件,咱们关心的是信号槽;若是咱们 自定义组件,咱们关心的是事件。由于咱们能够经过事件来改变组件的默认操做。好比,若是咱们要自定义一个QPushButton,那么咱们就须要重写它的鼠标点击事件和键盘处理事件,而且在恰当的时候发出clicked()信号。
 
还记得咱们在main函数里面建立了一个QApplication对象,而后调用了它的exec()函数吗?其实,这个函数就是开始Qt的事件循环。在执行exec()函数以后,程序将进入事件循环来监听应用程序的事件。当事件发生时,Qt将建立一个事件对象。Qt的全部事件都继承于QEvent类。在事件对象建立完毕后,Qt将这个事件对象传递给QObject的event()函数。event()函数并不直接处理事件,而是按照事件对象的类型分派给特定的事件处理函数(event handler)。关于这一点,咱们会在之后的章节中详细说明。
 
在全部组件的父类QWidget中,定义了不少事件处理函数,如keyPressEvent()、keyReleaseEvent()、mouseDoubleClickEvent()、mouseMoveEvent ()、 mousePressEvent()、mouseReleaseEvent()等。这些函数都是protected virtual的,也就是说,咱们应该在子类中重定义这些函数。下面来看一个例子。
 
#include <QApplication>
#include <QWidget>
#include <QLabel>
#include <QMouseEvent>

class EventLabel : public QLabel
{

protected:
         void mouseMoveEvent(QMouseEvent * event);
         void mousePressEvent(QMouseEvent * event);
         void mouseReleaseEvent(QMouseEvent * event);
};

void EventLabel::mouseMoveEvent(QMouseEvent * event)
{
         this->setText(QString( "<center><h1>Move: (%1, %2)</h1></center>")
                                                        .arg(QString::number( event->x()), QString::number( event->y())));
}

void EventLabel::mousePressEvent(QMouseEvent * event)
{
         this->setText(QString( "<center><h1>Press: (%1, %2)</h1></center>")
                                                        .arg(QString::number( event->x()), QString::number( event->y())));
}

void EventLabel::mouseReleaseEvent(QMouseEvent * event)
{
        QString msg;
        msg.sprintf( "<center><h1>Release: (%d, %d)</h1></center>",
                                 event->x(), event->y());
         this->setText(msg);
}

int main( int argc, char *argv[])
{
        QApplication app(argc, argv);
        EventLabel *label = new EventLabel;
        label->setWindowTitle( "MouseEvent Demo");
        label->resize(300, 200);
        label->show();
         return app.exec();
}
 
这里咱们继承了QLabel类,重写了mousePressEvent、mouseMoveEvent和MouseReleaseEvent三个函数。咱们并无添加什么功能,只是在鼠标按下(press)、鼠标移动(move)和鼠标释放(release)时把坐标显示在这个Label上面。注意咱们在mouseReleaseEvent函数里面有关QString的构造。咱们没有使用arg参数的方式,而是使用C语言风格的sprintf来构造QString对象,若是你对C语法很熟悉(估计不少C+++程序员都会比较熟悉的吧),那么就能够在Qt中试试熟悉的C格式化写法啦!
相关文章
相关标签/搜索