写点什么

基于 Qt 编写超精美自定义控件

作者:向阳逐梦
  • 2023-07-19
    四川
  • 本文字数:5032 字

    阅读完需:约 17 分钟

基于Qt编写超精美自定义控件

一、前言

无论是哪一门开发框架,如果涉及到 UI 这块,肯定需要用到自定义控件,越复杂功能越多的项目,自定义控件的数量就越多,最开始的时候可能每个自定义控件都针对特定的应用场景,甚至里面带了特定的场景的一些设置和处理,随着项目数量的增多,有些控件又专门提取出来共性,做成了通用的自定义控件,意味着控件主要做外观处理,用户根据不同的场景需要,设置不同的外观和规则,就这样搞来搞去搞到现在,已经超过了 202 个控件,慢慢的积累迭代和更新,历经超过 9 年的时间不断的完善,尤其是对不同 Qt 版本、不同编译器、不同操作系统的支持,其中 Qt6 改动比较大,很多方法或者类改名或者废弃了,需要用类似的方法处理,在改完整个自定义控件大全后,特意整理了升级到 Qt6 经验大全,放在开源主页上,合并在 Qt 开发经验中,目前该经验可能是国内 Qt 开发界最受欢迎的开发经验总结。

二、效果图



三、体验地址

国内站点:gitee.com/feiyangqingyun

国际站点:github.com/feiyangqingyun

四、功能特点


  • 超过 202 个精美控件并持续不断迭代更新升级,种类超多,控件类型极其丰富。

  • 涵盖了各种仪表盘、进度条、进度球、指南针、曲线图、标尺、温度计、导航条、导航栏,flatui、高亮按钮、滑动选择器、农历、广告轮播、饼状图、环形图、时间轴、拓展控件、增强控件等。

  • 每个类都是独立的一个.h 头文件和.cpp 实现文件组成,零耦合,不依赖其他文件,方便单个控件独立出来以源码形式集成到项目中,方便直观。

  • 控件数量远超其他第三方控件库比如 qwt 集成的控件数量,使用方式也比其简单友好零耦合。

  • 支持任意 Qt 版本,亲测 Qt4/5/6 的所有版本,全部纯 Qt 编写,QWidget+QPainter 绘制。

  • 支持任意编译器,包括但不限于 mingw、msvc、gcc、clang 等编译器。

  • 支持任意操作系统,包括但不限于 windows、linux、mac、android、uos、银河麒麟、各种国产 linux、嵌入式 linux、树莓派、香橙派、全志 H3 等。

  • 支持编译生成设计师插件,可直接集成到 QtCreator 的控件栏中,和自带的控件一样使用,大部分效果只要设置几个属性即可,极为方便。

  • 支持编译生成独立的非插件形式的动态库文件,体积小,比如嵌入式 linux 不支持 designer 只需要动态库的形式。

  • 每个控件都有一个单独的完整的使用 demo,方便参考学习单个控件使用,非常适合初学者。

  • 提供一个所有控件使用的集成的 example,方便快速查看所有控件的效果。

  • 支持直接源码集成到 example 的方式,方便编译到安卓,for web 套件等。

  • 支持编译成 wasm 文件,直接网页运行,可以在谷歌、火狐、edge 等浏览器运行,原生性能。

  • 每个控件的源代码都有详细中文注释,都按照统一设计规范编写,方便学习自定义控件的编写。

  • 每个控件都内置默认配色,demo 对应的配色都非常精美。

  • 部分控件提供多种样式风格选择,多种指示器样式选择。

  • 所有控件自适应布局和窗体拉伸变化,自动缩放。

  • 配套额外的自定义控件属性设计器,类似组态设计器,纯中文属性名称,支持拖曳设计,所见即所得,支持导入导出 xml 格式。

  • 集成 fontawesome 图形字体+阿里巴巴 iconfont 收藏的几百个图形字体,享受图形字体带来的乐趣。

  • 所有控件最后生成一个 dll 动态库文件,可以直接集成到 qtcreator 中拖曳设计使用。

  • 控件源码全部分门别类存放,pri 模块形式集成,提供控件对照表快速查找对应控件和说明。

五、相关代码

