9、qt事件机制、事件接收、事件忽略

1、事件机制也是qt的核心机制之一,在应用程序最后,返回值时,

QApplication a(argc, argv);
return a.exec();

应用等待在这里,等待捕获事件;

2、事件处理机制:

  等待检测到的事件A,会将该事件转换为相应的对象(该对象都集成QObject),该对象再转给event()函数,在传给事件处理器(类似于switch)-->再对相应的事件分类处理;----》再调用相应的处理动作;

   上述的事件处理类似于软件中断。

3、事件的特点:

  1、所有的事件类都是继承与OEvent

  2、事件的处理函数全部都是虚函数,在父类中声明,子类中使用的时候需要自己实现;

4、常见事件及其处理

  1、鼠标事件,在头文件中声明,不能自己定义,需要查QWidget有哪些事件,需要自己实现

protected:
    void mousePressEvent(QMouseEvent *ev);   // 鼠标按下事件
    void mouseReleaseEvent(QMouseEvent *ev); // 鼠标释放事件
    void mouseMoveEvent(QMouseEvent *ev);    // 鼠标移动事件
    void enterEvent(QEvent *ev);    // 鼠标进入窗口事件
    void leaveEvent(QEvent *ev);    // 鼠标离开窗口事件

  2、鼠标事件处理

MyLabel::MyLabel(QWidget *parent) : QLabel(parent)
{
    this->setMouseTracking(true);// 设置默认追踪鼠标
}
// QMouseEvent *ev 捕获鼠标的一些动作  鼠标按下
void MyLabel::mousePressEvent(QMouseEvent *ev)
{
    int i=ev->x();  // 获取鼠标x坐标
    int j=ev->y();
    // 鼠标三个按键捕获 判断
    if(ev->button() == Qt::RightButton)
    {
        qDebug()<< "RightButton";
    }else if(ev->button() == Qt::LeftButton)
    {
         qDebug()<< "LeftButton";
    }else if(ev->button() == Qt::MidButton)
    {
        qDebug()<< "MidButton";
    }
    /*字符串组包
     * QString str= QString("text %1...%2").arg(i).arg(j)
    */
    QString str= QString("<center><h1>press pos: (%1,%2)</h1></center>").arg(i).arg(j);
    this->setText(str);  // 标签上只可以显示字符串,获取的坐标是整数
}
// 鼠标释放 在标签上显示
void MyLabel::mouseReleaseEvent(QMouseEvent *ev)
{
    QString str= QString("<center><h1>release pos: (%1,%2)</h1></center>")
            .arg(ev->x()).arg(ev->y());
    this->setText(str);
}
// 鼠标拖动 在标签上显示
void MyLabel::mouseMoveEvent(QMouseEvent *ev)
{
    QString str= QString("<center><h1>Move pos: (%1,%2)</h1></center>")
            .arg(ev->x()).arg(ev->y());
    this->setText(str);
}
void MyLabel::leaveEvent(QEvent *ev)
{
    qDebug()<< "mouse leave";
}
void MyLabel::enterEvent(QEvent *ev)
{
    qDebug()<< "mouse enter";
}

  3、键盘事件

void keyPressEvent(QKeyEvent *event);   // 键盘事件 声明需要的事件

  4、键盘事件处理(函数的实现)

void Widget::keyPressEvent(QKeyEvent *ev)
{
    // ev->key(); 返回的ASCII码格式 可以直接转换
    qDebug()<<(char)ev->key();  // 
}

  5、定时器事件

void timerEvent(QTimerEvent *e);  // 计时器事件

  6、定时器事件处理

// 定时器事件处理
void Widget::timerEvent(QTimerEvent *e)
{
    static int sec = 0;
    qDebug()<<++sec;
    // 如果有多个timer需要根据timer ID分别处理 e->timerId() == this->timeID
   // e->timerId()
    if(sec > 10)
    {
        // 关闭定时器
        this->killTimer(timeID);// 根据定时器句柄 关闭定时器
    }
}

// 还需要开启定时器   并指定定时器的步进值(精度)
 this->timeID = this->startTimer(1000); // 启动定时器 间隔1000ms 返回定时器句柄

 5、事件接收

在UI界面创建一个按钮pushButton,使用connect()接收该信号,打印提示信息;

 connect(ui->pushButton,&myButton::clicked,
    [=]()
    {
        qDebug()<<"按钮被按下";
    });

新建一个按钮类myButton,并将上述的按钮提升,实现鼠标按下事件

protected:
    void mousePressEvent(QMouseEvent *ev);

实现该事件处理函数

void myButton::mousePressEvent(QMouseEvent *ev)
{
    if(ev->button() == Qt::LeftButton)
    {
        // 事件的接收  事件在这里接收了 就不传到其他位置
        qDebug()<<"按下的是左键";
        //ev->ignore();  // 事件忽略 将事件换递给父控件
    }else {
        // 事件的忽略  // 忽略会传递给符类QPushButton
        QPushButton::mousePressEvent(ev);
    }
}

事件发送出来,只要被接收,就不会往下传,该事件也结束;否则会继续往下传;也可以传给父类做处理

6、事件接收与忽略--》关闭窗口提示

// 需要实现窗口关闭事件
protected:
    void closeEvent(QCloseEvent *ev);

事件处理

void myWidget::closeEvent(QCloseEvent *ev)
{
    int ret = QMessageBox::question(this,"questio","是否需要关闭窗口");
      if (ret == QMessageBox::Yes) {
          // 关闭窗口 接收信号
          ev->accept();
      } else {
          // 不关闭窗口 忽略信号 将信号传递给myWidget
          ev->ignore();
      }
}

 

posted @ 2020-07-31 14:24  笑不出花的旦旦  阅读(340)  评论(0编辑  收藏  举报