在学习Qt时经常会用到事件系统,本文将对一些常用的事件进行汇总,写在这里帮助记忆。
1· 首先明确事件和信号是不一样的概念。比如在一个按钮上点击鼠标时,会产生鼠标事件QMouseEvent(注意不是按钮本身产生的),而因为按钮被按下而发出一个clicked()单击信号(这个是按钮产生的)。这时一般只考虑单击信号而不考虑鼠标事件。但是在设计一个按钮部件的时候,需要在点击按钮时产生其他的效果,那就要实现相应的鼠标事件了。在Qt中,任何QObject的子类的实例都可以接收和处理事件。
2· 常见的事件:鼠标事件,键盘事件,定时器事件,上下文菜单事件,绘制事件,拖放事件,关闭事件等等。本文将主要针对鼠标事件进行展开。
事件的处理方式有很多,一般最常见的有两种:1)重新实现部件的事件处理函数如mousePressEvent();2)在对象上安装事件过滤器。使用事件过滤器可以在一个界面类中同时处理不同子部件的不同事件。
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QLineEdit>
namespace Ui {
class Widget;
}
class QTextEdit;
class myLineEdit : public QLineEdit
{
protected:
//事件处理,方式1: 重新实现具体事件
void keyPressEvent(QKeyEvent *event);
bool event(QEvent *event);
};
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
protected:
//事件处理,方式1: 重新实现具体事件
void keyPressEvent(QKeyEvent *event);
//方式2:安装事件过滤器
bool eventFilter(QObject *obj, QEvent *event);
//具体的鼠标事件
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void mouseDoubleClickEvent(QMouseEvent *event);
void wheelEvent(QWheelEvent *event);
private:
Ui::Widget *ui;
myLineEdit *lineEdit;
QPoint offset;
QTextEdit *textEdit;
};
#endif
#include <QtGui>
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent), ui(new Ui::Widget)
{
ui->setupUi(this);
QTextCodec::setCodecForTr(QTextCodec::codecForName("utf-8"));
lineEdit = new myLineEdit();
textEdit = new QTextEdit(this);
QVBoxLayout *layout = new QVBoxLayout(this);
layout->addWidget(lineEdit);
layout->addWidget(textEdit);
setLayout(layout);
//在Widget上为lineEdit安装事件过滤器
lineEdit->installEventFilter(this);
}
Widget::~Widget()
{
delete ui;
}
//事件处理函数的定义
void myLineEdit::keyPressEvent(QKeyEvent *event)
{
qDebug() << tr("mylineEdit 键盘按下事件");
//执行QLineEdit类默认的事件处理
QLineEdit::keyPressEvent(event);
event->ignore(); //忽略该事件
}
//方式2:安装事件过滤器
bool myLineEdit::event(QEvent *event)
{
//获取事件类型
if(event->type() == QEvent::KeyPress)
qDebug() << tr("myLineEdit: event() 函数");
//执行QLineEdit类的event()函数
return QLineEdit::event(event);
}
//事件处理函数的定义
void Widget::keyPressEvent(QKeyEvent *event)
{
qDebug() << tr("Widget 键盘按下事件");
if(event->modifiers() == Qt::ControlModifier){
if(event->key() == Qt::Key_M)
//按下M键
setWindowState(Qt::WindowMaximized);
else
QWidget::keyPressEvent(event);
}
}
//事件过滤器函数的定义
bool Widget::eventFilter(QObject *obj, QEvent *event)
{
if(obj == lineEdit){
if(event->type() == QEvent::KeyPress)
qDebug() << tr("Widget的事件过滤器");
}
return QWidget::eventFilter(obj,event);
}
//事件会先传递给获得焦点的窗口部件,当当前的窗口部件忽略事件才传给其父窗口
//鼠标事件
void Widget::mousePressEvent(QMouseEvent *event)
{
if(event->button() == Qt::LeftButton){
//左键, 设置光标样式
QCursor cursor;
cursor.setShape(Qt::ClosedHandCursor);
//使鼠标指针暂时改变形状
QApplication::setOverrideCursor(cursor);
//获取指针位置和窗口位置的差值
offset = event->globalPos() - pos();
} else if(event->button() == Qt::RightButton){
//右键, 则显示自定义图片作为鼠标指针
QCursor cursor(QPixmap("./circle.png"));
QApplication::setOverrideCursor(cursor);
}
}
//使用鼠标移动窗口部件
void Widget::mouseMoveEvent(QMouseEvent *event)
{
if(event->buttons() & Qt::LeftButton){
QPoint temp;
//使用鼠标指针当前位置减去差值,得到窗口应该移动的位置
temp = event->globalPos() - offset;
move(temp);
}
}
//鼠标释放函数,恢复鼠标形状
void Widget::mouseReleaseEvent(QMouseEvent */*event*/)
{
QApplication::restoreOverrideCursor();
//restoreOverrideCursor 与 setOverrideCursor 相对应
}
//鼠标双击事件,最大化窗口和恢复大小
void Widget::mouseDoubleClickEvent(QMouseEvent *event)
{
if(event->button() == Qt::LeftButton){
if(windowState() != Qt::WindowFullScreen)
setWindowState(Qt::WindowFullScreen);
else
setWindowState(Qt::WindowNoState);
}
}
void Widget::wheelEvent(QWheelEvent *event)
{
if(event->delta() >0){
//当滚轮远离使用者时
textEdit->zoomIn(); //进行放大
} else {
textEdit->zoomOut(); //缩小
}
}