原标题:Qt C++编程实例│爱心表白小程序(附源码)
本小节将实现一个好玩的爱心表白小程序,将综合运用到鼠标移动事件、定时器事件、从已有按钮类派生出自定义类、自定义信号槽等方面的内容。
01
Qt C++编程实例:爱心表白小程序
初始界面如图6-18a)所示,爱心图像的中心默认位于窗口用户区的中心处,初始大小为100*100。
a) 初始界面
b) 运行效果
■图6-18 初始界面与运行效果
当点击喜欢按钮时,弹出一个消息框么么哒,我也喜欢你!!!,然后爱心图像以图像中心为固定点缓慢变大,直到到达窗口的边界为止;当鼠标移动到不喜欢按钮的区域时,该按钮会随机逃到窗口内的其它地方,且图像重置到初始的位置和大小,效果如图6-18b)所示。
首先,创建一个基于QWidget、带界面的应用6_15。在界面上拖入两个标签和一个按钮,部件的名字和显示的文本见图6-19。
■图6-19 界面设计
然后在项目中添加一个Qt资源文件,并添加一个图片资源。例如:本书添加的资源为:\img\heart.jpg。接着在自定义Widget类中添加一个私有的成员函数,用来初始化标签的图像、大小和位置,定义如下:
void Widget::initialImgLabel//设置图像标签的初始状态
{
ui->labelImg->setPixmap(QPixmap(“:/img/heart.jpg”));
ui->labelImg->resize(100,100);//设置图像标签初始大小
ui->labelImg->setScaledContents(true);//设置图像自适合标签大小
ui->labelImg->move(this->width/2-ui->labelImg->width/2,
this->height/2-ui->labelImg->height/2);
}
上述代码将labelImg的标签内容设置为资源图像heart.jpg、大小设置为100*100像素、位置设置为位于用户区的中心,设置图像显示大小自适应标签大小。在Widget类构造函数的定义体内的末尾添加调用上述成员函数的语句:
initialImgLabel;
接下来使用定时器事件实现喜欢按钮点击后图片逐渐变大的效果,在Widget类中添加一个整型数据成员如下:
intnowTimer=0;
该数据成员用于记录当前正在开启的定时器编号,初始为0。然后在Widget类中添加一个私有的成员函数用于开启定时器,定义如下:
voidWidget::startImageGrow
{
if(nowTimer!=0)
killTimer(nowTimer);
nowTimer=startTimer(20);
}
该函数首先判断当前对象中是否已有开启的定时器,若有则结束它,然后重新开启一个以20毫秒为间隔的定时器。
然后,在Widget类中重写定时器事件处理函数,定义如下:
void Widget::timerEvent(QTimerEvent *)//定时器事件处理函数
{
int userAreaWidth=geometry.width;
int userAreaHeight=geometry.height;
int imgWidth=ui->labelImg->width;
int imgHeight=ui->labelImg->height;
int posX=ui->labelImg->pos.x;
int posY=ui->labelImg->pos.y;
if(posX>0&&imgWidth+posX
{
ui->labelImg->resize(imgWidth+2,imgHeight+2);
ui->labelImg->move(ui->labelImg->x-1,ui->labelImg->y-1);
}
else
{
killTimer(nowTimer);
nowTimer=0;
}
}
每次定时器到期后,会对图像标签的四周位置进行判断,若仍处于窗口用户区范围内,则以原标签中心为固定点,将标签的长和宽分别增加两个像素。否则(图像已到用户区的某个边缘)删除定时器。
界面中的喜欢按钮clicked信号的自关联槽定义如下:
voidWidget::on_btnYes_clicked
{
startImageGrow;
QMessageBox::information(this,“^_^比心^_^”,“么么哒,我也喜欢你!!!”);
}
由于使用到了QMessageBox类,还需在该函数所在的widget.cpp文件中添加头文件:
include
此时就完成了 喜欢按钮的功能。运行时,若标签图像变大时遮住了喜欢按钮,只需在Widget构造函数体的末尾添加如下语句将喜欢按钮置于最前即可:
ui->btnYes->raise;
下面是不喜欢按钮在鼠标移进按钮区域时移动按钮位置功能的实现,需要重写按钮QMouseEvent事件的默认处理函数mouseMoveEvent,所以得从QPushButton类派生出自定义按钮类,然后在自定义按钮类内重写上述函数。
新添加一个继承自QPushButton的MyButton类,对应的MyButton.h定义如下:
/****************************************
* 项目名:6_15
* 文件名:mybutton.h
* 说明:自定义按钮类
****************************************/
ifndefMYBUTTON_H
defineMYBUTTON_H
include
include
classMyButton:publicQPushButton
{
Q_OBJECT
public:
MyButton(QWidget *parent =nullptr);
protected:
voidmouseMoveEvent(QMouseEvent *event);
signals:
voidbtnIsRunning;
};
endif// MYBUTTON_H
类中声明了重写的mouseMoveEvent函数;还声明了一个信号btnIsRuning,目的是用来通知窗口,以便其能重置标签图像大小和位置。类的实现代码如下:
/****************************************
* 项目名:6_15
* 文件名:mybutton.cpp
* 说明:自定义按钮类实现
****************************************/
include“mybutton.h”
MyButton::MyButton(QWidget *parent)
:QPushButton(parent)
{
setMouseTracking(true);
this->resize(75,23);
}
voidMyButton::mouseMoveEvent(QMouseEvent *)
{
QWidget *parent=dynamic_cast
intx=rand%(parent->geometry.width –this->width);
inty=rand%(parent->height –this->height);
this->move(x,y);
emitbtnIsRunning;
}
构造函数中设置了按钮的初始大小,setMouseTracking(true)语句用于开启跟踪功能,只有设置为true才会对鼠标移动事件实时跟踪(为false时只有鼠标键按下的同时移动鼠标才会捕捉到鼠标移动事件)。
鼠标移动事件的默认处理函数mouseMoveEvent获取到按钮的父窗口用户区大小、在此范围内随机生成新坐标位置(rand函数随机生成一个整数值)、然后据此移动按钮;同时发射出一个btnIsRuning的信号。
接下来在Widget窗口中添加自定义按钮类对象。首先在widget.h文件中添加头文件:
include“mybutton.h”
然后在类中添加一个私有的指针成员:
MyButton*btn;
再在Widget类的构造函数内添加如下语句,目的是在窗口中设置一个不喜欢按钮:
btn=newMyButton(this);
btn->setText(“不喜欢”);
btn->move(240,220);
btn->show;
btn->raise;
最后实现鼠标移进不喜欢按钮时图像标签大小和位置重置的效果。由于自定义按钮已在此时发出了btnIsRunning的信号,因此只需将该信号与窗口的initialImgLabel函数绑定即可。在Widget类构造函数中添加如下语句:
connect(btn,&MyButton::btnIsRunning,this,&Widget::initialImgLabel);
并在initialImgLabel函数末尾添加如下语句:
if(nowTimer!=0)
killTimer(nowTimer);
nowTimer=0;
至此,程序已全部编写完毕,运行一下看看效果吧!
02
源代码下载
关注微信公众号,后台回复关键词表白小程序即可获得完整源代码。
03
参考书籍
《Qt C++编程从入门到实战-微课视频版》
作者:彭源、孙超超、田秀霞、李红娇
定价:79.80元
编辑推荐
1. 以Qt框架为载体,讲授C++面向对象机制
2. 贯彻实例式学习法,在实例中理解、掌握和深化概念
3. 注重编程习惯的培养,注重与动手实践的衔接
4. 注意与前序、后继课程之间的衔接
5. 具备知识的拓展性
本书配套资源丰富,包括教学大纲、教学课件、电子教案、程序源码、习题答案、教学进度表和在线作业,作者还为本书精心录制了500分钟的微课视频。
04
精彩推荐
Qt C++编程实例│猴子选大王(附源码)
Qt C++编程实例│计算器(附源码)
Qt C++案例│使用OpenCV库进行图像读写(源码+视频)
通关操作系统 | 外存分配方式(附视频限免)
通关操作系统 | 页面置换算法(附视频限免)
通关操作系统 | 页式存储管理(附视频限免)
通关操作系统 | 银行家算法(附视频限免)
通关操作系统 | 死锁问题(附视频限免)
通关操作系统 | 调度算法(附视频限免)
通关操作系统 | 同步问题举例(附视频限免)
通关操作系统 | 进程的同步与互斥(附视频限免)
通关操作系统 | 进程控制(附视频限免)
通关操作系统 | 进程的概念(附视频限免)
人工智能实践: 基于T-S 模型的模糊推理(附源码)
Python自然语言处理|语料清洗(附视频)
Python编程|实现基于字典的通讯录
CCF CSP-J/S第一轮认证考纲详解
Python 韩信点兵思政案例(含优惠码)
Python ︱爬取天气预报信息(附视频)
《机器学习》实验指导书(附实验参考+代码)
Python爬虫综合实战 │ 创建云起书院爬虫(附代码)
Python爬虫实战 │ Email提醒(附代码)
Python深度学习 │一文掌握卷积神经网络返回搜狐,查看更多
责任编辑:
评论0