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(); } }