首页 > 其他分享 >Qt学习笔记9——P30-33. 自定义控件封装,鼠标事件,定时器

Qt学习笔记9——P30-33. 自定义控件封装,鼠标事件,定时器

时间:2023-04-01 16:24:42浏览次数:49  
标签:控件 定时器 Qt 自定义 void ui arg ev 鼠标

  • P30. 自定义控件封装
  • P31. Qt中的鼠标事件
  • P32. 定时器1
  • P33. 定时器2
  • P30. 自定义控件封装(创建了新项目)
  •  添加新的界面和类:右键项目的文件夹(顶层的文件)-> Qt——Qt设计师界面类 -> “选择界面模板”选"Widget" -> 在"Class name"中取个类名(此案例中改成了SmallWidget) -> 别的没什么注意的了,点下一步或完成,其他默认

(下面要做的是把“Spin Box”和“Horizontal Slider”封装到一起)

先拖一个Spin Box和Horizontal Slider到新添加的ui界面中,调整整个ui的大小和两个控件的位置(水平对齐)

  

切换到主的ui编辑界面中,拖一个“Widget”到界面中,右键此Widget -> 提升为 ->新窗口中的“提升的类名称”中填 一开始添加的在“Class name”中的类名 -> 点“全局包含”(说是可点可不点;作用是方便其他相同的提升),点击“添加” -> 再点击“提升”

(此时新添加的Widget的类名不再是QWidget,而变成了SmallWidget)

(下面实现按钮和滑块的同步)

(切换到smallwidget.cpp)

1     //QSpinBox移动 QSlider跟着移动
2     //因为valueChanged重载了,需要用函数指针
3     void(QSpinBox:: * spSignal)(int) = &QSpinBox::valueChanged;
4     connect(ui->spinBox,spSignal,ui->horizontalSlider,&QSlider::setValue);
5 
6     //QSlider滑动 QSpinBox数字跟着改变
7     connect(ui->horizontalSlider,&QSlider::valueChanged,ui->spinBox,&QSpinBox::setValue);

运行结果:

  

(下面实现两个功能:设置数字 和 获取数字)

(切换到smallwidget.h,先声明两个函数)

    //设置数字
    void setNum(int num);
    //获取数字
    int getNum();

 

(在smallwidget.cpp中实现上面的函数)

 1 //设置数字
 2 void SmallWidget::setNum(int num)
 3 {
 4     ui->spinBox->setValue(num);
 5 }
 6 //获取数字
 7 int SmallWidget::getNum()
 8 {
 9     return ui->spinBox->value();
10 }

 

(widget.cpp)

1     //点击获取 获取控件当前值
2     connect(ui->btn_get,&QPushButton::clicked,this,[=](){
3         qDebug()<<ui->widget1->getNum();  //widget1是封装的控件的widget变量名;getNum()是刚才在smallwidget.cpp中自己写的函数
4     });
5 
6     //点击设置到一半
7     connect(ui->btn_set,&QPushButton::clicked,this,[=](){
8        ui->widget1->setNum(50);
9     });

  

 

  • P31. Qt中的鼠标事件(创建了新项目)

(将要实现的功能:判断鼠标进入和离开一个区域)

往项目中添加新的类,不需要ui界面:右键项目名称 -> Add New -> 左边选C/C++,中间选“C++ Class”,“Choose” -> “Class name”中取个名字(此案例中为“myLabel”),“Base class”选“QWidget” -> 下一步,完成

(mylabel.h)

1     //鼠标进入事件
2     void enterEvent(QEvent * event);
3     //鼠标离开事件
4     void leaveEvent(QEvent *);

 

(mylabel.cpp)

 1 //鼠标进入事件
 2 void myLabel::enterEvent(QEvent * event)
 3 {
 4     qDebug()<<"鼠标进入了";
 5 }
 6 //鼠标离开事件
 7 void myLabel::leaveEvent(QEvent *)
 8 {
 9     qDebug()<<"鼠标离开了";
10 }

 

(一个因为之前新建错误 而导致现在必要的操作)

在“mylabel.h”中:

#include <QLabel>

把 class myLabel : public QWidget 改成 class myLabel : public QLabel

 

在“mylabel.cpp”中:

把 myLabel::myLabel(QWidget *parent) : QWidget(parent) 改成 myLabel::myLabel(QWidget *parent) : QLabel(parent)

 

往ui编辑界面中拖拽一个"Label",右键 -> 提升为 -> “提升的类的名称”里填“myLabel” -> 添加,提升

  

(因为这个新添加的控件的基类是QLabel,所以提升的类也要是QLabel,所以刚才要把QWidget改成QLabel)

 

  • ui中的Label添加进去之后,不好找,怎么办?:

选中添加进去的Label,右下角“frameShape”可以选“Box”,就有边框了

运行一下:

  

