当前位置: 首页 > news >正文

淘宝客建设网站珠海哪个建设网站建设好

淘宝客建设网站,珠海哪个建设网站建设好,杭州做网点卖服装在那个网站,课程网站建设规划鼠标事件0 事件1 需求2 查看控件的事件处理函数3 UI设计4 新建一个类,继承QLabel5 对已有对象进行类型提升6 重写事件处理函数7 项目进一步拓展(1)获取鼠标按键(2)鼠标移动(3)显示多个按键&…

鼠标事件

  • 0 事件
  • 1 需求
  • 2 查看控件的事件处理函数
  • 3 UI设计
  • 4 新建一个类,继承QLabel
  • 5 对已有对象进行类型提升
  • 6 重写事件处理函数
  • 7 项目进一步拓展
    • (1)获取鼠标按键
    • (2)鼠标移动
    • (3)显示多个按键
    • (4)设置默认鼠标跟踪
  • 8 QT事件分发机制

0 事件

用户对界面中的控件进行操作后,控件需要进行响应,响应一般有两种方式,一种是之前学过的槽函数,另一种是事件,部分操作无法通过槽函数响应,只能通过事件,例如鼠标移动,键盘输入等。
当某个事件(鼠标、键盘)发生的时候,相关控件就会收到这个事件,并且调用相应的事件处理函数进行相应,事件处理函数的命名都是以Event结尾的。

1 需求

在窗口内的任意位置点击,然后窗口会有一个标签(使用QLabel)显示鼠标所在位置的坐标:随着鼠标在窗口内不同位置进行点击,标签显示的坐标也在变换。效果如下图所示:
在这里插入图片描述

2 查看控件的事件处理函数

在帮助界面搜索QWidget,然后点击Protected Functions
在这里插入图片描述
可以看到很多以“Event”结尾的函数,这些函数的参数都是各个事件,并且这些函数都使用了virtual修饰,即他们都是虚函数,继承时表现为多态特性。
在这里插入图片描述
我们可以往下滑,找到鼠标事件
在这里插入图片描述
截图中红色方框框出来的几个分别为:鼠标单击、鼠标移动、鼠标点击、鼠标释放,说明这个控件可以对这四种鼠标事件进行响应,它们的参数均为鼠标事件指针(QMouseEvent *)。

3 UI设计

打开QT设计师,在Display Widgets中选择Label,将其拖到窗口中:在这里插入图片描述
给主窗口来个布局
在这里插入图片描述
右下角可以看到类的继承层次结构,我们刚刚拖到窗口中的控件,类型是QLabel
在QFrame的frameShape属性中选择Box
在这里插入图片描述
窗口中会出现黑色的框线
在这里插入图片描述

4 新建一个类,继承QLabel

设计好UI后,之所以还要新建类去继承已有类,是因为原先的事件处理函数无法满足需求,我们需要重写相应的事件处理函数(这部分稍后会说)。
由于新建类的时候,父类选项没有QLabel,所以这里新建类的时候先选择继承QWidget(也可以选其他),产生代码后手动改父类
在这里插入图片描述
打开新建类的头文件,将父类由QWidget改成QLabel
在这里插入图片描述
对应的cpp文件也要改,在构造函数的初始化列表中,将父类改过来
在这里插入图片描述

5 对已有对象进行类型提升

在UI设计界面的对象树中,右击我们刚刚在UI设计阶段,拖到窗口中的空间(QLabel对象),然后点击“提升为”
在这里插入图片描述
在弹出的对话框中,填写提升的类名称,然后点击添加
在这里插入图片描述
再次填写提升的类名称,然后点击提升
在这里插入图片描述
此时可以看到,我们刚刚拖到窗口中的控件,类型变成了MyLabel
在这里插入图片描述
然后Ctrl+R,看看有没有错。

6 重写事件处理函数

MyLabel.h内容如下:

#ifndef MYLABEL_H
#define MYLABEL_H#include <QWidget>
#include <QLabel>class MyLabel : public QLabel
{Q_OBJECT
public:explicit MyLabel(QWidget *parent = nullptr);signals:public:void mousePressEvent(QMouseEvent *event);
};#endif // MYLABEL_H

输入完函数声明后,按下alt+回车,会显示提示消息,然后选择“在mylabel.cpp添加定义”,就能在mylabel.cpp中自动生成函数头,十分方便。
在这里插入图片描述

MyLabel.cpp内容如下:

#include "mylabel.h"
#include "QMouseEvent"MyLabel::MyLabel(QWidget *parent) : QLabel(parent)
{}void MyLabel::mousePressEvent(QMouseEvent *event)
{//获取鼠标事件的一些信息//获取坐标int x = event->x();int y = event->y();//格式化显示坐标,并居中QString str = QString("<h1><center>[%1, %2]</center></h1>").arg(x).arg(y);this->setText(str);
}

