Qt编写自定义控件二动画按钮
现在的web发展越来越快,很多流行的布局样式,都是从web开始的,写惯了Qt widgets 项目,很多时候想改进一下现有的人机交互,尤其是在现有的按钮上加一些动画的效果,例如鼠标移上去变大,移开还原。
Qt编写自定义控件还是非常方便和非常强大的,数量掌握Qpainter的各种绘制,自定义任意控件几乎都不是难题,只有想不到,没有做不到。
贴一张个人认为做的比较炫的UI界面:
如果工控项目的界面能够做到这种程序,应该可以让人眼前一亮。
运行效果图:
核心代码:
void AnimationButton::paintEvent(QPaintEvent *) { if (image.isEmpty()) { return; } QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); QPixmap pix(image); pix = pix.scaled(targetWidth, targetHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation); if (enter || leave) { int pixX = rect().center().x() - targetWidth / 2; int pixY = rect().center().y() - targetHeight / 2 - 10; QPoint point(pixX, pixY); painter.drawPixmap(point, pix); painter.drawText(QRectF(0, height() - 20, width(), 20), Qt::AlignCenter, text); } }
完整代码:
animationbutton.h

#ifndef ANIMATIONBUTTON_H #define ANIMATIONBUTTON_H /** * 作者:feiyangqingyun(QQ:517216493) 2016-10-22 * 1:可设置显示的图像和底部的文字 */ #include <QWidget> #include <QVariant> class QPropertyAnimation; class AnimationButton : public QWidget { Q_OBJECT public: explicit AnimationButton(QWidget *parent = 0); ~AnimationButton(); protected: void enterEvent(QEvent *); void leaveEvent(QEvent *); void paintEvent(QPaintEvent *); private: bool enter; //是否进入 bool leave; //是否离开 int pixWidth; //图片宽度 int pixHeight; //图片高度 int oldWidth; //图片旧宽度 int oldHeight; //图片旧高度 QPropertyAnimation *enterAnimation; //进入动画 QPropertyAnimation *leaveAnimation; //离开动画 int targetWidth; //目标宽度 int targetHeight; //目标高度 QString text; //显示文字 QString image; //图像路径 private slots: void enterImageChanged(QVariant index); void leaveImageChanged(QVariant index); public slots: //设置显示的文字 void setText(QString text); //设置显示的图像 void setImage(QString image); }; #endif // ANIMATIONBUTTON_H
animationbutton.cpp

#include "animationbutton.h" #include "qpainter.h" #include "qpropertyanimation.h" #include "qdebug.h" AnimationButton::AnimationButton(QWidget *parent) : QWidget(parent) { enter = true; leave = false; pixWidth = 0; pixHeight = 0; oldWidth = 0; oldHeight = 0; enterAnimation = new QPropertyAnimation(this, ""); enterAnimation->setStartValue(0); enterAnimation->setEndValue(5); enterAnimation->setDuration(200); connect(enterAnimation, SIGNAL(valueChanged(QVariant)), this, SLOT(enterImageChanged(QVariant))); leaveAnimation = new QPropertyAnimation(this, ""); leaveAnimation->setStartValue(0); leaveAnimation->setEndValue(5); leaveAnimation->setDuration(200); connect(leaveAnimation, SIGNAL(valueChanged(QVariant)), this, SLOT(leaveImageChanged(QVariant))); } AnimationButton::~AnimationButton() { delete enterAnimation; delete leaveAnimation; } void AnimationButton::enterEvent(QEvent *) { enter = true; leave = false; pixWidth = pixWidth - 25; pixHeight = pixHeight - 25; enterAnimation->start(); } void AnimationButton::leaveEvent(QEvent *) { enter = false; leave = true; pixWidth = oldWidth; pixHeight = oldHeight; leaveAnimation->start(); } void AnimationButton::paintEvent(QPaintEvent *) { if (image.isEmpty()) { return; } QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); QPixmap pix(image); pix = pix.scaled(targetWidth, targetHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation); if (enter || leave) { int pixX = rect().center().x() - targetWidth / 2; int pixY = rect().center().y() - targetHeight / 2 - 10; QPoint point(pixX, pixY); painter.drawPixmap(point, pix); painter.drawText(QRectF(0, height() - 20, width(), 20), Qt::AlignCenter, text); } } void AnimationButton::enterImageChanged(QVariant index) { int i = index.toInt(); targetWidth = pixWidth + i * 5; targetHeight = pixHeight + i * 5; update(); } void AnimationButton::leaveImageChanged(QVariant index) { int i = index.toInt(); targetWidth = pixWidth - i * 5; targetHeight = pixWidth - i * 5; update(); } void AnimationButton::setImage(QString image) { this->image = image; QPixmap pix(image); pixWidth = pix.width(); pixHeight = pix.height(); oldWidth = pixWidth; oldHeight = pixHeight; targetWidth = pixWidth - 25; targetHeight = pixHeight - 25; update(); } void AnimationButton::setText(QString text) { this->text = text; update(); }
此自定义控件集成在QFramework中。
自定义控件可执行文件下载:http://pan.baidu.com/s/1i5iCfzv
QFramework简介:
QFramework是一套通用的Qt程序开发框架,集成主界面布局、各种自定义控件、数据库处理、excel极速导出、数据打印、串口通信、网络通信、协议解析、全局热键、邮件发送,短信发送,百度地图调用、ffmpeg+vlc处理等功能,将常用的功能封装成类库,提供统一直观的调用接口,方便使用者使用,对应封装的库都有对应的demo程序。
QFramework基本功能:
1:支持从4.7.0到5.7.0的任何Qt版本,不受版本限制。用了此框架,不会再有Qt版本不同而引起的程序编译通不过的烦恼。
2:极速导出数据到excel,支持表格数据或者查询的数据,不依赖任何组件,支持任何excel、wps等表格软件版本,导出10万行数据8个字段只需要3秒完成。对导出的表格样式可自定义主标题和副标题,可对导出的数据按照指定条件红色突出显示。
3:数据导出到pdf及打印功能,支持表格数据或者查询的数据,支持横向纵向打印,自动分页。
4:数据分页dbapi类,只需传入表格对象,表名,翻页按钮即可。无需再写重复的方法处理翻页。
5:各种自定义控件,例如开关按钮、发光按钮,仪表盘控件、音量控件、温湿度控件、仪表仪器类控件等。
6:全新超级中英双拼输入法,非常适合触摸设备。
7:全局热键处理。
8:串口热敏打印机打印。
9:qcustomplot 2D图形曲线绘制(含鼠标数据跟踪)。
10:多线程邮件发送,支持多个接收邮箱。
11:多线程短信发送,支持多个接收号码及长短信。
12:Qffmpeg+Qvlc视频处理。
13:取字模,字符转LED数据处理。
14:全局日志输出类 applog,可动态挂载和卸载。
15:全局程序控制类 appkey,可控制程序的使用时间、运行时间、设备数量限制等。
16:封装百度地图调用接口,支持设备标注、路线查询、位置显示等。
17:自动清理程序早期数据类 cleanapi,传入要清理的数据库表名,执行间隔,保留的最大记录数即可。这样保证了整个系统存储的都是最新的数据。
18:NTP校时服务程序。
19:全局截图处理,可以很方便的直接在ARM上对程序进行截图。
20:程序存活检测功能 applive,通过udp通信实时发送心跳命令,这样可以保证程序7*24小时运行,在ARM上可采用 appdog看门狗程序。
21:已运行时间+当前时间+实时CPU使用率+实时内存使用率等。
22:自定义程序主界面底部信息。
23:Echart图表的交互使用。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律