Qt中的事件和信号的作用都是为了使程序知道程序内部或外部的事情或者动作发生。任何QOBject子类实例都可以接收和处理事件。原理就是放入了消息循环,有事件发生就调用相关的处理函数。更全面的事件,在Qt帮助文档搜索The Event System。
常用的事件有鼠标、键盘、定时器等,下面代码实现了常用事件的使用,基本用法都是一样。
Qt还提供了事件过滤器来在一个部件中监控其他多个部件的事件,它并不是一个类,是由一对函数构成。函数名为installEventFilter()和eventFilter(),是QObject类中的方法。某个部件使用事件过滤器,先对这个部件安装过滤器。
Qt也提供了发送事件的功能,由sendEvent()和postEvent()函数执行,是QCoreApplication类的方法。两个函数的主要区别在于,前一个函数会立即发送,而后一个函数会放入队列中,等下一次消息循环时发送。也就导致了前一个函数需要在栈中创建,而后一个函数需要new在堆上创建。
常用的5种事件处理方法:(经常使用1和5)
- 重新实现部件的mousePressEvent()等事件处理函数。最常用,但是只能处理特定部件的特定事件。
- 重新实现notify()函数。这个函数功能和控制都足够全,并且再过滤器之前就能捕获事件,但是一次只能处理一个事件,并且需要继承自QApplication类。
- 在QApplication的对象上安装事件过滤器。一个应用程序只会有一个QApplication的对象,所以功能与notify()的功能一样,但是能够处理多个事件,但是要使用全局事件过滤器,这将减缓事件的传递。
- 重新实现event()函数。QObject类的event()函数可以再事件达到默认的事件处理函数之前就捕获到。
- 在对象上安装事件过滤器。使用事件过滤器可以再一个界面类中同事处理不同子部件的不同事件。
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include<QLabel>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
void keyPressEvent(QKeyEvent *event);
void keyReleaseEvent(QKeyEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void mouseDoubleClickEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void wheelEvent(QWheelEvent *event);
void timerEvent(QTimerEvent *event);
bool eventFilter(QObject *obj,QEvent *event);
private:
Ui::MainWindow *ui;
QLabel *label;
QPoint offset;
int timerId;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QKeyEvent>
#include<QMouseEvent>
#include<QDebug>
#include<QWheelEvent>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QCursor cursor;
cursor.setShape(Qt::OpenHandCursor);
setCursor(cursor);
timerId = startTimer(1000);
ui->lineEdit->installEventFilter(this);
QKeyEvent myEvent(QEvent::KeyPress, Qt::Key_0, Qt::NoModifier );
qApp->sendEvent(ui->lineEdit, &myEvent);
}
MainWindow::~MainWindow()
{
delete ui;
}
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
if(obj == ui->lineEdit){
if(event->type() == QEvent::Wheel){
ui->lineEdit->setText("Slid in lineedit!");
}
}
}
void MainWindow::keyPressEvent(QKeyEvent *event)
{
qDebug("keyboard pressed");
qDebug()<<event->key() ;
}
void MainWindow::keyReleaseEvent(QKeyEvent *event)
{
qDebug("Keyboard released!");
}
void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
if(event->buttons() & Qt::LeftButton){
QPoint temp;
temp = event->globalPos() - offset;
move(temp);
}
}
void MainWindow::mousePressEvent(QMouseEvent *event)
{
if(event->button() == Qt::LeftButton){
QCursor cursor;
cursor.setShape(Qt::ClosedHandCursor);
QApplication::setOverrideCursor(cursor);
offset = event->globalPos() - pos();
qDebug("Left mouse pressed!");
}else{
qDebug("Right mouse pressed!");
}
}
void MainWindow::mouseReleaseEvent(QMouseEvent *event)
{
QApplication::restoreOverrideCursor();
qDebug("Released!");
}
void MainWindow::mouseDoubleClickEvent(QMouseEvent *event)
{
if(event->button() == Qt::LeftButton){
if(windowState() != Qt::WindowFullScreen)
setWindowState(Qt::WindowFullScreen);
else setWindowState(Qt::WindowNoState);
}
qDebug("Double click!");
}
void MainWindow::wheelEvent(QWheelEvent *event)
{
if(event->delta() > 0){
qDebug("Slide up!");
}else {
qDebug("Slide down!");
}
}
void MainWindow::timerEvent(QTimerEvent *event)
{
if(event->timerId() == timerId)
qDebug("Timer event is running!");
}