Qt知识笔记(八)—— 鼠标和事件

这篇具有很好参考价值的文章主要介绍了Qt知识笔记(八)—— 鼠标和事件。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

鼠标事件

默认情况下,触发事件需要点击一下,才能触发。可设置为自动触发:setMouseTracking(true);
鼠标事件有单机,双击,释放,移动,滑轮

单机:void mousePressEvent(QMouseEvent *event);
双击:void mouseDoubleClickEvent(QMouseEvent *event);
释放:void mouseReleaseEvent(QMouseEvent *event);
移动:void mouseMoveEvent(QMouseEvent *event);
滑轮:void wheelEvent(QWheelEvent *event);

想要实现指定控件的鼠标事件,要将控件提升为自定义类,然后在类中重写对应的鼠标事件。

指定鼠标键

如何指定鼠标左键还是右键触发事件呢?
在重写函数中进行判断即可,如:

//鼠标左键按下
void myLabel::mousePressEvent(QMouseEvent *ev)
{
    if(ev->button()==Qt::LeftButton)
    {
    	......
    }
}
//鼠标左键释放
void myLabel::mouseReleaseEvent(QMouseEvent *ev)
{
    if(ev->button()==Qt::LeftButton)
    {
    	......
    }
}

//鼠标左键移动
void myLabel::mouseMoveEvent(QMouseEvent *ev)
{
    if(ev->button()==Qt::LeftButton)
    {
    	......
    }
}

鼠标联合按键

鼠标点击、释放、移动三个时间的具体实现,if条件判断的是事件是否由鼠标左键触发,如果三个条件全部写成ev->button()==Qt::LeftButton,运行时会发现鼠标移动事件不做反应。解决的方法是将原本的条件改为ev->buttons() == Qt::LeftButton这样,在点击鼠标左键后进行移动,就会做出反应。
button() 仅仅返回的是触发事件时的按键,而buttons() 返回的是鼠标的状态,包括鼠标左中右三键的联合信息。

//&为位与运算符,只有在所有状态下均为左键按下时为真
if(ev->buttons() & Qt::LeftButton)
{
    ......
}

右键菜单

鼠标右键弹出菜单可以通过重写鼠标事件实现,也可以通过重写从父类继承的虚函数 void contextMenuEvent(QContextMenuEvent *event)来实现。
1.在类中声明

protected:
    // 如果窗口设置了 Qt::DefaultContextMenu 策略, 
    // 点击鼠标右键该函数被Qt框架调用
    void contextMenuEvent(QContextMenuEvent *event) override;

2.在这个窗口类的构造函数设置右键菜单策略

 setContextMenuPolicy(Qt::DefaultContextMenu);

3.在这个窗口类的源文件中重写事件处理器函数 contextMenuEvent()

void MainWindow::contextMenuEvent(QContextMenuEvent *event)
{
	......
}

除了上面的策略,还有两个策略Qt::ActionsContextMenuQt::CustomContextMenu,这两个策略这里就不介绍了。

事件

在 Qt 框架内部为我们提供了一系列的事件处理机制,当窗口事件产生之后,事件会经过:事件派发 -> 事件过滤->事件分发->事件处理几个阶段。Qt 窗口中对于产生的一系列事件都有默认的处理动作,如果我们有特殊需求就需要在合适的阶段重写事件的处理动作。
事件分发过程:

1.事件产生之后,Qt 应用程序对象调用 notify() 函数将事件发送到指定的窗口
2.事件在发送过程中可以通过事件过滤器进行过滤,默认不对任何产生的事件进行过滤
3.事件发送到指定窗口之后,窗口的事件分发器会对收到的事件进行分类
4.事件分发器将分类之后的事件(如鼠标事件、键盘事件等)分发给对应的事件处理器函数进行处理

事件处理器

每个事件处理器函数都对应一个唯一的事件,事件处理器函数都是回调函数,也就是说作为使用者只需要指定函数的处理动作,关于函数的调用是不需要进行操作的,当某个事件被触发,Qt 框架会调用对应的事件处理器函数。
常用的事件处理器函数:

鼠标事件
键盘事件
窗口重绘
窗口关闭
重置窗口大小

可以在 Qt 的任意一个窗口类中重写这些事件处理器函数来重定义它们的行为。

事件分发器

当事件产生被发送到对应的窗口之后,窗口并不会直接处理这个事件,而是对这些事件进行细分,然后根据事件的类型再次进行分发,对应的事件处理器函数得到这个分发的事件之后就开始处理这个事件。
关于窗口事件的分发,对应一个事件分发器

[override virtual protected] bool QWidget::event(QEvent *event);

关于事件类型的判断是基于参数完成的,这个参数是一个 QEvent 类型的对象
这里有两个常用的API

//让窗口接受传递过来的事件,事件不会向上层窗口(父窗口)传递
void QEvent::accept();
//让窗口忽略传递过来的事件,事件被传递给父窗口(向上传递)
void QEvent::ignore();

可以在事件分发器中进行拦截,不让某些触发的事件进入到当前窗口中。
事件分发器函数的返回值:

如果传入的事件已被识别并且处理,则需要返回 true,否则返回 false。如果返回值是 true,那么 Qt 会认为这个事件已经处理完毕,不会再将这个事件发送给其它对象,而是会继续处理事件队列中的下一事件。

如果想过滤某个事件,只需要在判断出这个事件之后直接返回 true 就可以了。
在event()函数中,调用事件对象的 accept() 和 ignore() 函数是没有作用的,不会影响到事件的传播。
在窗口中过滤掉鼠标按下的事件:

bool MainWindow::event(QEvent *ev)
{
    if(ev->type() == QEvent::MouseButtonPress ||
            ev->type() == QEvent::MouseButtonDblClick)
    {
        // 过滤调用鼠标按下的事件
        return true;
    }
    //调用了父类的事件分发器函数
    return QWidget::event(ev);
}