(实现几个其他的鼠标功能)

(mylabel.h)

1     //鼠标按下
2     virtual void mousePressEvent(QMouseEvent *ev);
3     //鼠标释放
4     virtual void mouseReleaseEvent(QMouseEvent *ev);
5     //鼠标移动
6     virtual void mouseMoveEvent(QMouseEvent *ev);

 

(mylabel.cpp)

 1 //鼠标按下
 2 void myLabel::mousePressEvent(QMouseEvent *ev)
 3 {
 4     //当鼠标左键按下 提示信息
 5     if(ev->button() == Qt::LeftButton)
 6     {
 7         //如果没有上面的if,这里的操作鼠标左右键都可以进行
 8         QString str = QString("鼠标按下了 x = %1 y = %2 globalX = %3 globalY = %4" ).arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY()); //%1 和 %2 都是占位的,%1的位置将是ev->x(),%2的位置将是ev->y()
 9         qDebug()<<str;
10     }
11 
12 }
13 //鼠标释放
14 void myLabel::mouseReleaseEvent(QMouseEvent *ev)
15 {
16     if(ev->button() == Qt::LeftButton)
17     {
18         QString str = QString("鼠标释放了 x = %1 y = %2 globalX = %3 globalY = %4" ).arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY()); //%1 和 %2 都是占位的,%1的位置将是ev->x(),%2的位置将是ev->y()
19         qDebug()<<str;
20     }
21 
22 }
23 //鼠标移动
24 void myLabel::mouseMoveEvent(QMouseEvent *ev)
25 {
26     if(ev->buttons() & Qt::LeftButton)  //跟上面的判断不同:1. buttons 2. &
27     {
28         QString str = QString("鼠标移动了 x = %1 y = %2 globalX = %3 globalY = %4" ).arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY()); //%1 和 %2 都是占位的,%1的位置将是ev->x(),%2的位置将是ev->y()
29         qDebug()<<str;
30     }
31 
32 }

 

1     //设置鼠标追踪
2     setMouseTracking(true);

设置了鼠标追踪后,即使鼠标在区域中不按下,也会显示移动(但是要把判断移动的“if”注释掉)

总结:

  • 鼠标进入事件  enterEvent
  • 鼠标离开事件  leaveEvent
  • 鼠标按下  mousePressEvent(QMouseEvent * ev)
  • 鼠标释放  mouseReleaseEvent
  • 鼠标移动  mouseMoveEvent
  • ev->x() x坐标  ev->y() y坐标
  • ev->button() 可以判断左右按键  Qt::LeftButton  Qt::RightButton
  • ev->buttons() 判断组合按键 判断move时候的左右键 结合 & 操作符
  • 格式化字符串 QString("%1 %2").arg(111).arg(222)

 

  • P32. 定时器(沿用了上P项目)

(下面做:每隔一秒数字增加1)

在ui编辑界面里拖拽一个“Label”

(widget.h)

1     //重写定时器事件
2     void timerEvent(QTimerEvent *);

 

(widget.cpp)

1     //构造函数中
2     //启动定时器
3     startTimer(1000);    //参数1.间隔(单位 毫秒)
4 ...
5 void Widget::timerEvent(QTimerEvent *)
6 {
7     static int num = 1; //静态变量
8     ui->label_2->setText(QString::number(num++));
9 }

 

(下面实现:一个隔一秒+1,一个隔两秒+1)

再往ui编辑界面拖拽一个“Label”

(widget.h)

    //public中
    int id1;    //定时器1的唯一标识
    int id2;    //定时器2的唯一标识

 

(widget.cpp)

 1 //构造函数中
 2     //启动定时器
 3     id1 = startTimer(1000);    //参数1.间隔(单位 毫秒);startTimer返回的是定时器id
 4     id2 = startTimer(2000);
 5 ...
 6 //全局函数
 7 void Widget::timerEvent(QTimerEvent *ev)
 8 {
 9     if(ev->timerId() == id1)
10     {
11         static int num = 1; //静态变量
12         ui->label_2->setText(QString::number(num++));
13     }
14     if(ev->timerId()==id2)
15     {
16         static int num2=1;
17         ui->label_3->setText(QString::number(num2++));
18     }
19 }

总结:

  • 利用事件 void timerEvent(QTimerEvent * ev)
  • 启动定时器 startTimer(1000) 单位毫秒
  • timerEvent 的返回值是定时器的唯一标识 可以和ev->timerId 作比较

 

  • P33. 定时器2(推荐这种方法)(沿用了上P项目)

定时器第二种方式

(实现每隔0.5s数字+1)

在ui编辑界面再拖拽一个“Label”

(widget.cpp)

1 //构造函数中
2 //定时器第二种方式
3     QTimer * timer = new QTimer(this);
4     //启动定时器
5     timer->start(500);  //单位毫秒
6     connect(timer,&QTimer::timeout,this,[=](){
7         static int num3 =1;
8         ui->label_4->setText(QString::number(num3++));
9     });

 

