Bootstrap

Qt桌面应用开发 第六天(鼠标事件 定时器事件 定时器类 事件分发器 事件过滤器)

目录

1.1鼠标进入和离开enterEvent\leaveEvent

1.2鼠标按下释放和移动mousePressEvent\mouseReleaseEvent\mouseMoveEvent

1.3定时器事件timerEvent

1.4定时器类QTimer

1.5事件分发器event

 1.6事件过滤器eventFilter


1.1鼠标进入和离开enterEvent\leaveEvent

事件:

鼠标进入函数原型:

[virtual protected] void QWidget::enterEvent(QEvent* event);

鼠标离开函数原型:

[virtual protected] void QWidget::leaveEvent(QEvent* event);

举例:重写鼠标进入离开事件

void MyLable::enterEvent(QEvent *event)
{
    qDebug()<<"鼠标进入";
}

void MyLable::leaveEvent(QEvent *event)
{
    qDebug()<<"鼠标离开";
}

1.2鼠标按下释放和移动mousePressEvent\mouseReleaseEvent\mouseMoveEvent

鼠标按下、释放是瞬间触发的,移动是一个持续性事件

 鼠标按下函数原型:

[virtual protected] void QWidget::mousePressEvent(QMouseEvent* event);

鼠标释放函数原型:

[virtual protected] void QWidget::mouseReleaseEvent(QMouseEvent* event);

鼠标移动函数原型: 

[virtual protected] void QWidget::mouseMoveEvent(QMouseEvent* event);

举例:

void MyLable::mousePressEvent(QMouseEvent *event)
{
    qDebug()<<"鼠标按下了";
}

void MyLable::mouseReleaseEvent(QMouseEvent *event)
{
    qDebug()<<"鼠标松开了";
}

void MyLable::mouseMoveEvent(QMouseEvent *event)
{
    qDebug()<<"鼠标移动了";
}

扩展1:鼠标按下,释放,移动时,分别打印鼠标相对于Label的x、y坐标

 QMouseEvent可以获取鼠标对应的信息

void MyLable::mousePressEvent(QMouseEvent *event)
{
    QString str=QString("x=%1,y=%2").arg(event->x()).arg(event->y());
    qDebug()<<str;
    qDebug()<<"鼠标按下了";
}

void MyLable::mouseReleaseEvent(QMouseEvent *event)
{
    QString str=QString("x=%1,y=%2").arg(event->x()).arg(event->y());
    qDebug()<<str;
    qDebug()<<"鼠标松开了";
}

void MyLable::mouseMoveEvent(QMouseEvent *event)
{
    QString str=QString("x=%1,y=%2").arg(event->x()).arg(event->y());
    qDebug()<<str;
    qDebug()<<"鼠标移动了";
}

扩展2:在MyLabel中鼠标只要移动,就会触发移动事件,不需要按下

将鼠标追踪效果设为true

MyLable::MyLable(QWidget *parent)
    : QLabel{parent}
{
    this->setMouseTracking(true);
}

扩展3:鼠标左键按下时,才会触发相应内容

QMouseEvent对象的button()可以判断鼠标按下的是左键或右键

void MyLable::mousePressEvent(QMouseEvent *event)
{
    if(Qt::LeftButton==event->button())
    {
        QString str=QString("x=%1,y=%2").arg(event->x()).arg(event->y());
        qDebug()<<str;
        qDebug()<<"鼠标按下了";
    }
}

void MyLable::mouseReleaseEvent(QMouseEvent *event)
{
    if(Qt::LeftButton==event->button())
    {
        QString str=QString("x=%1,y=%2").arg(event->x()).arg(event->y());
        qDebug()<<str;
        qDebug()<<"鼠标松开了";
    }
}

void MyLable::mouseMoveEvent(QMouseEvent *event)
{
    if(Qt::LeftButton==event->button())
    {
        QString str=QString("x=%1,y=%2").arg(event->x()).arg(event->y());
        qDebug()<<str;
        qDebug()<<"鼠标移动了";
    }
}

1.3定时器事件timerEvent

需求:两个label,初始值都为1,第一个每隔一秒加一,第二个每隔一秒加二

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
    
    //重写定时器事件
    void timerEvent(QTimerEvent *event);
    
    //声明两个定时器的唯一标识
    int id1;
    int id2;
private:
    Ui::Widget *ui;
};
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    
    //1000毫秒,每隔一秒钟会触发timerEvent,startTimer会返回一个唯一标识
    this->id1=startTimer(1000);
    
    this->id2=startTimer(2000);
}

void Widget::timerEvent(QTimerEvent *event)
{
    //QTimerEvent的timerId方法可以获得计时器的唯一标识
    if(event->timerId()==this->id1)
    {
        static int num1=1;
        ui->label->setText(QString::number(num++));
    }
    
    if(event->timerId()==this->id2)
    {
        static int num2=1;
        ui->label->setText(QString::number(num2++));
    }
}

startTimer——启动定时器,单位是毫秒,startTimer会返回一个int类型的唯一标识

1.4定时器类QTimer

 需求:一个label,初始值为1,每隔0.5秒加一;且有一个停止按钮,点击之后,label上的数字停止递增

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    
    QTimer * timer=new QTimer(this);
    //每隔500毫秒发timeout的信号
    timer->start(500);
    connect(timer,&QTimer::timeout,[=]{
        static int num3=1;
        ui->label_3->setText(QString::number(num++));
    })

    connect(ui->btn_stop,&QPushButton::clicked,[=]{
    timer->stop();
    });
}

注意:

  • start——启动定时器,单位毫秒;超过时间会发timeout的信号
  • stop——停止计时器

1.5事件分发器event

需求:重写一个事件分发器,拦截鼠标按下事件

class MyLabel : public QLabel
{
    Q_OBJECT
public:
    explicit MyLabel(QWidget *parent = nullptr);

    void mousePressEvent(QMouseEvent *ev);

    bool event(QEvent *e);
signals:

};
void MyLabel::mousePressEvent(QMouseEvent *ev)
{
    QString str=QString("鼠标按下了x=%1,y=%2").arg(ev->x()).arg(ev->y());
    qDebug()<<str;
}

bool MyLabel::event(QEvent *e)
{
    if(e->type()==QEvent::MouseButtonPress)
    {
        QMouseEvent* ev=static_cast<QMouseEvent*>(e);
        QString str=QString("event事件中鼠标按下了x=%1,y=%2").arg(ev->x()).arg(ev->y());
        qDebug()<<str;
        //标识拦截下鼠标按下事件
        return true;
    }
    //其他事件交给父类处理
    return QLabel::event(e);
}

 1.6事件过滤器eventFilter

时间过滤器函数原型:

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

若此事件是感兴趣的类型,返回true,自己进行处理;若不是,返回false,继续转发

事件过滤器使用步骤:

  1. 给控件安装过滤器installEventFilter
  2. 重写过滤器事件eventFilter
    //安装事件过滤器
    ui->label->installEventFilter(this);


    bool Widget::eventFilter(QObject *watched, QEvent *event)
    {
    if(watched==ui->label)
    {
        if(event->type()==QEvent::MouseButtonPress)
        {
            QMouseEvent* ev=static_cast<QMouseEvent*>(event);
            QString str=QString("eventFilter事件中鼠标按下了x=%1,y=%2").arg(ev->x()).arg(ev->y());
            qDebug()<<str;
            //标识拦截下鼠标按下事件
            return true;
        }
    }

    //其他事件交给父类处理
    return QWidget::eventFilter(watched,event);
    }

;