事件过滤器

除了使用事件分发器来过滤 Qt 窗口中产生的事件,还可以通过事件过滤器过滤相关的事件。当 Qt 的事件通过应用程序对象发送给相关窗口之后,窗口接收到数据之前这个期间可对事件进行过滤,过滤掉的事件就不能被继续处理了。
使用:

1.给要被过滤事件的类对象安装事件过滤器
2.在要进行事件过滤的类中重写从QObject类继承的虚函数eventFilter()
3.如果想过滤掉这个事件,停止它被进一步处理,返回 true,否则返回 false

事件过滤器和被安装过滤器的组件必须在同一线程, 否则,过滤器将不起作用。另外,如果在安装过滤器之后,这两个组件到了不同的线程,那么,只有等到二者重新回到同一线程的时候过滤器才会有效。文章来源地址https://www.toymoban.com/news/detail-594771.html

到了这里,关于Qt知识笔记(八)—— 鼠标和事件的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Qt窗口设置无边框不能移动,鼠标穿透后不能响应点击事件

      最近在做一个迷你小工具,准备干点不可描述的事情,想要短小强悍,始终在最顶层显示,同时不要自带的关闭按钮和边框,百度一下,发现是需要设置如下两个属性:   那么问题来了,这样的话一运行窗体就在正中间,而且无法拖动,就像这样   哪怕对于我这种

    2024年02月10日
    浏览(61)
  • qt-C++笔记之捕获鼠标滚轮事件并输出滚轮角度增量

    code review! 在WheelWidget类中,wheelEvent函数被重写。这个函数是QWidget的一个虚函数,用于处理鼠标滚轮事件。

    2024年02月19日
    浏览(44)
  • 【QT开发笔记-基础篇】| 第四章 事件QEvent | 4.4 鼠标按下、移动、释放事件

    本章要实现的整体效果如下: QEvent::MouseButtonPress ​ 鼠标按下时,触发该事件,它对应的子类是 QMouseEvent QEvent::MouseMove ​ 鼠标移动时,触发该事件,它对应的子类是 QMouseEvent QEvent::MouseButtonRelease ​ 鼠标释放时,触发该事件,它对应的子类是 QMouseEvent 本节通过两个案例来讲

    2024年02月08日
    浏览(49)
  • Qt - Qt5事件处理(鼠标事件)

    鼠标事件 ​ 鼠标事件包括鼠标的移动,鼠标键按下,松开,单击,双击等 使用鼠标事件时,加入对应头文件 常见的鼠标事件如下: QMouseEvent类包含了用于描述鼠标事件的参数。 当在一个窗口里按住鼠标按键、或移动、或释放就会产生鼠标事件QMouseEvent。 鼠标移动事件只会

    2023年04月09日
    浏览(43)
  • QT学习日记12——Qt中的鼠标事件

    学习视频链接 最新QT从入门到实战完整版|传智教育_哔哩哔哩_bilibili https://www.bilibili.com/video/BV1g4411H78N?p=31vd_source=0471cde1c644648fafd07b54e303c905 目录 一、鼠标进入和出去事件 1.1 新建 C++ 文件 1.2 编写代码 1.3 操作 1.4 运行结果 二、鼠标点击、释放和移动事件 2.1 修改代码 2.2 运行结

    2024年02月11日
    浏览(54)
  • 【Qt】Qt无边框窗口(鼠标点击自定义标题栏)可拖动

    隐藏掉标题栏后,默认情况下窗口无法被鼠标拖动的,需要自己处理鼠标事件,移动窗口达到拖动效果,但是又不想要鼠标点击整个窗口都可以拖动,只需要鼠标点击自定义的标题栏时可拖动 具体步骤如下: 类外初始化 通过鼠标点击事件,判断鼠标是否在标题栏,如果是,

    2024年02月12日
    浏览(45)
  • qt鼠标事件

    鼠标移动事件,只要移动鼠标,就会触发这个函数,其中,正常情况下,只有当鼠标在QWidget界面点击鼠标后,才会捕捉到鼠标的坐标,那如何实现,在不点击鼠标的情况下,也可以捕捉到鼠标移动事件呢? 代码如下: 比如在主窗口QWidget下有一个父窗口Lable,在鼠标进入Lab

    2024年02月09日
    浏览(41)
  • Qt 鼠标进入离开事件

    QEvent::Enter ​ 鼠标进入事件,当鼠标进入到窗口/控件内部时,触发该事件,它对应的子类是 QEnterEvent QEvent::Leave ​ 鼠标离开事件,当鼠标离开到窗口/控件内部时,触发该事件 自定义一个标签控件 LabelX ,让它继承自 QLabel ,然后重写父类的 enterEvent 和 leaveEvent 。 代码如下:

    2024年01月24日
    浏览(38)
  • 【QT】鼠标常用事件

    新建项目 加标签控件 当鼠标进去,显示【鼠标进入】,离开时显示【鼠标离开】 将QLable提升成自己的控件,然后再去捕获 添加文件 改继承的类名 提升类 同一个父类,可以提升 效果 现在代码就和Qlabel对应起来了。 在.h中声明,.cpp中实现 测试 鼠标的移动、按下、松开事件

    2024年02月06日
    浏览(39)
  • qt鼠标常用事件

    和上一个案例相同,也是做了提升,换了相同父类,但是方式有所不同 先在widget.ui中加入label标签,此时其父类为QLabel,然后想实现鼠标在QLabel上的捕获。所以我们需要把QLabel提升为自己的框架,然后自定义框架后,我们就可以自己捕获信息了。然后添加新文件mylabel.h和mylabel.cpp,

    2024年02月02日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包