(下面实现:点一个按钮暂停)

在ui编辑界面拖拽一个“Push Button”(改名“暂停”,变量名“btn”)

(widget.cpp)

1     //点击暂停按钮 实现停止计时器
2     connect(ui->btn,&QPushButton::clicked,this,[=](){
3        timer->stop();
4     });
5     //如果恢复那就再添加一个按钮,然后连接timer->start(间隔)

总结:

  • 利用定时器类 QTimer
  • 创建定时器对象 QTimer * timer = new QTimer (this)
  • 启动定时器 timer->start(毫秒)
  • 每隔一定毫秒,发送信号 timeout,进行监听
  • 暂停 timer->stop()

(〃>_<;〃)(〃>_<;〃)(〃>_<;〃)

标签:控件,定时器,Qt,自定义,void,ui,arg,ev,鼠标
From: https://www.cnblogs.com/wjjgame/p/17277585.html

相关文章

  • 在Qt中,如何在sheets末端添加新的sheet
        voidMainWindow::on_createNewSheet_clicked(){try{intsheetsCount=work_sheets->property("Count").toUInt();//cout<<"sheetsCount="<<sheetsCount<<endl;//获取最后一个sheet的指针......
  • 报错 qt.qpa.plugin: Could not load the Qt platform plugin “xcb“ in ““ even t
    参考:https://blog.csdn.net/qq_39938666/article/details/120452028  ==========================================  使用ubuntu系统下python的seaborn模块画图,报错:qt.qpa.plugin:CouldnotloadtheQtplatformplugin“xcb“in““eventhoughitwasfound......
  • 添加自定义监控第2篇--------------------------------------------------
      netstat-antp|grep':80'|grep-c'ESTABLISHED'换一个测试项:netstat-antp|grep":22"|grep-c"ESTABLISHED"    出现了不是正整数的情况,怎么消掉前面的错误提示??        chmod +s/bin/netstat    或者  chmodu+s /......
  • Qt学习笔记8——P26-28. ui中的一些控件(QTreeWidget, QTableWidget, 其他)
    P26.QTreeWidget树控件P27.QTableWidget控件P28.其他常用控件介绍P26.QTreeWidget树控件(创建了新项目) (ui界面)ItemWidgets(Item-Based)->TreeWidget把"TreeWidget"拖进界面后,如果想把此TreeWidget居中,选中最大的窗口(Widget),然后选工具栏中的"水平居中"或"垂直居......
  • 发一下好看的博客园自定义主题代码
    发一下好看的博客园自定义主题代码要开通js权限,皮肤用simplememory,最好禁用模板侧边栏:<!DOCTYPEhtml><html><style>/*最外层容器样式*/.wrap{top:0;right:0;bottom:0;left:0;width:200px;height:200px;margin:auto;/......
  • 如何使用自定义通达信指标(附带3技术指标3选股指标)
    通达信类型的交易软件都支持通达信指标公式,电脑端推荐使用东方财富,同花顺,通达信自己也有电脑端,但是做得不好。手机端可以下载通达信APP,最好是安卓版,IOS的通达信有bug,不知道修复了没。点击日线再点更多选更多指标点新建就可以进入公式编辑界面,或者可以选择已有的公式进行修改点条件......
  • 面向chatgpt运维:根据自定义的日志统计访问用户数
    Craftedby[Genie](https://marketplace.visualstudio.com/items?itemName=genieai.chatgpt-vscode)You如何使用awk统计访问用户数,我的日志格式如下:{"level":"info","ts":"2023/03/3108:58:03","msg":"/api/v1/goods/project&quo......
  • Qt调用摄像头二,Pro版
    本示例,为纯Qt调用摄像头,功能会比版本一要多一点:打开摄像头,设置参数,完整拍照,框选拍照,切换分辨率,旋转,水平镜像,垂直镜像,放大,缩小上一个版本,使用的显示窗口直接显示出摄像头画面,所以可操作性有限,没关系,这个版本使用的另一种方法:打开设备,获取视频帧,自己把视频帧画上去,这样就操作的东......
  • vue3 - 在单独的项目制作自定义组件插件,支持vite【前提不要使用webpack专属语法】
    1.背景与vue2组件不一样,没有那么随意,如果想要支持vite,那么不要使用webpack专属语法,如defide和 require等2.解决在 package.json文件属性  main配置为插件入口文件位置,至于是js还是ts随意 目录  简单做了个组件  入口文件内容如下importComponentf......
  • django自定义模板显示不同状态的颜色
    一般这个颜色列表是放在models.py里charge_type_class_mapping={1:"success",2:"danger",3:"default",4:"info",5:"primary",} color.pyfromdjango.templateimportLib......