- 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