zoukankan      html  css  js  c++  java
  • <C++ QT4 GUI 编程>第七章笔记

    事件Event

    事件是由窗口系统和Qt自身产生的,用以响应发生的各类事情,例如用户按下键盘或者鼠标,都会产生一个键盘或鼠标的事件。大多数事件是用于的动作相应的,小数是由系统独立产生的,如定时器事件。要记住“事件”和“信号”是两种不同的概念。

    重载键盘事件函数:

    如果我们想自定义事件处理函数,只需要重载相关的事件函数就行了,如我需要对点击F3”按键的事件进行处理,代码如下:

    //重载keyPressEvent()

    void MainWindow::keyPressEvent(QKeyEvent *event)

    {    

    if(event->key() == Qt::Key_F3)    

    {        

    //todu    

    }

    //把事件传递给父窗口部件来处理

    QWidget::keyPressEvent(event);

    }

    定时器事件:

    调用startTimer()后会分配一个唯一的标识号,每隔一段时间都会调用一次timerEvent()

    //mainwindow.h

    void timerEvent(QTimerEvent *event);

    int myTimerId;

    //mainwindow.cpp

    //开启定时器

    myTimerId = startTimer(500);

    void MainWindow::timerEvent(QTimerEvent *event)

    {    

    if(myTimerId == event->timerId())    

    {        

    //todo    

    }

    }

    //关闭定时器

    killTimer(myTimerId);        

    myTimerId = 0;

    补充:

    定时器还可以这样用QTimer::singleShot(0, this, SLOT(function()));功能是马上触发定时器执行槽函数,这种用法多用于构造函数中耗时较长的初始功能,为了避免因为耗时的原因界面没有加载出来,使用户认为是应用程序启动失败。

    定时器事件是一种低级事件,当需要多个定时器时,一个定时器对应一个ID这会让追踪定时器变得困难,因此最好的方法是创建QTimer对象。

    事件过滤器:

    假设现在有一个需求,界面上有四个QLineEdit,点击QlineEdit后光标在上面显示,当我们输入空格键时光标调到下一个QLineEdit上。

    我们可以子类化QLineEdit,用上面重载键盘事件函数的方法实现,但当是不同的窗口部件(QSpinBox,QComboBox等)之间实现这个需求时,子类化每个窗口部件类是非常麻烦的,所以我们可以用事件过滤器实现。

    Qt事件模型的一个非常强大的功能是QObject实例(例如窗口部件)在看到它自己的事件之前,可以通过设置另一个QObject实例先监视这些事件。我的理解是父窗体可以先监视子窗口的事件,并在监视代码中实现相应功能。

    使用过滤器的步骤为:

    1、目标对象(窗口部件)调用installEventFilter()注册监视对象

    2、在监视对象的eventFilter()中处理目标对象(窗口部件)的事件。

    过滤器代码实例:

    //mainwindow.h

    QLineEdit *lineEdit1;    

    QLineEdit *lineEdit2;

    void eventFilter(QObject *target, QEvent *event);

    //mainwindow.cpp

    //构造函数中

    {

    ...

    lineEdit1 = new QLineEdit(this);    

    lineEdit2 = new QLineEdit(this);    

    lineEdit1->installEventFilter(this);    

    lineEdit2->installEventFilter(this);

    ...

    }

    //重载eventFilter()

    bool MainWindow::eventFilter(QObject *target, QEvent *event)

    {    

    //检查目标对象

    if(target == lineEdit1 || target == lineEdit2)    

    {        

    //判断是否键盘按下事件

    if(event->type() == QEvent::KeyPress)        

    {   

    //将事件强制转换为键盘事件,为了可以调用keyEvent->key()         

    QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);             //判断是否空格键

    if(keyEvent->key() == Qt::Key_Space)

    {                

    //todo                

    return true;           

     }       

    }

        }

    //如果目标对象不对,不是按键按下事件,就调用基类的eventFilter,因为基类eventFilter也可能正在监控某个窗口部件。

        return QWidget::eventFilter(target,event);

    }

    Qt提供五个级别的事件处理和时间过滤方法(序号越大级别越高):

    1、重新实现特殊的事件处理器

    即重载按键按下,鼠标单击等事件处理函数

    2、重新实现QObject:event()

    通过event()函数的重新实现,可以让事件到达特定的事件处理器前处理它们。

    3、Object中安装事件过滤器

    4、QApplicantion对象中安装事件过滤器

    应用程序的每个对象都会在事件发送到其他事件过滤器之前,先发送给这个eventFilter()函数。

    5、子类化QApplicantion并且重载notify()

     

    QApplicatn::processEvent():

    当调用QApplicant:exec()时,就启动了Qt的事件循环。当处理一个事件时(执行功能函数),也有可能有产生别的事件并会添加到事件队列中。当处理这个事件耗时太长时,其他事件无法进行,用户界面就无法响应了,如无法进行鼠标点击,这时解决的方法有两种:

    1、利用多线程方法,将处理应用程序的用户界面和耗时的操作分开为不同的线程

    2、频繁调用QApplicatn::processEvent(),这个函数的作用是告诉Qt处理那些还没被处理的事件,这可以让用户界面继续操作,因此QApplicant:exec()就是一个不断调用QApplicatn::processEvent()while循环。

  • 相关阅读:
    【Bootloader】探究bootloader,分析u-boot源码
    【内核】linux2.6版本内核编译配置选项(一)
    【内核】linux2.6版本内核编译配置选项(二)
    【内核】探究linux内核,超详细解析子系统
    【内核】几个重要的linux内核文件
    【教程】探究暴风影音视频截图黑屏原因
    【Linux技术】BusyBox详解
    【C/C++】C/C++中Static的作用详述
    cf515d
    poj1155
  • 原文地址:https://www.cnblogs.com/qjswxd/p/11883730.html
Copyright © 2011-2022 走看看