这里QString str = QString("<h1><center>[%1, %2]</center></h1>").arg(x).arg(y);是将字符串进行格式化匹配,QString中是可以使用html语法的,随后的this->setText(str)是输出指定的字符串。

现在我们按下Ctrl+R运行,然后点击窗口中的任意一点,然后就能看到坐标了
在这里插入图片描述
至此,大功告成。

我们这个项目的结构如下图所示:
在这里插入图片描述
项目中的main.cpp、widget.h和widget.cpp都没有修改,这几个文件一般很少去动,除非要和后端进行联动。

7 项目进一步拓展

(1)获取鼠标按键

在mylabel.cpp中输入event->button();,然后移动光标到函数上,按两遍F1(笔记本电脑可能和某些屏幕、声音设置的快捷键冲突,这种情况下需要按住键盘左下角的fn键,然后按两遍F1)
在这里插入图片描述
可以看到这个函数的返回值类型是Buttons,点击QT::MouseButton
在这里插入图片描述
QT 5.14.2的帮助文档中,button()返回值是Qt3DInput::QMouseEvent::Buttons类型,而用这个类来定义event->button的返回值却报错,我不知道怎么回事,所以上面使用的是QT 5.9文档内容。也就是说,5.14.2并不是稳定版本,编译器和帮助文档有冲突,我们以后查看返回值类型的时候,用ctrl,然后鼠标点击要查看的函数,找到源码查看返回值类型,然后再调用帮助文档。

可以看到QT::MouseButton枚举类型(一般Qt后面跟两个冒号的,都是枚举类型),红框框出来的为需要掌握的键,分别是:未按下、任意键、左键、右键、中键(滚轮)、中键,最后两个含义相同。
在这里插入图片描述
将mylabel.cpp的代码修改如下:

#include "mylabel.h"
#include "QMouseEvent"MyLabel::MyLabel(QWidget *parent) : QLabel(parent)
{}void MyLabel::mousePressEvent(QMouseEvent *event)
{//获取鼠标事件的一些信息//获取坐标int x = event->x();int y = event->y();//获取鼠标按键Qt::MouseButtons btns = event->buttons();QString strButton ="" ;if(btns & Qt::LeftButton){strButton += "LeftButton;";}if(btns & Qt::RightButton){strButton += "RightButton;";}if(btns & Qt::MidButton){strButton += "MidButton";}//格式化显示坐标,并居中QString str = QString("<h1><center>[%1, %2][%3]</center></h1>").arg(x).arg(y).arg(strButton);this->setText(str);
}

运行结果如下:
在这里插入图片描述

(2)鼠标移动

在MyLabel类中新增一个函数,定义如下(mylabel.h中也要声明,这里不再赘述):

void MyLabel::mouseMoveEvent(QMouseEvent *ev)
{//获取坐标int x = ev->x();int y = ev->y();QString str=QString("<h1><center>Move[%1, %2][%3]</center></h1>").arg(x).arg(y);this->setText(str);
}

点击运行后,按下鼠标,会调用mousePressEvent,移动鼠标会调用mouseMoveEvent
在这里插入图片描述

(3)显示多个按键

对于按下按键后(不松开)拖动的情况,会先调用mousePressEvent,然后调用mouseMoveEvent,我们希望标签能显示Move和坐标的同时,也显示按下了哪个按钮,例如Move[300, 300][LeftButton],对于鼠标移动过程中,同时按下左键和右键的情况,我们也希望能够检测到。则可以对mouseMoveEvent做如下修改:

void MyLabel::mouseMoveEvent(QMouseEvent *ev)
{//获取坐标int x = ev->x();int y = ev->y();//获取鼠标按键Qt::MouseButtons btns = ev->buttons();  //可以一次获取多个按键QString strButton ="" ;if(btns & Qt::LeftButton)               //按位与操作{strButton += "LeftButton ";			//+是字符串拼接,因为有可能按了多个键}if(btns & Qt::RightButton){strButton += "RightButton ";		//+是字符串拼接,因为有可能按了多个键}if(btns & Qt::MidButton){strButton += "MidButton ";}QString str=QString("<h1><center>Move[%1, %2][%3]</center></h1>").arg(x).arg(y).arg(strButton);this->setText(str);
}

这里需要注意的是,ev->buttons()返回一个数,我们用二进制的角度来看,假如它返回的是000101,那么它是000100(MidButton)和000001(LeftButton)按位与的结果,表示同时按下了两个按键。
后面的几个if判断条件,其实是按位与运算。因为每一种Qt::MouseButton常量,只有某一位是1,其他位都为0,因此要从ev->buttons()的返回值中将某一位抽取出来,可以使用按位与运算,例如要判断是否按下了RightButton(000010),可以用RightButton与返回值进行按位与运算,结果为0则表示没按下,非0则表示按下了,假设返回值为000011,000010&000011结果是000010,结果非0,因此按下了。

