Qt 06事件处理

qt的工作原理:事件驱动、信号机制

qt的事件由窗口系统或是qt自身产生,用于响应各种需要处理的事务
Qevent类定义了Qt中的事件,通过enum QEvent::Type可以查询
常见需要处理的由窗口系统的QKeyEvent、QMouseEvent、QPaintEvent、QResizeEvent、QMoveEvent事件,来自系统的QTimerEvent等

在这里插入图片描述

处理特定事件处理器:

1.重写特定事件处理器

1.重写键盘按键按下的事件处理器  虚函数
        #include <QKeyEvent>        
        void keyPressEvent(QKeyEvent *event);
        
        key():返回按键的编码
        text():获取按键的文件编码,返回的是QString
        x():获取当前的x坐标值
        
         switch(event->key())
     {
     case Qt::Key_Up:
            ui->label->move(ui->label->x(),ui->label->y()-2);
         break;
     case Qt::Key_Down:
         ui->label->move(ui->label->x(),ui->label->y()+2);
         break;
     case Qt::Key_Left:
         ui->label->move(ui->label->x()-2,ui->label->y()-2);
         break;
     case Qt::Key_Right:
         ui->label->move(ui->label->x()+2,ui->label->y()-2);
         break;
     }
-------------------------------------------------------------------------------------------------         
2.重写鼠标按下的事件处理
        #include <QMouseEvent>        
        void mouseMoveEvent(QMouseEvent *event);
        
        鼠标特殊设备,必须按下任意按键移动时,才会产生鼠标移动事件
        x():获取当前鼠标在界面的x坐标
        ui->label->move(event->x()-ui->label->width()/2,event->y()-ui->label->width()/2);
        
        设置鼠标跟随:
            意味着在 widget不需要鼠标按键按下就可以产生鼠标移动事件
        在构造函数中:this->setMouseTracking(true);

2.重写event函数

bool event(QEvent *event);
事件的处理流程:
     1.界面产生的任何事,优先调用QWidge基类的event函数进行处理
     2.event函数内部,判断事件的类型,然后调用基类的特定事件处理器进行处理
     3.如果派生类重写了特定事件处理器,则event调用派生类重写的虚函数,实现新功能
     注:如果派生类重写了event虚函数,则界面产生的事件优先调用派生类重写的event虚函数
        1.判断自己感兴趣需要处理的事件,实现新功能,处理完返回true
        2.不感兴趣的事件,则需要手动调用基类的event函数进行默认处理,返回基类处理结果
------------------------------------------------------------------------------------------------- 
事件的处理流程,事件发生后首先交给级别比较高的QWidget类的event处理
再交给特定函数事件处理,但都是基于QWidget类的
bool Widget::event(QEvent *event)
{
    //将感兴趣的事件处理
    if(event->type()==感兴趣的事件)
    {
        处理;
        return true;
    }
    return QWidget::event(event);
    //将不感兴趣的手动交给基类处理
    //最顶级的QObject派生出QWidget,QWidget派生出其他特殊处理
    //不能调QObject基类,QObject太广泛了
}        
                              
-------------------------------------------------------------------------------------------------                                                 
        
bool Widget::event(QEvent *event)
{
    if(event->type()==QKeyEvent::KeyPress)
    {
        keyPressEvent((QKeyEvent *)event);
        return true;
    }
    if(event->type()==QMouseEvent::MouseMove)
    {
        QMouseEvent *e=(QMouseEvent *)event;
        ui->label->move(e->x()-ui->label->width()/2,e->y()-ui->label->height()/2);
    }
    
    return QWidget::event(event);
}

3.注册事件过滤器,并重写过滤器

bool eventFilter(QObject *watched, QEvent *event);

事件过滤器目的是筛选出感兴趣控件上产生的感兴趣的事件
 步骤:
      1.重写eventFilter函数
          bool eventFilter(QObject *watched, QEvent *event);
      2.将关注的控件加载安装到当前类的过滤器中  installEventFilter(this);
          在构造函数中:ui->textEdit->installEventFilter(this);
          这样在该控件上产生的任何事件都优先调用eventFilter,不会调用event
          
          