#pragma execution_character_set("utf-8")#include "frmexamplessimple.h"#include "ui_frmexamplessimple.h"#include "head.h"#include "../../demo/gauge/gaugecar/frmgaugecar.h"#include "../../demo/gauge/gaugecloud/frmgaugecloud.h"#include "../../demo/gauge/gaugecolor/frmgaugecolor.h"#include "../../demo/gauge/gaugecompass/frmgaugecompass.h"#include "../../demo/gauge/gaugecompasspan/frmgaugecompasspan.h"#include "../../demo/gauge/gaugedial/frmgaugedial.h"#include "../../demo/gauge/gaugemini/frmgaugemini.h"#include "../../demo/gauge/gaugepanel/frmgaugepanel.h"#include "../../demo/gauge/gaugeprogress/frmgaugeprogress.h"#include "../../demo/gauge/gaugespeed/frmgaugespeed.h"#include "../../demo/progress/progressbutton/frmprogressbutton.h"#include "../../demo/progress/progresspercent/frmprogresspercent.h"#include "../../demo/progress/progressring/frmprogressring.h"#include "../../demo/progress/progressshadow/frmprogressshadow.h"#include "../../demo/progress/progresstip/frmprogresstip.h"#include "../../demo/painter/battery/frmbattery.h"#include "../../demo/painter/lightbutton/frmlightbutton.h"#include "../../demo/painter/lunarcalendarwidget/frmlunarcalendarwidget.h"#include "../../demo/painter/magicpoolfish/frmmagicpoolfish.h"#include "../../demo/painter/telwidget/frmtelwidget.h"#include "../../demo/custom/customring/frmcustomring.h"#include "../../demo/custom/customgraphics/frmcustomgraphics.h"#include "../../demo/custom/shadowcalendar/frmshadowcalendar.h"#include "../../demo/custom/spiderchart/frmspiderchart.h"#include "../../demo/custom/timeaxis/frmtimeaxis.h"#include "../../demo/custom/customdart/frmcustomdart.h"#include "../../demo/custom/tasktableview/frmtasktableview.h"#include "../../demo/ruler/rulerprogress/frmrulerprogress.h"#include "../../demo/color/colorpanel/frmcolorpanel.h"#include "../../demo/image/adswidgetx/frmadswidgetx.h"#include "../../demo/image/imageclock/frmimageclock.h"#include "../../demo/other/selectwidget/frmselectwidget.h"#include "../../demo/wave/wavewater/frmwavewater.h"#include "../../demo/slider/sliderselect/frmsliderselect.h"#include "../../demo/flight/frmflightall.h"frmExamplesSimple::frmExamplesSimple(QWidget *parent) : QWidget(parent), ui(new Ui::frmExamplesSimple){    ui->setupUi(this);    this->initForm();    this->addItem();}frmExamplesSimple::~frmExamplesSimple(){    delete ui;}void frmExamplesSimple::paintEvent(QPaintEvent *){    QPainter painter(this);    painter.drawTiledPixmap(rect(), bgPix);}void frmExamplesSimple::initForm(){    bgPix = QPixmap(":/image/bg.png");    connect(ui->navListView, SIGNAL(pressed(QString, QString)), this, SLOT(pressed(QString, QString)));    //设置文本边距    ui->navListView->setChildMargin(28);    ui->navListView->setFixedWidth(190);    ui->navListView->setExpendMode(NavListView::ExpendMode_SingleClick);    ui->navListView->setSeparateColor(QColor(40, 43, 51));    //设置子节点颜色    ui->navListView->setChildBgNormalColor(QColor(40, 43, 51));    ui->navListView->setChildBgSelectedColor(QColor(20, 20, 20));    ui->navListView->setChildBgHoverColor(QColor(20, 20, 20));    ui->navListView->setChildTextNormalColor(QColor(180, 180, 180));    ui->navListView->setChildTextSelectedColor(QColor(250, 250, 250));    ui->navListView->setChildTextHoverColor(QColor(255, 255, 255));    //设置父节点颜色    ui->navListView->setParentBgNormalColor(QColor(57, 61, 73));    ui->navListView->setParentBgSelectedColor(QColor(78, 83, 102));    ui->navListView->setParentBgHoverColor(QColor(78, 83, 102));    ui->navListView->setParentTextNormalColor(QColor(250, 250, 250));    ui->navListView->setParentTextSelectedColor(QColor(250, 250, 250));    ui->navListView->setParentTextHoverColor(QColor(250, 250, 250));}void frmExamplesSimple::addItem(){    ui->stackedWidget->addWidget(new frmGaugeCar);    ui->stackedWidget->addWidget(new frmGaugeCloud);    ui->stackedWidget->addWidget(new frmGaugeColor);    ui->stackedWidget->addWidget(new frmGaugeCompass);    ui->stackedWidget->addWidget(new frmGaugeCompassPan);    ui->stackedWidget->addWidget(new frmGaugeDial);    ui->stackedWidget->addWidget(new frmGaugeMini);    ui->stackedWidget->addWidget(new frmGaugePanel);    ui->stackedWidget->addWidget(new frmGaugeProgress);    ui->stackedWidget->addWidget(new frmGaugeSpeed);    ui->stackedWidget->addWidget(new frmProgressButton);    ui->stackedWidget->addWidget(new frmProgressPercent);    ui->stackedWidget->addWidget(new frmProgressRing);    ui->stackedWidget->addWidget(new frmProgressShadow);    ui->stackedWidget->addWidget(new frmProgressTip);    ui->stackedWidget->addWidget(new frmBattery);    ui->stackedWidget->addWidget(new frmLightButton);    ui->stackedWidget->addWidget(new frmLunarCalendarWidget);    ui->stackedWidget->addWidget(new frmMagicPoolFish);    ui->stackedWidget->addWidget(new frmTelWidget);    ui->stackedWidget->addWidget(new frmCustomRing);    ui->stackedWidget->addWidget(new frmCustomGraphics);    ui->stackedWidget->addWidget(new frmShadowCalendar);    ui->stackedWidget->addWidget(new frmSpiderChart);    ui->stackedWidget->addWidget(new frmTimeAxis);    ui->stackedWidget->addWidget(new frmCustomDart);    ui->stackedWidget->addWidget(new frmTaskTableView);    ui->stackedWidget->addWidget(new frmRulerProgress);    ui->stackedWidget->addWidget(new frmColorPanel);    ui->stackedWidget->addWidget(new frmAdsWidgetx);    ui->stackedWidget->addWidget(new frmImageClock);    ui->stackedWidget->addWidget(new frmSelectWidget);    ui->stackedWidget->addWidget(new frmWaveWater);    ui->stackedWidget->addWidget(new frmSliderSelect);    ui->stackedWidget->addWidget(new frmFlightAll);    listName << "汽车仪表盘" << "云台仪表盘" << "多彩仪表盘" << "指南针表盘" << "指南针面板"             << "旋转仪表盘" << "迷你仪表盘" << "面板仪表盘" << "进度仪表盘" << "速度仪表盘";    listName << "按钮进度条" << "百分比进度" << "环形进度条" << "光晕进度条" << "提示进度条";    listName << "电池电量" << "高亮按钮" << "农历控件" << "游动的鱼" << "手机通讯录";    listName << "环形图表" << "多边形状" << "光晕日历" << "蜘蛛网图" << "垂直时间轴"             << "自定义飞镖盘" << "任务策略表格";    listName << "进度标尺" << "颜色面板" << "图片轮播" << "图片时钟" << "描点跟随"             << "水波效果" << "范围选择条" << "飞控套件";    addItem("精美控件", listName);    QString item = listItem.join(",");    ui->navListView->setItems(item);    this->setWindowTitle("Qt自定义控件大全 V2023 (QQ: 517216493 WX: feiyangqingyun)");    ui->navListView->setCurrentRow(0);}void frmExamplesSimple::addItem(const QString &parentName, const QStringList &childNames){    //设置节点数据格式: 标题|父节点标题(父节点为空)|是否展开(0展开)|提示信息|左侧图标    int count = childNames.count();    listItem << QString("%1||0|%2|").arg(parentName).arg(count);    for (int i = 0; i < count; ++i) {        listItem << QString("%1. %2|%3|1||0xf0da").arg(i + 1, 2, 10, QChar('0')).arg(childNames.at(i)).arg(parentName);    }}void frmExamplesSimple::pressed(const QString &childText, const QString &parentText){    //如果带了 . 表示序号,要删除再比较    QString text = childText;    if (text.contains(".")) {        text = text.mid(text.indexOf(".") + 2, text.length());    }    int index = listName.indexOf(text);    if (index >= 0) {        ui->stackedWidget->setCurrentIndex(index);    }}
复制代码


发布于: 刚刚阅读数: 5
用户头像

向阳逐梦

关注

人生享受编程,编程造就人生! 2022-06-01 加入

某公司芯片测试工程师,嵌入式开发工程师,InfoQ签约作者,阿里云星级博主,华为云·云享专家。座右铭:向着太阳,追逐梦想!

评论

发布
暂无评论
基于Qt编写超精美自定义控件_向阳逐梦_InfoQ写作社区