运行后,按下鼠标拖动如下:
在这里插入图片描述
在按下鼠标(左键)拖动的那一瞬间,是否调用了mousePressEvent?可以在mousePressEvent函数中增加一行打印功能,来查看是否调用。
我自己尝试了,点下的那一瞬间,确实是先调用mousePressEvent,然后调用mouseMoveEvent,即点下的一瞬间先相应mousePressEvent,随后移动鼠标时相应mouseMoveEvent,此时由于鼠标左键还没松开,因此能被ev->buttons()检测到。

对于同时按下多个按键进行拖动,也能正常显示
在这里插入图片描述

(4)设置默认鼠标跟踪

上面的程序,在开始的时候,没有跟踪鼠标,也就是下面这个样子:
在这里插入图片描述
只有点击了窗口以后,才会显示“Move+坐标+按键名称”

如果我们想在窗口打开后,鼠标移动到窗口中(未点击)就开始跟踪鼠标的移动,那么可以在构造函数中进行设置

MyLabel::MyLabel(QWidget *parent) : QLabel(parent)
{//默认情况下,窗口不会主动跟踪鼠标//只有当某个鼠标按键按下的情况下才开始跟踪//如果想一开始跟踪,就要使用以下函数this->setMouseTracking(true);
}

8 QT事件分发机制

为什么我们点击了鼠标,就会调用mousePressEvent,移动了鼠标就会调用mouseMoveEvent?
当某个事件(鼠标、键盘)发生的时候,相应的控件就会收到这个事件,并且根据事件的类型调用相应的事件处理函数,这个过程都在一个名为event的事件中,这个函数可以在帮助文档中查看,它是一个虚函数,可以被子类重写。

在这里插入图片描述
一般情况下,不会去重写这个函数,我们能这里为了了解事件分发机制,因此对其进行重写。

这里仅仅以鼠标移动为例

bool MyLabel::event(QEvent *e)
{//返回值:true表示该事件得到处理,如果是false,没被处理,事件会继续传递到父窗口//QEvent就是所有Event类的父类,这里其实是使用了多态//判断event的类型if(e->type()==QEvent::MouseMove)    //e->type()返回的是鼠标事件的类型{this->mouseMoveEvent(static_cast<QMouseEvent *>(e));	//这句如果注释掉,则鼠标移动将不会有反应return true;}//其他类型的事件,交给父类的event函数去处理return QLabel::event(e);    //父类的event函数因为被覆盖了,所以需要域作用符
}

如果将this->mouseMoveEvent(static_cast<QMouseEvent *>(e));注释掉,则当鼠标移动时将不会有反应,此时就把鼠标移动给拦截过滤了。

事件的机制,可以用下面这张图来总结,事件过滤器这里没讲,这个并不重要:
在这里插入图片描述

http://www.15wanjia.com/news/169852.html

相关文章:

  • 网站风格有哪些网站开发广告怎么写
  • 武义建设局官方网站wordpress开通邮件注册
  • 黑龙江省住房与建设厅网站软件开发 网站建设
  • 学做西餐网站led论坛网站建设
  • 苏州论坛型网站建设保健品商城网站模板
  • 网站公共模板是什么wordpress获得授权
  • 杭州做公司网站哪家好西安官网seo推广
  • 户型图在哪个网站找如何做网站广告图片
  • 河北省沧州建设厅网站企业手机网站
  • 衡水市网站建设推广通
  • 连云港集团网站建设关键词优化需要注意
  • 图书馆建设网站打不开如何写一份企业网站建设方案
  • 免费vip网站推广电话销售网站建设
  • 外国优秀设计网站宜兴建设局网站
  • 南昌网站建设搜q.479185700wordpress免插件增强
  • 推荐电子商务网站建设有关网站升级建设的申请书
  • 北京模板建站软件设计师培训基地
  • php网站怎么做伪静态河北中瑞建设集团有限公司网站
  • 国外免费建站网站西安公司做网站
  • 南京网站搜索排名山东省建设人才网站
  • 加强网站网络安全建设方案信息系网站建设开题报告书
  • 网站设计分析报告做私单的网站
  • 免费发布卖车信息网站外国做挂的网站是多少
  • 档案网站开发浙江网站推广公司
  • 网站服务器费用明细公司网站开发的工作内容
  • 国内设计大神网站苏州做网站公司 询苏州聚尚网络
  • 志愿者网站 建设方案新变更营业执照注册号查了发现之前有备案过网站了
  • 做流程图用什么网站好濮阳网站关键词
  • 机械产品做哪个网站网站推广 昆明
  • 网站更新seo菜市场做建筑设计图库的网站设计