本文讲的是QT中的事件及其响应。首先信号和事件是两个层面的东西,我简单的理解为人机界面交互中,输入设备如鼠标、键盘的操作,还有定时器产生的动作。这个解释并不准确,但先这么解释吧。
应用上:一个MainWindow里有好几个控件,我按下键盘后,要A控件响应,B控件不响应 如何实现呢?
首先:要知道事件是先到MainWindow还是先到控件的;//顺序:先MainWindow 后控件
其次:A、B控件接收的顺序是由什么决定的;//顺序:控件创建的顺序
最后:如何控制控件忽略事件。 //MainWindow、B中分别创建事件过滤函数 调用顺序
调用顺序:事件产生->焦点窗口->父窗口
具体步骤:
1.创建MainWindow和2个响应事件的控件类。
响应事件的控件类MyLineEdit;
响应事件并含过滤器功能的MyLineEditFilter。
MyLineEditQ创建一个含QKeyEvent *event 参数的函数。
void MyLineEdit::keyPressEvent(QKeyEvent *event) // 键盘按下事件
{
qDebug() << tr("MyLineEdit键盘按下事件");
QLineEdit::keyPressEvent(event); // 执行QLineEdit类的默认事件处理
event->ignore(); // 忽略该事件
}
MyLineEditFilter除了创建含QKeyEvent *event 参数的函数外还要创建一个含返回为bool ,含QEvent *event类型的函数。
bool event(QEvent *event)
{return QLineEdit::event(event);}
2. MainWindow中调用控件
2.1创建控件
MyLineEdit plineEdit = new MyLineEdit(this);
MyLineEditFilter plineEditFilter=new MyLineEditFilter(this);
过滤器类调用需要多一个函数
plineEditFilter->installEventFilter(this);
2.2 MainWindow 添加事件过滤函数
bool MainWindow ::eventFilter(QObject *obj, QEvent *event) //
{
if(obj == plineEditFilter){ // 如果是plineEditFilter部件上的事件
if(event->type() == QEvent::KeyPress)
qDebug() << tr("Widget的事件过滤器");
}
return QWidget::eventFilter(obj, eve
}
代码实例
MainWindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "mylineedit.h"
#include "mylineeditfilter.h"
#include <QKeyEvent>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
plineEdit = new MyLineEdit(this);
plineEdit->move(100, 100);
plineEditFilter=new MyLineEditFilter(this);
plineEditFilter->move(100, 150);
plineEditFilter->installEventFilter(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::keyPressEvent(QKeyEvent *event)
{
qDebug() << tr("MainWindow键盘按下事件");
}
bool MainWindow::eventFilter(QObject *obj, QEvent *event) // 事件过滤器
{
if(obj == plineEditFilter){ // 如果是lineEdit部件上的事件
if(event->type() == QEvent::KeyPress)
qDebug() << tr("MainWindow的事件过滤器");
}
return QWidget::eventFilter(obj, event);
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
//引入头文件的方式两种 NAMESPACE 和include
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
class MyLineEdit;
class MyLineEditFilter;
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
bool eventFilter(QObject *obj, QEvent *event);
void keyPressEvent(QKeyEvent *event);
private:
Ui::MainWindow *ui;
MyLineEdit *plineEdit;
MyLineEditFilter *plineEditFilter;
};
#endif // MAINWINDOW_H
mylineedit.h
#ifndef MYLINEEDIT_H
#define MYLINEEDIT_H
#include <QLineEdit>
class MyLineEdit : public QLineEdit
{
Q_OBJECT
public:
explicit MyLineEdit(QWidget *parent = 0);
protected:
void keyPressEvent(QKeyEvent *event);
};
#endif // MYLINEEDIT_H
mylineedit.cpp
#include "mylineedit.h"
#include <QKeyEvent>
#include <QDebug>
MyLineEdit::MyLineEdit(QWidget *parent):
QLineEdit(parent)
{
}
void MyLineEdit::keyPressEvent(QKeyEvent *event) // 键盘按下事件
{
qDebug() << tr("MyLineEdit键盘按下事件");
QLineEdit::keyPressEvent(event); // 执行QLineEdit类的默认事件处理
event->ignore(); // 忽略该事件
}
MyLineEditFilter.h
#ifndef MYLINEEDITFILTER_H
#define MYLINEEDITFILTER_H
#include <QLineEdit>
class MyLineEditFilter : public QLineEdit
{
Q_OBJECT
public:
explicit MyLineEditFilter(QWidget *parent = 0);
bool event(QEvent *event);
protected:
void keyPressEvent(QKeyEvent *event);
};
#endif // MYLINEEDITFILTER_H
MyLineEditFilter.cpp
#include "mylineeditfilter.h"
#include <QKeyEvent>
#include <QDebug>
MyLineEditFilter::MyLineEditFilter(QWidget *parent):
QLineEdit(parent)
{
}
void MyLineEditFilter::keyPressEvent(QKeyEvent *event) // 键盘按下事件
{
qDebug() << tr("MyLineEditFilter键盘按下事件");
QLineEdit::keyPressEvent(event); // 执行QLineEdit类的默认事件处理
event->ignore(); // 忽略该事件
}
bool MyLineEditFilter::event(QEvent *event) // 事件
{
if(event->type() == QEvent::KeyPress)
qDebug() << tr("MyLineEditFilter的event()函数");
return QLineEdit::event(event); // 执行QLineEdit类event()函数的默认操作
}