QT +事件

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

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

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

keyPressEvent()

keyReleaseEvent()

mouseDoubleClickEvent()等;

这些函数都是 protected virtual 的,也就是说,我们可以在子类中重新实现这些函数。

在了解以上的学习的内容后,我们现在要实现的功能描述如下:整体为两种事件,一种是外部触发事件,一种是内部事件(计数器)

定义一个窗口,里面添加一个QLabel控件,当鼠标按下的时候,能够显示其坐标,并且能够判断是鼠标的左键、右键、中间键。

首先需要重新定义一个MyQlabel 的类,继而在ui中进行提升,让在 ui 中的 label 控件的基类是MyLabel ,从而在程序的编写界面进行事件的处理。

项目的工程建立如下图:

          

ui界面文件如图:

mylabel.h文件:

#ifndef MYLABEL_H
#define MYLABEL_H

//#include <QWidget>//由于MyLabel继承于QLabel,所以这里需要将其修改为:#include<QLabel>

#include<QLabel>  //1

class MyLabel : public QLabel//2
{
    Q_OBJECT
public:
    explicit MyLabel(QWidget *parent = 0);

protected:
    /*这里需要说明一点,怎么知道虚函数有没有写错?这里的虚函数是保护类型的,
     * 当你忘记了事件的名字时,最好在QWidget中查看一下,值得一提的是事件代码:
     * void mousePressEvent(QMouseEvent *ev);中的任何一个都不能自己写,必须利用提示,
     * 这是因为如果是自己写的,就相当于自定义函数,就不是虚函数了。
     * 并且,在mousePressEvent虚函数上按F1是没有反应的,必须在其基类QWidget中查看
    */
    //鼠标点击事件
    void mousePressEvent(QMouseEvent *ev);
    //鼠标释放事件
    void mouseReleaseEvent(QMouseEvent *ev);
    //鼠标移动事件
    void mouseMoveEvent(QMouseEvent *ev);
    //进入窗口区域
    void enterEvent(QEvent *);
    //离开窗口区域
    void leaveEvent(QEvent *);

signals:

public slots:
};

#endif // MYLABEL_H

mywidget.h:

#ifndef MYWIDGET_H
#define MYWIDGET_H

#include <QWidget>



namespace Ui {
class MyWidget;
}

class MyWidget : public QWidget
{
    Q_OBJECT

public:
    explicit MyWidget(QWidget *parent = 0);
    ~MyWidget();
protected:
    //键盘按下事件
    void keyPressEvent(QKeyEvent *event);
    //计时器事件
    void timerEvent(QTimerEvent *event);



private:
    Ui::MyWidget *ui;

    int timeID ;//为了区分是哪一个计时器,添加计时器ID。
    int timeID2;
};

#endif // MYWIDGET_H

mylabel.cpp

#include "mylabel.h"

#include <QMouseEvent>
#include <QDebug>
                                    //3
MyLabel::MyLabel(QWidget *parent) : QLabel(parent)
{
    //设置追踪鼠标,当鼠标一进来窗口就产生事件
    this ->setMouseTracking(true);

}

void MyLabel::mousePressEvent(QMouseEvent *ev)
{
    int i = ev->x();
    int j = ev->y();
    /*在这里,i和j都是整数类型。
     * 在Qlabel上显示,需要将其进行格式化;这里介绍格式化的代码和arg的用法;
     * 例如:QString str = QString ("abc %1 ^_^ %2").arg(123).arg("mike");
     *
     * 这里%1对应着第一个arg
     * %2对应着第二个arg
     *
     * 那么str就会变成:
     * str = abc 123 ^_^ mike
     *
    */
    /*
     * 这个事件本身是当鼠标按下的时候会执行这里面的代码,为了更加的精确高级,还能判断是鼠标的左键,右键,中间键,从而更加精确的执行代码;
    */
    if (ev->button() ==Qt::LeftButton)
    {
        qDebug()<<"鼠标的左键被按下!!!";
    }
    else if (ev->button() == Qt::RightButton)
    {

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

    }
                                //这里添加的是H5代码
    QString text = QString ("<center><h1>Mouse Press:(%1,%2)</h1></center>").arg(i).arg(j);
    this->setText(text);

}
void MyLabel::mouseReleaseEvent(QMouseEvent *ev)
{

}
void MyLabel::mouseMoveEvent(QMouseEvent *ev)
{

}

void MyLabel::enterEvent(QEvent *e)
{
    QString text = QString ("<center><h1>Mouse enter</h1></center>");
    this->setText(text);
}

void MyLabel::leaveEvent(QEvent *e)
{

}

mywidget.cpp:

#include "mywidget.h"
#include "ui_mywidget.h"

#include <QKeyEvent>
#include <QDebug>

MyWidget::MyWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MyWidget)
{
    ui->setupUi(this);

    //毫秒为单位,每隔1S触发一次定时器
    timeID =  this->startTimer(1000);

    timeID2 =  this->startTimer(500);

}

MyWidget::~MyWidget()
{
    delete ui;
}
//想知道怎么知道哪个按键被按下,可以对QKeyEvent按下F1,查看帮助文档 中的int key() const,
void MyWidget::keyPressEvent(QKeyEvent *event)
{
    qDebug()<<event->key();//直接打印ACSII码
    qDebug()<<(char)event->key();//转化成字母打印出来
    if(event->key() == Qt::Key_A)
    {
        qDebug()<<"Qt::Key_A";
    }
}

void MyWidget::timerEvent(QTimerEvent *event)
{
    if (event->timerId() == this->timeID)
    {
        static int sec = 0;
        ui->label->setText( QString ("<center><h1>time : %1</h1></center>").arg(sec++));
        if (sec == 5)
        {
            this ->killTimer(this->timeID);
        }
    }
    else if (event->timerId() == this->timeID2)
    {
        static int sec = 0;
        ui->label_2->setText( QString ("<center><h1>time : %1</h1></center>").arg(sec++));

    }
}

至此为止,内部事件(计时器)和外部事件(鼠标和键盘)的功能就完成了。

猜你喜欢

转载自www.cnblogs.com/doker/p/11059809.html