Qt:键盘事件和鼠标事件、定时器小实例

目录

引言:

一、键盘事件

 二、鼠标事件

 三、定时器小实例

 四、总结

引言:

QT程序是事件驱动的, 程序的每个动作都是由内部某个事件所触发。QT事件的发生和处理成为程序运行的主线,存在于程序整个生命周期。

  常见的QT事件类型如下:

     键盘事件: 按键按下和松开

     鼠标事件: 鼠标移动,鼠标按键的按下和松开

     拖放事件: 用鼠标进行拖放

     滚轮事件: 鼠标滚轮滚动

     绘屏事件: 重绘屏幕的某些部分

     定时事件: 定时器到时

     焦点事件: 键盘焦点移动

     进入和离开事件: 鼠标移入widget之内,或是移出

     移动事件: widget的位置改变

     大小改变事件: widget的大小改变

     显示和隐藏事件: widget显示和隐藏

     窗口事件: 窗口是否为当前窗口

   QT将系统产生的消息转化为QT事件,QT事件被封装为对象,所有的QT事件均继承抽象类QEvent,用于描述程序内部或外部发生的动作,任意的QObject对象都具备处理QT事件的能力。

一、键盘事件

头文件

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

#include <QDebug>
#include <QCloseEvent>
#include <QKeyEvent>
#include <QMouseEvent>
#include <QTimerEvent>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT
public:
    int nIdFast;
    int nIdSlow;
public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
public:
    //void closeEvent(QCloseEvent *event);
    void keyPressEvent(QKeyEvent *event);
    //void mousePressEvent(QMouseEvent *event);
    //void timerEvent(QTimerEvent * event);
private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

源文件

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //ui->pushButton->setText("close");
    //ui->label->setText("哈哈");
    nIdSlow = startTimer(1000);
    nIdFast = startTimer(500);

    //QObject::connect(ui->pushButton,&QPushButton::clicked,this,&QWidget::close);
    QObject::connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(close()));
}

Widget::~Widget()
{
    delete ui;
}
void Widget::closeEvent(QCloseEvent *event)
{
    qDebug() << "close" << endl;
}
void Widget::keyPressEvent(QKeyEvent *event)
{
    //ui->label->setText("呵呵");
    switch(event->key())
    {
    case Qt::Key_A:
        ui->label->setText("A");
        break;
    case Qt::Key_B:
        ui->label->setText("B");
        break;
    }
}

运行:

 二、鼠标事件

头文件

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

#include <QDebug>
#include <QCloseEvent>
#include <QKeyEvent>
#include <QMouseEvent>
#include <QTimerEvent>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT
public:
    int nIdFast;
    int nIdSlow;
public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
public:
    //void closeEvent(QCloseEvent *event);
    //void keyPressEvent(QKeyEvent *event);
    void mousePressEvent(QMouseEvent *event);
    //void timerEvent(QTimerEvent * event);
private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

源文件

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //ui->pushButton->setText("close");
    //ui->label->setText("哈哈");
    nIdSlow = startTimer(1000);
    nIdFast = startTimer(500);

    //QObject::connect(ui->pushButton,&QPushButton::clicked,this,&QWidget::close);
    QObject::connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(close()));
}

Widget::~Widget()
{
    delete ui;
}
void Widget::mousePressEvent(QMouseEvent *event)
{
    QString str;
    int x = 0,y = 0;
    if(event->button() == Qt::LeftButton)
    {
        x = event->x();
        y = event->y();
        str = "(" + QString::number(x) + "," + QString::number(y) + ")";
        ui->label->setText(str);
    }
    if(event->button() == Qt::RightButton)
    {
        x = event->globalX();
        y = event->globalY();
        str = "(" + QString::number(x) + "," + QString::number(y) + ")";
        ui->label->setText(str);
    }
}

运行

 三、定时器小实例

头文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QKeyEvent>
#include <QTimerEvent>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    int nIdFast1;
    int nIdSlow1;
    int nIdFast2;
    int nIdSlow2;
public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
public:
    void keyPressEvent(QKeyEvent* event);
    void timerEvent(QTimerEvent* event);
private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

源文件

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    nIdFast1 = startTimer(250);
    nIdSlow1 = startTimer(1000);

    nIdFast2 = startTimer(500);
    nIdSlow2 = startTimer(1000);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::keyPressEvent(QKeyEvent* event)
{
    switch(event->key())
    {
    case Qt::Key_A:
        killTimer(nIdSlow1);
        killTimer(nIdFast1);
        ui->label_2->setText("A");
        break;
    case Qt::Key_B:
        killTimer(nIdSlow2);
        killTimer(nIdFast2);
         ui->label->setText("B");
        break;
    case Qt::Key_C:
        startTimer(250);
        startTimer(1000);
         ui->label_2->setText("C");
        break;
    case Qt::Key_D:
        startTimer(500);
        startTimer(1000);
         ui->label->setText("D");
        break;
    }
}
void MainWindow::timerEvent(QTimerEvent* event)
{
    static int n1 = 0;
    static int x1 = 0;
    if(event->timerId() == nIdSlow1)
    {
        n1++;
        QString str = QString::number(n1);
        ui->pushButton->setText(str);

    }
    if(event->timerId() == nIdFast1)
    {
        x1 += 5;
        ui->pushButton->setGeometry(x1,100,50,50);
    }
    static int n2 = 0;
    static int x2 = 0;
    if(event->timerId() == nIdSlow2)
    {
        n2++;
        QString str = QString::number(n2);
        ui->pushButton_2->setText(str);
    }
    if(event->timerId() == nIdFast2)
    {
        x2 += 5;
        ui->pushButton_2->setGeometry(x2,300,50,50);
    }
}

运行

 四、总结

        事件(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 的,也就是说,我们应该在子类中重定义这些函数。

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值