1. 程式人生 > >Qt的事件處理和定時器解析(例項解析)

Qt的事件處理和定時器解析(例項解析)

理論準備:

1、事件是由視窗系統或者Qt自身產生的,用以響應所發生的各類事情。

2、Qt事件的產生可能是因為鍵盤或滑鼠被按下,也有可能是視窗在顯示時,產生的繪製事件。

3、大多數事件都是為使用者的操作而產生的響應。其中比較特殊的定時器事件,則是由系統獨立產生的。

4、在Qt中,事件就是QEvent子類的一個例項,QEvent是所有事件類的基類。我們可以通過QEventtype()函式返回事件的型別。

bool MainWindow::event(QEvent *event)
{
    qDebug()<<event->type();
    return true;
}

當滑鼠移動,或者按下鍵盤是,打印出當前的事件型別。

程式執行效果:


例項:

下面仔細講一講Qt中如何重新實現事件處理器,以及怎麼樣使用單個定時器和多個定時器。

程式執行效果:



定時器事件:

定時器1: 通過訊號與槽繫結,使用timeout()訊號才出發槽。

定時器2和定時器3: 通過startTimer()開啟,並記錄器ID,在虛擬函式timerEvent(QTimerEvent *event)中判斷定時器定時是否已經到了。

滑鼠按鍵:

  • 按下組合鍵Ctrl + F1,定時器1清零,重新開始計數;
  • 按下Ctrl + F2,定時器2清零,重新開始計數;
  • 按下Ctrl + F3,定時器3清零,重新開始計數;

原始碼解析:

main.cpp

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    MainWindow w;
    w.show();

    return a.exec();
}

定義一個MainWindow物件,並且使用show()方法顯示出來。

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTimerEvent>
#include <QKeyEvent>
#include "ui_mainwindow.h"

namespace Ui
{
class MainWindow;
}

class MainWindow : public QMainWindow  ,Ui_MainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

protected:
    void timerEvent(QTimerEvent *event);
  // bool event(QEvent *event);

private slots:
    void onTimerOut();
    void keyPressEvent(QKeyEvent *event);

private:
    QTimer *m_Timer1;

    int m_Timer1ID;
    int m_Timer2ID;
    int m_Timer3ID;

    int m_Timer1Count;
    int m_Timer2Count;
    int m_Timer3Count;
};

#endif // MAINWINDOW_H

重新實現虛擬函式
voidtimerEvent(QTimerEvent*event);
voidkeyPressEvent(QKeyEvent*event);

timerEvent()用於定時器事件,keyPressEvent()用於鍵盤按鍵事件。

*m_Timer1是一個QTimer型別的物件。

mainwindow.cpp

#include <QTimer>
#include <QDebug>
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
    setupUi(this);

    lineEdit1->setEnabled(false);
    lineEdit2->setEnabled(false);
    lineEdit3->setEnabled(false);

    m_Timer1Count = 0;
    m_Timer2Count = 0;
    m_Timer3Count = 0;

    m_Timer2ID = startTimer(2000);
    m_Timer3ID = startTimer(3000);

    m_Timer1 = new QTimer(this);
    connect(m_Timer1,SIGNAL(timeout()),this,SLOT(onTimerOut()));  //繫結定時器的訊號與槽
    m_Timer1->start(1000);
}

MainWindow::~MainWindow()
{

}

void MainWindow::timerEvent(QTimerEvent *event)
{
    //判斷定時器的時間是否到了
    if(event->timerId() == m_Timer2ID)
    {
        ++m_Timer2Count;
        lineEdit2->setText(QString::number(m_Timer2Count));
    }

    if(event->timerId() == m_Timer3ID)
    {
        ++m_Timer3Count;
        lineEdit3->setText(QString::number(m_Timer3Count));
    }
}

//bool MainWindow::event(QEvent *event)
//{
//    qDebug()<<event->type();
//    return true;
//}

void MainWindow::onTimerOut()
{
    ++m_Timer1Count;
    lineEdit1->setText(QString::number(m_Timer1Count));
}

void MainWindow::keyPressEvent(QKeyEvent *event)
{
    //判斷按鍵值
    switch (event->key())
    {
    case Qt::Key_F1:
        if(event->modifiers() & Qt::ControlModifier)
        {
            m_Timer1Count = 0;
        }
        break;

    case Qt::Key_F2:
        if(event->modifiers() & Qt::ControlModifier)
        {
            m_Timer2Count = 0;
        }
        break;

    case Qt::Key_F3:
        if(event->modifiers() & Qt::ControlModifier)
        {
            m_Timer3Count = 0;
        }
        break;
    default:
        qDebug()<<event->key();
        break;
    }
}

    m_Timer2ID = startTimer(2000);
    m_Timer3ID = startTimer(3000);

開啟兩個定時器,定時時間分別為2秒和3秒,並且記錄下定時器唯一的ID號。

m_Timer1 = new QTimer(this);
connect(m_Timer1,SIGNAL(timeout()),this,SLOT(onTimerOut()));  //繫結定時器的訊號與槽
m_Timer1->start(1000);

例項化定時器,繫結訊號與槽,定時時間為1秒。

void MainWindow::timerEvent(QTimerEvent *event)
{
    //判斷定時器的時間是否到了
    if(event->timerId() == m_Timer2ID)
    {
        ++m_Timer2Count;
        lineEdit2->setText(QString::number(m_Timer2Count));
    }


    if(event->timerId() == m_Timer3ID)
    {
        ++m_Timer3Count;
        lineEdit3->setText(QString::number(m_Timer3Count));
    }
}