注:在输入类控件(比如文本编辑框)中,鼠标左键不会产生MouseButtonPress事件
------------------------------------------------------------------------------------------------- 
bool Widget::eventFilter(QObject *watched, QEvent *event)
{
    if(watched==感兴趣的控件)
    {
        if(event->type()==控件上感兴趣的事件)
        {
            return true;              
        }
        //return false;
        //该控件上的其他不感兴趣事件,都忽略
        return QWidget::eventFilter(watched,event);
        //该控件上的其他不感兴趣事件,都交给基类处理
     }
     return QWidget::eventFilter(watched,event);
     //凡是不感兴趣控件上的事件,都交给基类处理
}
-------------------------------------------------------------------------------------------------      
bool Widget::eventFilter(QObject *watched, QEvent *event)
{
    //判断该事件产生的对象是否为感兴趣的控件
    if(watched==ui->textEdit)
    {
        //判断该控件上产生的事件是否为感兴趣的事件
        if(event->type()==QMouseEvent::MouseButtonPress)
        {
            QMouseEvent *e=(QMouseEvent *)event;
#if 0
            if(e->button()==Qt::LeftButton)
            {
                 ui->label->setStyleSheet("background-color:yellow;border-radius:25px;");
            }
            //在输入类控件中,鼠标左键不会产生 MouseButtonPress事件
            //输入类的鼠标左键触发事件会被编辑框捕获,用于将焦点置于编辑框中
            //故在编辑框里按左键不会变色
#endif
            if(e->button()==Qt::MiddleButton)
            {
                ui->label->setStyleSheet("background-color:yellow;border-radius:45px;");
            }
            if(e->button()==Qt::RightButton)
            {
                ui->label->setStyleSheet("background-color:green;border-radius:45px;");
            }
            return true;
        }
        //return false;
        //该控件上的其他不感兴趣事件,都忽略
        return QWidget::eventFilter(watched,event);
        //该控件上的其他不感兴趣事件,都交给基类处理
    }
    return QWidget::eventFilter(watched,event);
    //凡是不感兴趣控件上的事件,都交给基类处理
}

二维画图

#include <QPainter>         //提供绘图方法
#include <QPen>             //画笔
#include <QBrush>           //画刷

重写绘图事件处理器:
    void paintEvent(QPaintEvent *e);
    {
        QPainter p(this);   // 构造画家到当前界面 
        p.setRenderHint(QPainter::Antialiasing);//设置反锯齿   
       
        QPen pen;           //构造画笔
        pen.setColor(QColor("#aabbcc"));        //设置颜色
        pen.setStyle(Qt::SolidLine);            //设置画笔样式
        pen.setWidth(8);                        //设置画笔粗细
        p.setPen(pen);                          //给画家设置画笔  
        
        p.translate(width()/2, height()/2);     //将绘图设备平移到 某个点
        p.drawLine(QPoint(150, 0), QPoint(155, 0));     //画线
        
        p.rotate(90);                            //将坐标轴旋转角度
        p.drawLine(QPoint(150, 0), QPoint(155, 0));
        
        p.setBrush(QBrush("black"));                //设置画刷
        p.drawEllipse(QPoint(0, 0), 155, 155);      //画圆
    
        QPoint point[3] = {
        QPoint(0, 0),
        QPoint(0, 40),
        QPoint(30, 0),
        };
        p.drawConvexPolygon(point, 3);              //画凸多边形
    }

计时器

#include <QTimer>

widget.h:
    private:
        QTimer *time;
    private slots:
        void timeOut();
        
widget.c:
    构造函数:
    time = new QTimer(this);                                     // 构造定时器
    connect(time, &QTimer::timeout, this, &Widget::timeOut);     // 定时器时间到了,立即触发 timeout超时信号
    time->start(1000);                                           //启动定时器,设定 超时时间 1s
    
    //时间一到就调用槽函数,刷新界面
槽函数:
    void Widget::timeOut()
{
    update();                         //刷新一次
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值