zoukankan      html  css  js  c++  java
  • 11事件处理器

    Qt消息机制和事件

    事件(event)是由系统或者 Qt 本身在不同的时刻发出的。当用户按下鼠标、敲下键盘,或者是窗口需要重新绘制的时候,都会发出一个相应的事件。一些事件在对用户操作做出响应时发出,如键盘事件等;另一些事件则是由系统自动发出,如计时器事件。

    在前面也曾经简单提到,Qt 程序需要在main()函数创建一个QApplication对象,然后调用它的exec()函数。这个函数就是开始 Qt 的事件循环。在执行exec()函数之后,程序将进入事件循环来监听应用程序的事件。当事件发生时,Qt 将创建一个事件对象。Qt 中所有事件类都继承于QEvent。在事件对象创建完毕后,Qt 将这个事件对象传递给QObject的event()函数。event()函数并不直接处理事件,而是按照事件对象的类型分派给特定的事件处理函数(event handler),关于这一点,会在后边详细说明。

    在所有组件的父类QWidget中,定义了很多事件处理的回调函数,如

      keyPressEvent()

      keyReleaseEvent()

      mouseDoubleClickEvent()

      mouseMoveEvent()

      mousePressEvent()

      mouseReleaseEvent() 等。

    头文件

    #include <QEvent>

    #include <QMouseEvent>

    #include <QKeyEvent>

    这些函数都是 protected virtual 的,也就是说,我们可以在子类中重新实现这些函数。下面来看一个例子:

    class Widget : public Qwidget

    {

    protected:

        //鼠标事件

        void mousePressEvent(QMouseEvent *ev);

        void mouseMoveEvent(QMouseEvent *ev);

        void mouseReleaseEvent(QMouseEvent *ev);

        //窗口事件

        void enterEvent(QEvent *e);

        void leaveEvent(QEvent *e);

        //键盘事件

        void keyPressEvent(QKeyEvent *e);

        void keyReleaseEvent(QKeyEvent *e);

    }

    void Widget::mousePressEvent(QMouseEvent *ev)

    {

         //判断鼠标左键、中、右键

        if(ev->button()==Qt::LeftButton)

        {

            qDebug()<<"LeftButton";

        }

        else if(ev->button()==Qt::MidButton)

        {

            qDebug()<<"MidButton";

        }

        else if(ev->button()==Qt::RightButton)

        {

            qDebug()<<"RightButton";

        }

        ui->label->setText(QString("MousePressedePoint:(%1,%2)").arg(ev->x()).arg(ev->y()));

    };

    void Widget::mouseMoveEvent(QMouseEvent *ev)

    {

        ui->label->setText(QString("<center><h1>Point:(%1,%2)</h1></center>").arg(ev->x()).arg(ev->y()));

    }

    void Widget::mouseReleaseEvent(QMouseEvent *ev)

    {

         ui->label->setText(QString("MouseReleasePoint:(%1,%2)").arg(ev->x()).arg(ev->y()));

    };

    void Widget::enterEvent(QEvent *e)

    {

        ui->label_2->setText("EnterWidget");

    }

    void Widget::leaveEvent(QEvent *e)

    {

        ui->label_2->setText("LeaveWidget");

    }

    void Widget::keyPressEvent(QKeyEvent *e)

    {

        qDebug()<<(char)e->key();

        if(e->key()==Qt::Key_A)

        {

            qDebug()<<"AAAA";

        }

    }

    void Widget::keyReleaseEvent(QKeyEvent *e)

    {

    }

      mousePressEvent()、mouseMoveEvent()和MouseReleaseEvent()三个函数。我们并没有添加什么功能,只是在鼠标按下(press)、鼠标移动(move)和鼠标释放(release)的时候,把当前鼠标的坐标值显示在这个Label上面。由于QLabel是支持 HTML 代码的,因此我们直接使用了 HTML 代码来格式化文字。

      QString的arg()函数可以自动替换掉QString中出现的占位符。其占位符以 % 开始,后面是占位符的位置,例如 %1,%2 这种。

    QString("[%1, %2]").arg(x).arg(y);

    语句将会使用x替换 %1,y替换 %2,因此,生成的QString为[x, y]。

    在mouseReleaseEvent()函数中,我们使用了另外一种QString的构造方法。我们使用类似 C 风格的格式化函数sprintf()来构造QString。

    为什么要点击鼠标之后才能在mouseMoveEvent()函数中显示鼠标坐标值?

    这是因为QWidget中有一个mouseTracking属性,该属性用于设置是否追踪鼠标。只有鼠标被追踪时,mouseMoveEvent()才会发出。如果mouseTracking是 false(默认即是),组件在至少一次鼠标点击之后,才能够被追踪,也就是能够发出mouseMoveEvent()事件。如果mouseTracking为 true,则mouseMoveEvent()直接可以被发出。

    知道了这一点,我们就可以在main()函数中添加如下代码:

    //鼠标跟踪

    this->setMouseTracking(true);

    在运行程序就没有这个问题了。

    定时器事件

    #include <QTimerEvent>

        //定时器

    void timerEvent(QTimerEvent *t);

    void Widget::timerEvent(QTimerEvent *t)

    {

        static int time1=0,time2=0;

        if(t->timerId()==timeID1)

        {

             ui->label_3->setText(QString("Timer1:%1").arg(time1++));

             //到10终止定时器

             if(time1==10)

             {

                 QObject::killTimer(timeID1);

             }

        }

        else if(t->timerId()==timeID2)

        {

             ui->label_4->setText(QString("Timer2:%1").arg(time2++));

        }

    }

    启动定时器

        //按时启动定时器

        timeID1=this->startTimer(1000); //1000毫秒

        timeID2=this->startTimer(500);

    启动定时器后,按毫秒数按时引发定时器事件,同时返回一个定时器ID,用于终止定时器使用。

    终止定时器

    QObject::killTimer(timeID1);

     

    源代码

    .h

    #include "widget.h"

    #include "ui_widget.h"

    #include <QPushButton>

    #include <QDebug>

    Widget::Widget(QWidget *parent) :

        QWidget(parent),

        ui(new Ui::Widget)

    {

        ui->setupUi(this);

        //鼠标跟踪

        this->setMouseTracking(true);

        //按时启动定时器

        timeID1=this->startTimer(1000); //1000毫秒

        timeID2=this->startTimer(500);

    }

    Widget::~Widget()

    {

        delete ui;

    }

    void Widget::mousePressEvent(QMouseEvent *ev)

    {

        if(ev->button()==Qt::LeftButton)

        {

            qDebug()<<"LeftButton";

        }

        else if(ev->button()==Qt::MidButton)

        {

            qDebug()<<"MidButton";

        }

        else if(ev->button()==Qt::RightButton)

        {

            qDebug()<<"RightButton";

        }

        //switch(ev->button())

        {

       // case Qt::LeftButton:

       //     qDebug()<<"LeftButton";

        //    break;

       // case Qt::MidButton:

       //     qDebug()<<"MidButton";

        //    break;

       // case Qt::RightButton:

        //    qDebug()<<"RightButton";

        //   break;

        }

        ui->label->setText(QString("MousePressedePoint:(%1,%2)").arg(ev->x()).arg(ev->y()));

    };

    void Widget::mouseMoveEvent(QMouseEvent *ev)

    {

        ui->label->setText(QString("<center><h1>Point:(%1,%2)</h1></center>").arg(ev->x()).arg(ev->y()));

    }

    void Widget::mouseReleaseEvent(QMouseEvent *ev)

    {

         ui->label->setText(QString("MouseReleasePoint:(%1,%2)").arg(ev->x()).arg(ev->y()));

    };

    void Widget::enterEvent(QEvent *e)

    {

        ui->label_2->setText("EnterWidget");

    }

    void Widget::leaveEvent(QEvent *e)

    {

        ui->label_2->setText("LeaveWidget");

    }

    void Widget::keyPressEvent(QKeyEvent *e)

    {

        qDebug()<<(char)e->key();

        if(e->key()==Qt::Key_A)

        {

            qDebug()<<"AAAA";

        }

    }

    void Widget::keyReleaseEvent(QKeyEvent *e)

    {

    }

    void Widget::timerEvent(QTimerEvent *t)

    {

        static int time1=0,time2=0;

        if(t->timerId()==timeID1)

        {

             ui->label_3->setText(QString("Timer1:%1").arg(time1++));

             //到10终止定时器

             if(time1==10)

             {

                 QObject::killTimer(timeID1);

             }

        }

        else if(t->timerId()==timeID2)

        {

             ui->label_4->setText(QString("Timer2:%1").arg(time2++));

        }

    }

    .cpp

    #include "widget.h"

    #include "ui_widget.h"

    #include <QPushButton>

    #include <QDebug>

    Widget::Widget(QWidget *parent) :

        QWidget(parent),

        ui(new Ui::Widget)

    {

        ui->setupUi(this);

        //鼠标跟踪

        this->setMouseTracking(true);

        //按时启动定时器

        timeID1=this->startTimer(1000); //1000毫秒

        timeID2=this->startTimer(500);

    }

    Widget::~Widget()

    {

        delete ui;

    }

    void Widget::mousePressEvent(QMouseEvent *ev)

    {

        if(ev->button()==Qt::LeftButton)

        {

            qDebug()<<"LeftButton";

        }

        else if(ev->button()==Qt::MidButton)

        {

            qDebug()<<"MidButton";

        }

        else if(ev->button()==Qt::RightButton)

        {

            qDebug()<<"RightButton";

        }

        //switch(ev->button())

        {

       // case Qt::LeftButton:

       //     qDebug()<<"LeftButton";

        //    break;

       // case Qt::MidButton:

       //     qDebug()<<"MidButton";

        //    break;

       // case Qt::RightButton:

        //    qDebug()<<"RightButton";

        //   break;

        }

        ui->label->setText(QString("MousePressedePoint:(%1,%2)").arg(ev->x()).arg(ev->y()));

    };

    void Widget::mouseMoveEvent(QMouseEvent *ev)

    {

        ui->label->setText(QString("<center><h1>Point:(%1,%2)</h1></center>").arg(ev->x()).arg(ev->y()));

    }

    void Widget::mouseReleaseEvent(QMouseEvent *ev)

    {

         ui->label->setText(QString("MouseReleasePoint:(%1,%2)").arg(ev->x()).arg(ev->y()));

    };

    void Widget::enterEvent(QEvent *e)

    {

        ui->label_2->setText("EnterWidget");

    }

    void Widget::leaveEvent(QEvent *e)

    {

        ui->label_2->setText("LeaveWidget");

    }

    void Widget::keyPressEvent(QKeyEvent *e)

    {

        qDebug()<<(char)e->key();

        if(e->key()==Qt::Key_A)

        {

            qDebug()<<"AAAA";

        }

    }

    void Widget::keyReleaseEvent(QKeyEvent *e)

    {

    }

    void Widget::timerEvent(QTimerEvent *t)

    {

        static int time1=0,time2=0;

        if(t->timerId()==timeID1)

        {

             ui->label_3->setText(QString("Timer1:%1").arg(time1++));

             //到10终止定时器

             if(time1==10)

             {

                 QObject::killTimer(timeID1);

             }

        }

        else if(t->timerId()==timeID2)

        {

             ui->label_4->setText(QString("Timer2:%1").arg(time2++));

        }

    }

    Main.cpp

    #include "widget.h"

    #include <QApplication>

    int main(int argc, char *argv[])

    {

        QApplication a(argc, argv);

        Widget w;

        w.show();

        return a.exec();

    }

  • 相关阅读:
    Amoeba -- 阿里巴巴工程师的开源项目之一陈思儒
    js表达式与语句的区别
    互联网公司github项目汇总
    CDN解决方案
    免费评论组件多说
    ajax同步的实现
    两种时间格式化对比
    Google Gson 使用简介
    使用XStream解析MXL文件用到的jar包---xpp3_min-1.1.3.4.O.jar和xstream-1.3.1.jar
    《Netty in Action》中文版
  • 原文地址:https://www.cnblogs.com/gd-luojialin/p/9215732.html
Copyright © 2011-2022 走看看