前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >【QT】QT事件处理

【QT】QT事件处理

作者头像
半生瓜的blog
发布于 2023-05-13 05:55:34
发布于 2023-05-13 05:55:34
1.6K00
代码可运行
举报
文章被收录于专栏:半生瓜のblog半生瓜のblog
运行总次数:0
代码可运行

事件处理

QT中,事件作为一个对象,继承自QEvent类,常见的有键盘事件QKeyEvent、鼠标事件QMouseEvent和定时器事件QTimerEvent等。QT中,任何QObject子类示例都可以接收和处理事件。实际编程中通常实现部件的paintEvent()、mousePressEvent()等事件处理函数来处理特定部件的特定事件。

每个程序的main函数最后都会调用QApplication类的exec()函数,它会使QT应用程序进入到事件循环,使应用程序在运行的时候接收各种事件。一旦有事件发生,QT便会构造一个相应的QEvent子类的对象来表示它,然后将它传递给QObject对象或子对象。


鼠标事件

对鼠标实现进行重写来实现你想要达到的功能

mouseevent.h

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#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);
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-02-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Qt编写安防视频监控系统9-自动隐藏光标
这个效果的灵感来自于大屏电子看板系统,在很多系统中尤其是上了大屏的时候,其实在用户不在操作的时候,是很不希望看到那个鼠标箭头指针的,只有当用户操作的时候才显示出来,这个就需要开个定时器定时计算最后一次用户操作的时间,和当前时间比较,如果超过了鼠标未操作隐藏时间,则隐藏鼠标,在Qt中提供了方法qApp->setOverrideCursor(Qt::BlankCursor);这样设置个空白的鼠标指针就表示隐藏鼠标,如果需要恢复调用qApp->restoreOverrideCursor();即可,怎么触发恢复鼠标指针呢?搞个bool存储当前鼠标是否隐藏,在鼠标隐藏的时候置为真,拦截鼠标移动事件,一旦发现之前鼠标处于隐藏状态,则立即恢复指针状态,同时将标志位改为假,不然频繁恢复指针没有意义,只有当指针隐藏的时候才需要恢复一次。
feiyangqingyun
2019/08/21
1.5K0
Qt编写安防视频监控系统9-自动隐藏光标
QT入门学习——从鼠标事件,定时器事件到绘图学习,绘图设备
Arya
2024/11/06
2330
QT入门学习——从鼠标事件,定时器事件到绘图学习,绘图设备
用Qt写软件系列五:一个安全防护软件的制作(1)
引言       又有许久没有更新了。Qt,我心爱的Qt,为了找工作不得不抛弃一段时间,业余时间来学一学了。本来计划要写一系列关于Qt组件美化的博文,但是写了几篇之后就没坚持下去了。技术上倒是问题不大,主要是时间不够充裕。这段时间写几篇关于界面整体设计的博文,从最基础的界面元素开始,到最后构建一个页面元素丰富的桌面应用程序。Trojan Assessment Platform是一个原型设计项目,只是实现了有限的一部分功能。远远还称不上是一个评估平台。这里仅仅侧重于用Qt做界面的实现。 界面预览      
24K纯开源
2018/01/18
1.5K0
用Qt写软件系列五:一个安全防护软件的制作(1)
python pyqt5 事件过滤器
from PyQt5.QtGui import * from PyQt5.QtCore import * from PyQt5.QtWidgets import * import sys
用户5760343
2019/07/22
1.5K0
【QT】事件分发器 & 事件过滤器
在 Qt 中,事件分发器(Event Dispatcher) 是一个核心概念,用于处理 GUI 应用程序中的事件。事件分发器负责将事件从⼀个对象传递到另⼀个对象,直到事件被处理或被取消。每个继承自 QObject 类或 QObject 类本身都可以在本类中重写 bool event(QEvent *e) 函数,来实现相关事件的捕获和拦截。
YoungMLet
2024/07/27
5340
【QT】事件分发器 & 事件过滤器
19.QT-事件发送函数sendEvent()、postEvent()
Qt发送事件分为两种 -阻塞型事件发送 需要重写接收对象的event()事件处理函数 当事件发送后,将会立即进入event()事件处理函数进行事件处理 通过sendEvent()静态函数实现阻塞发送: bool QApplication::sendEvent ( QObject * receiver, QEvent * event ) ; // receiver:接收对象, event :要发送的event类型(比如:鼠标双击) //当有事件发送,将会
诺谦
2018/05/28
3.3K0
Qt编写自定义控件30-颜色多态按钮
这个控件一开始打算用样式表来实现,经过初步的探索,后面发现还是不够智能以及不能完全满足需求,比如要在此控件设置多个角标,这个用QSS就很难实现,后面才慢慢研究用QPainter来绘制,我记得当时接到这个定制控件任务的时候是2016年,那时候对QPainter的使用还不是很熟悉,也就是从此控件开始,逐步研究QPainter的绘制,把所有的内置函数都使用一遍,最终用的越来越熟悉,使得后来到了心中有坐标,万物皆painter的境界,可能就像武林中所说的打通了任督二脉吧。
feiyangqingyun
2019/08/27
2.1K0
Qt编写自定义控件30-颜色多态按钮
【QT】Qt事件
事件是应用程序内外部产生的事情以及动作的统称,常见的所有事件例如鼠标事件QMouseEvent,键盘事件QKeyEvent等等都是继承自QEvent
s-little-monster
2024/11/06
2480
【QT】Qt事件
自定义Qt对话框
今天就简单简单写个自定义对话框分享给大家。 演示 上代码! 自定义对话框的使用: #include <QApplication> #include <QDebug> #include "Dialog
Qt君
2020/07/17
1.7K0
Qt编写自定义控件35-GIF录屏控件
在平时的写作过程中,经常需要将一些操作动作和效果图截图成gif格式,使得涵盖的信息更全面更生动,有时候可以将整个操作过程和运行效果录制成MP4,但是文件体积比较大,而且很多网站不便于上传,基本上都支持gif动图,一般一个5秒左右的gif,800*600分辨率,可以很好的控制在500KB内,这样就比较完美的支持各大网站上传动图。
feiyangqingyun
2019/08/27
1.5K0
Qt编写自定义控件35-GIF录屏控件
【QT】事件系统入门——QEvent 基础与示例
事件本身是 操作系统提供的 机制,Qt 也同样把操作系统事件机制进行了封装拿到了 Qt 中,但由于 事件 对应的代码编写起来不方便,因此 Qt 对于事件机制 又进行了进一步的 封装,就得到了 信号槽
IsLand1314
2025/03/14
1400
【QT】事件系统入门——QEvent 基础与示例
FFMPEG音频视频开发: 开发本地视频播放器(单线程解码)
ffmpeg与x264源码开源,可以在任意平台上编译。自行下载源码编译得到库文件即可。
DS小龙哥
2022/01/12
1.4K0
FFMPEG音频视频开发: 开发本地视频播放器(单线程解码)
qt学习笔记(五) QGraphicsPixmapItem与QGraphicsScene的编程实例 图标拖动渐变效果
应大家的要求,还是把完整的project文件贴出来,大家省点事:http://www.kuaipan.cn/file/id_48923272389086450.htm
全栈程序员站长
2022/07/12
1.9K0
qt学习笔记(五) QGraphicsPixmapItem与QGraphicsScene的编程实例 图标拖动渐变效果
Qt实战:云曦日历篇
自国务院印发《推进普惠金融发展规划(2016—2020年)》通知以来,各省、自治区、直辖市人民政府、国务院各部委各直属机构积极响应,认真贯彻执行,普惠金融发展已经进入了高潮阶段,各大互联网公司和高校紧跟时代潮流,推出了各种创新性产品和软件,该软件作为一款以培养兴趣,提高学生软件项目的编程项目能力为目的,所创建的一款实用性的软件,以日历为依托,创建了许多相关的特效,优美界面和天气查询、日程管理等实用性功能,且界面等均符合当下青少年的审美需求,是一款紧跟潮流的日历软件
灵彧
2022/10/31
1.5K0
Qt实战:云曦日历篇
20.QT-Qpixmap实现图片鼠标缩放,鼠标拖动示例(详解)
通过 QPainter 绘画实现,以本地图片985*740为例 如下图所示: 效果如下所示: 实现原理 主要通过以下函数实现: void QPainter::drawTiledPixmap ( int
诺谦
2018/05/28
4.1K0
浅谈基于QT的截图工具的设计与实现
在介绍截图工具设计与实现前,让我们先通过介绍QT的绘图基础知识,让读者有一个比较感性的认识。
w4ngzhen
2023/10/18
5330
浅谈基于QT的截图工具的设计与实现
Qt入门系列(四)
新建一个class C++:ChoselevelScence,简称cs,继承QMainWIndow
用户9831583
2022/06/16
9750
Qt入门系列(四)
Qt中自定义QTreeWidget实现节点拖拽复制功能[通俗易懂]
QT中在QWidget支持拖拽功能,QTreeWidget继承自QWidget,所以自然也具有节点的拖拽功能。
全栈程序员站长
2022/11/14
4.6K0
Qt中自定义QTreeWidget实现节点拖拽复制功能[通俗易懂]
Qt学习之路_14(简易音乐播放器)
  这一节实现一个简易的音乐播放器,其音乐播放的核心功能是采用Qt支持的Phonon框架,该框架在前一篇博文Qt学习之路_13(简易俄罗斯方块) 中已经使用过了,在俄罗斯方块中主要是用来设置背景音乐和消行的声音的。这里用这个框架同样是用来播放,暂停等多媒体的各种控制功能,另外该框架可以自动获取音频文件的一些信息,这样我们在设计播放列表时可以获取这些信息,比如歌手名,专辑名,时长,文件名等等。程序中桌面歌词的实现是继承了QLabel类,然后使用3层文本显示,最上面一层采用渐进显示的方式来达到歌词播放的动态效果。
bear_fish
2018/09/20
2.1K0
Qt学习之路_14(简易音乐播放器)
【QT】鼠标按键事件 - QMouseEvent & QKeyEvent
事件是应用程序内部或者外部产生的事情或者动作的统称。在 Qt 中使用⼀个对象来表⽰⼀个事件。所有的 Qt 事件均继承于抽象类 QEvent。事件是由系统或者 Qt 平台本⾝在不同的时刻发出的。当用户按下⿏标、敲下键盘,或者是窗⼝需要重新绘制的时候,都会发出⼀个相应的事件。⼀些事件是在用户操作时发出,如键盘事件、⿏标事件等,另⼀些事件则是由系统本⾝⾃动发出,如定时器事件。常见的 Qt 事件如下:
YoungMLet
2024/07/20
1.1K0
【QT】鼠标按键事件 - QMouseEvent & QKeyEvent
推荐阅读
相关推荐
Qt编写安防视频监控系统9-自动隐藏光标
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档