QT中,事件作为一个对象,继承自QEvent类,常见的有键盘事件QKeyEvent、鼠标事件QMouseEvent和定时器事件QTimerEvent等。QT中,任何QObject子类示例都可以接收和处理事件。实际编程中通常实现部件的paintEvent()、mousePressEvent()等事件处理函数来处理特定部件的特定事件。
每个程序的main函数最后都会调用QApplication类的exec()函数,它会使QT应用程序进入到事件循环,使应用程序在运行的时候接收各种事件。一旦有事件发生,QT便会构造一个相应的QEvent子类的对象来表示它,然后将它传递给QObject对象或子对象。
对鼠标实现进行重写来实现你想要达到的功能。
mouseevent.h
#ifndef MOUSEEVENT_H
#define MOUSEEVENT_H
#include <QMainWindow>
#include<QLabel>
#include<QMouseEvent>
namespace Ui {
class MouseEvent;
}
class MouseEvent : public QMainWindow
{
Q_OBJECT
public:
explicit MouseEvent(QWidget *parent = 0);
~MouseEvent();
protected:
void mousePressEvent(QMouseEvent *event);//鼠标按下
void mouseMoveEvent(QMouseEvent *event);//鼠标移动
void mouseReleaseEvent(QMouseEvent *event);//鼠标释放
private:
Ui::MouseEvent *ui;
QLabel *m_statusLabel;
QLabel* m_posLabel;
};
#endif // MOUSEEVENT_H
mouseevent.cpp
#include "mouseevent.h"
#include "ui_mouseevent.h"
MouseEvent::MouseEvent(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MouseEvent)
{
ui->setupUi(this);
setWindowTitle(QString("鼠标事件"));
m_statusLabel = new QLabel(QString("当前位置:"));
m_statusLabel->setFixedWidth(100);
m_posLabel = new QLabel(QString(""));
m_posLabel->setFixedWidth(100);
statusBar()->addPermanentWidget(m_statusLabel);//状态栏添加永久部件
statusBar()->addPermanentWidget(m_posLabel);
}
MouseEvent::~MouseEvent()
{
delete ui;
}
void MouseEvent::mousePressEvent(QMouseEvent *event)
{
QString str = "("+QString::number(event->x())+","+QString::number(event->y())+")";
if(event->button() == Qt::LeftButton)
{
statusBar()->showMessage(QString("左键:") +str );
}
else if(event->button() == Qt::MidButton)
{
statusBar()->showMessage(QString("中键:")+str);
}
else if(event->button() == Qt::RightButton)
{
statusBar()->showMessage(QString("右键")+str);
}
}
void MouseEvent::mouseMoveEvent(QMouseEvent *event)
{
QString strPos;
strPos = "(" + QString::number(event->x())+","+QString::number(event->y())+")";
m_posLabel->setText(strPos);
}
void MouseEvent::mouseReleaseEvent(QMouseEvent *event)
{
QString strPos;
strPos = "(" + QString::number(event->x())+","+QString::number(event->y())+")";
statusBar()->showMessage(QString("释放在:")+strPos,3000);
}
通过重写键盘事件来达到你想要实现的效果。
keyevent.h
#ifndef KEYEVENT_H
#define KEYEVENT_H
#include <QWidget>
#include<QKeyEvent>
namespace Ui {
class KeyEvent;
}
class KeyEvent : public QWidget
{
Q_OBJECT
public:
explicit KeyEvent(QWidget *parent = 0);
~KeyEvent();
void drawPix();
void keyPressEvent(QKeyEvent *event) override;
void paintEvent(QPaintEvent* event)override;
private:
Ui::KeyEvent *ui;
QPixmap *m_pix;
QImage m_image;
int m_startX; //图标顶点位置
int m_startY;
int m_width; //界面的宽度,高度
int m_height;
int m_step; //步长
};
#endif // KEYEVENT_H
keyevent.cpp
#include "keyevent.h"
#include "ui_keyevent.h"
#include<QPainter>
#include<QPen>
KeyEvent::KeyEvent(QWidget *parent) :
QWidget(parent),
ui(new Ui::KeyEvent)
{
ui->setupUi(this);
setWindowTitle(QString("键盘事件"));
setAutoFillBackground(true);
setFixedSize(521,256);
m_width = size().width();
m_height = size().height();
m_pix = new QPixmap(m_width,m_height);
m_pix->fill(Qt::white);
m_image.load("picture.jpg");
m_startX = 100;
m_startY = 100;
m_step = 20;
drawPix();
}
KeyEvent::~KeyEvent()
{
delete ui;
}
void KeyEvent::drawPix()
{
m_pix->fill(Qt::white);
QPainter painter(this);
QPen pen(Qt::DotLine);
//按照步长画纵向网格线
//bagin与end成对出现
for(int i = m_step;i < m_width; i+=m_step)
{
painter.begin(m_pix);//指定m_pix为绘图设备
painter.setPen(pen);//设置笔
painter.drawLine(QPoint(i,0),QPoint(i,height()));
painter.end();
}
//按照步长画水平网格线
for(int j = m_step;j < m_height;j += m_step)
{
painter.begin(m_pix);//指定m_pix为绘图设备
painter.setPen(pen);//设置笔
painter.drawLine(QPoint(0,j),QPoint(m_width,j));
painter.end();
}
//画图片
painter.begin(m_pix);
painter.drawImage(QPoint(m_startX,m_startY),m_image);
painter.end();
}
void KeyEvent::keyPressEvent(QKeyEvent *event)
{
//按下ctrl,每次移动为1个像素
if(event->modifiers() == Qt::ControlModifier)
{
if(event->key() == Qt::Key_Left)
{
m_startX = (m_startX -1)<0 ? m_startX : m_startX-1;
}
if(event->key() == Qt::Key_Right)
{
m_startX = (m_startX +1+m_image.width()) > m_width ? m_startX :m_startX+1 ;
}
if(event->key() == Qt::Key_Up)
{
m_startY = (m_startY - 1) < 0 ? m_startY:m_startY -1;
}
if(event->key() == Qt::Key_Down)
{
m_startY = (m_startY +1 +m_image.height()) > m_height ? m_startY:m_startY+1;
}
}
else//没有按ctrl键,每一移动为一个步长
{
//调整图标左上角位置到网格顶点顶点上
m_startX = m_startX - m_startX % m_step;
m_startY =m_startY - m_startY % m_step;
if(event->key() == Qt::Key_Left)
{
m_startX = (m_startX -m_step)<0 ? m_startX : m_startX-m_step;
}
if(event->key() == Qt::Key_Right)
{
m_startX = (m_startX +m_step+m_image.width()) > m_width ? m_startX :m_startX+m_step ;
}
if(event->key() == Qt::Key_Up)
{
m_startY = (m_startY - m_step) < 0 ? m_startY:m_startY -m_step;
}
if(event->key() == Qt::Key_Down)
{
m_startY = (m_startY +m_step +m_image.height()) > m_height ? m_startY:m_startY+m_step;
}
}
drawPix();//根据调整后的图标位置重新在m_pix上绘制图像
update();//触发窗口重绘
}
void KeyEvent::paintEvent(QPaintEvent *event)
{
QPainter painter;
painter.begin(this);
painter.drawPixmap(QPoint(0,0),*m_pix);
painter.end();
}
指定某个对象对什么事件进行处理。
**示例:**鼠标按压对指定图片进行缩放
dialog.h
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include<QLabel>
#include<QImage>
#include<QHBoxLayout>
#include<QEvent>
#include<QMouseEvent>
class Dialog : public QDialog
{
Q_OBJECT
public:
Dialog(QWidget *parent = 0,Qt::WindowFlags f = 0);
~Dialog();
public slots:
bool eventFilter(QObject*watched ,QEvent *event)override;
private:
QLabel *m_label1;
QLabel *m_label2;
QLabel *m_label3;
QLabel *m_stateLabel;
QImage m_image1;
QImage m_image2;
QImage m_image3;
};
#endif // DIALOG_H
dialog.cpp
#include "dialog.h"
#include<QHBoxLayout>
Dialog::Dialog(QWidget *parent,Qt::WindowFlags f)
: QDialog(parent,f)
{
setWindowTitle(QString("事件过滤"));
m_label1 = new QLabel;
m_label2 =new QLabel;
m_label3 = new QLabel;
m_stateLabel = new QLabel(QString("鼠标按下标志"));
m_stateLabel->setAlignment(Qt::AlignHCenter);//水平居中
m_image1.load("fly1.png");
m_image2.load("fly2.png");
m_image3.load("fly3.png");
m_label1->setPixmap(QPixmap::fromImage(m_image1));
m_label2->setPixmap(QPixmap::fromImage(m_image2));
m_label3->setPixmap(QPixmap::fromImage(m_image3));
//添加水平布局
QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(m_label1);
layout->addWidget(m_label2);
layout->addWidget(m_label3);
QVBoxLayout*mainLayout = new QVBoxLayout(this);
mainLayout->addLayout(layout);
mainLayout->addWidget(m_stateLabel);
resize(m_image2.width() * 3,m_image2.height() *2);
//给图片标签部件安装事件过滤,并且指定整个窗体为监视事件的对象。
m_label1->installEventFilter(this);
m_label2->installEventFilter(this);
m_label3->installEventFilter(this);
}
Dialog::~Dialog()
{
}
//对象-事件
bool Dialog::eventFilter(QObject *watched, QEvent *event)
{
QMatrix matrix;//放大比例
QImage tmpImg;//保存处理过后的图片
//放大图片
matrix.scale(2.0,2.0);
//对象
if(watched == m_label1)
{
//鼠标按下事件的处理
if(event->type() == QEvent::MouseButtonPress)
{
//转换事件类型Wie鼠标事件
QMouseEvent* mouseEvent = (QMouseEvent*)event;
if(mouseEvent->button() & Qt::LeftButton)
{
m_stateLabel->setText(QString("左键按下图片1"));
}
if(mouseEvent->button() & Qt::MidButton)
{
m_stateLabel->setText(QString("中键按下图片1"));
}
if(mouseEvent->button() & Qt::RightButton)
{
m_stateLabel->setText(QString("右键按下图片1"));
}
//将原本图片缩放用tmpImg临时存储,设置图片
tmpImg = m_image1.transformed(matrix);
m_label1->setPixmap(QPixmap::fromImage(tmpImg));
}
//鼠标释放,恢复图片大小
if(event->type() == QEvent::MouseButtonRelease)
{
m_stateLabel->setText(QString("鼠标释放图片1"));
m_label1->setPixmap(QPixmap::fromImage(m_image1));
}
}
else if(watched ==m_label2)
{
if(event->type() == QEvent::MouseButtonPress)
{
QMouseEvent* mouseEvent = (QMouseEvent*)event;
if(mouseEvent->button() & Qt::LeftButton)
{
m_stateLabel->setText(QString("左键按下图片2"));
}
if(mouseEvent->button() & Qt::MidButton)
{
m_stateLabel->setText(QString("中键按下图片2"));
}
if(mouseEvent->button() & Qt::RightButton)
{
m_stateLabel->setText(QString("右键按下图片2"));
}
tmpImg = m_image2.transformed(matrix);
m_label2->setPixmap(QPixmap::fromImage(tmpImg));
}
if(event->type() == QEvent::MouseButtonRelease)
{
m_stateLabel->setText(QString("鼠标释放图片2"));
m_label2->setPixmap(QPixmap::fromImage(m_image2));
}
}
else if(watched ==m_label3)
{
if(event->type() == QEvent::MouseButtonPress)
{
QMouseEvent* mouseEvent = (QMouseEvent*)event;
if(mouseEvent->button() & Qt::LeftButton)
{
m_stateLabel->setText(QString("左键按下图片3"));
}
if(mouseEvent->button() & Qt::MidButton)
{
m_stateLabel->setText(QString("中键按下图片3"));
}
if(mouseEvent->button() & Qt::RightButton)
{
m_stateLabel->setText(QString("右键按下图片3"));
}
tmpImg = m_image3.transformed(matrix);
m_label3->setPixmap(QPixmap::fromImage(tmpImg));
}
if(event->type() == QEvent::MouseButtonRelease)
{
m_stateLabel->setText(QString("鼠标释放图片3"));
m_label3->setPixmap(QPixmap::fromImage(m_image3));
}
}
//事件交给上层对话框进行处理
return QDialog::eventFilter(watched,event);
}