
简介Qt控件大全是一套面向Qt开发者的控件集合资源集中收录了多种Qt4环境下可直接借鉴的界面组件无论是刚接触Qt的初学者还是需要拓展自定义控件的进阶开发者都能从中获得参考。压缩包共60个文件以cpp与h源文件为主体26个cpp、25个h另含ui界面文件、qrc资源文件、pro工程文件及图标图片等整体仅101KB结构紧凑适合按模块拆解研读。目前已有2693人学习或下载。资料除常见按钮、输入框、文本编辑框、视图控件等基础组件外还展示了仪表盘、进度条、波形、电池、滑动按钮等大量自绘控件并包含myValueControl完整自定义控件工程覆盖QPainter绘图、信号槽通信、布局管理、资源文件组织等关键知识点。通过阅读这些源码和工程配置读者能清晰理解Qt自定义控件的开发流程也便于将其中设计直接复用到自己的应用中。 Qt 控件 大全这几个字看起来像是凑检索量的但真要把 Qt 的控件体系梳理清楚并且能在项目里用得顺手还真不是拉一张列表就完事。我这些年用 Qt 做上位机、做桌面工具、做工业看板在控件上踩过的坑比想象中多得多。这篇文章不打算给你堆一个又臭又长的控件清单而是从实际使用的角度把 Qt 控件里真正影响开发效率的东西串一遍装环境、调布局、解决间距问题、串口和绘图实战、最后再说说打包和崩溃排查。不管你是刚接触 Qt 的新手还是已经被平台插件报错折磨过的老油条应该都能从里面找到点有用的东西。1. 先把 Qt 控件这张地图铺开1.1 控件家族其实就四大类很多初学者拿到 Qt 的第一反应是去查控件列表看到一个 QPushButton 就试一个结果两天下来脑子全是浆糊。其实 Qt 控件的分类逻辑非常清楚按使用场景划分核心就四大类。分类典型控件核心使用场景基础交互QPushButton、QLineEdit、QComboBox、QCheckBox、QRadioButton、QSpinBox、QSlider表单页面、设置界面、工具栏操作容器与布局QWidget、QGroupBox、QTabWidget、QStackedWidget、QSplitter、QScrollArea页面骨架搭建、分组管理、多页切换数据展示QTableView、QTreeView、QListView、QTableWidget、QTreeWidget、QListWidget表格明细、树形结构、日志列表绘图与图表QPainter、QChart、QCustomPlot、Q3DSurface波形显示、趋势图、三维可视化这里要特别提醒一句Qt 5 和 Qt 6 的控件体系差异其实没有想象中那么大绝大多数 QWidget 控件在 Qt 6 里照样能用。真正需要注意的是模块划分比如 QChart 从 Qt 5.7 开始单独拆成了 Qt Charts 模块如果用开源版编译得在安装器里主动勾选不然后面 code 里 include 了半天查不到头文件白白浪费时间。1.2 选控件之前先想清楚三件事控件选型决定了一个功能模块后续要改多少代码我一般会在动手前问自己三个问题。第一是数据量。列表里如果只有几十条数据用 QListWidget 或者 QTableWidget 完全没问题但数据量一旦上千甚至上万就必须用 QTableView 配合 Model/View 架构。我接过一个项目原来的同事用 QTextEdit 当日志窗口跑了一个小时后界面卡死换成 QListView 加 QStringListModel 之后内存占用直接降了将近一半UI 线程也不再掉帧了。第二是交互频率。如果是传感器波形这种高频刷新的场景QChart 内部重绘开销比较大实测下来 QCustomPlot 在大量数据点下的表现会稳很多。第三是定制深度。如果界面需要高度自定义外观控件本身只是兜底的真正干活的是 QPainter 和样式表。这几个问题想明白了控件选择就不会纠结太久。2. 环境安装下载、国内镜像和离线部署2.1 下载安装的正确姿势Qt 的下载安装是所有坑的起点尤其是从官网直接点下载那个在线安装器在国内网络下经常让人怀疑人生。我自己的做法是直接用国内镜像站清华、中科大的开源镜像都比较稳把安装包列表拉下来选好操作系统对应的版本下载速度能快出几个量级。版本选择上如果是做正式项目Qt 5.15.2 和 Qt 6.5 LTS 这两个长期支持版本是比较稳妥的选择5.15.2 胜在生态兼容好很多第三方库还停留在基于 Qt5 的构建方式6.5 则适合新项目未来的维护周期更长。安装器里组件勾选也讲究不要图省事全选也不要只选默认。编译器套件、Qt Charts、Qt Data Visualization、Qt Multimedia 这些按需勾选Source Components 一般不勾白白占空间。勾选完组件安装时最好把安装路径记下来后面配置构建套件Kit要用。2.2 麒麟系统离线安装的实操记录工业现场和政企项目里麒麟系统配 x86 架构很常见而且这种环境往往内网隔离没法在线安装。我之前在麒麟 V10 上装 Qt 5.15.2用的方案是找一台可以联网的机器从镜像站下载 run 后缀的离线安装包拷进内网之后直接执行安装。这里有个容易忽略的点安装包执行后默认走的还是图形安装向导如果目标机器没有桌面环境需要用./qt-opensource-linux-x64-5.15.2.run --platform offscreen这样带参数的方式启动否则界面起不来。装完之后最常遇到的问题就是缺系统库常见的比如libGL.so.1、fontconfig等用 yum 安装对应包就能解决。还有一点麒麟系统自带的 gcc 版本可能和 Qt 编译套件不完全匹配建议在 Configure 阶段多试几个 Kit不要一棵树上吊死。2.3 装完之后先验证这几件事环境装好不要急着写业务代码先做三个小验证。第一在命令行敲qmake --version确认 qmake 路径是安装目录下的那个不是系统自带的旧版本。第二新建一个最简单的 Widgets 工程跑起来看窗口能不能正常弹出。第三如果后面要用 QCustomPlot先把第三方库编译一遍确认能链接通过。这三步走完环境基本就稳了后面再报错大概率是代码问题排查范围会小很多。3. 布局与间距界面好不好看全看这里3.1 布局管理器是子控件间距的答案热词里有个“子控件间距”很多人一上来就在代码里 setGeometry 手写坐标然后发现窗口一拉伸整个界面的控件挤成一团或者相互重叠。Qt 的布局管理器Layout就是为了解决这个问题设计的QHBoxLayout 管水平排列QVBoxLayout 管垂直排列QGridLayout 管网格排列QFormLayout 管表单里的标签和输入框对齐。用布局管理器之后子控件的间距统一由两个接口控制setSpacing设置控件之间的间隔setContentsMargins设置布局边缘和窗口边缘的留白。实际开发里我一般这样设置QVBoxLayout *mainLayout new QVBoxLayout(centralWidget); mainLayout-setSpacing(8); mainLayout-setContentsMargins(12, 12, 12, 12);这样设置之后窗口无论拉伸到多大控件之间的间距都是 8 像素边缘留白始终是 12 像素整体视觉不会散架。表单类的界面我特别推荐 QFormLayout它把“标签”和“输入控件”的对应关系管理得非常清楚比手工拼 QHBoxLayout 省事得多。3.2 想让控件听话还得理解 sizePolicy 和弹簧光会 setSpacing 只能解决基础间距真正让布局变得灵活好用还要理解两个概念sizePolicy 和 stretch 弹簧。sizePolicy 决定了控件在布局中被拉伸或压缩时的行为比如一个 QLineEdit默认的策略是水平方向可以拉伸、垂直方向固定所以表单里输入框会自动撑满剩余宽度而 QLabel 默认是固定大小不会随便变。如果想让某个控件在窗口缩放时始终保持居中或者在某一侧留出动态空白就需要在布局里插入弹簧layout-addStretch(); layout-addWidget(button); layout-addStretch();这个 addStretch 就相当于两边的弹性空白按钮自然就被推到水平居中的位置。我在做登录框界面时用的就是 QVBoxLayout 加 QFormLayout 加 addStretch 的组合整个界面在任意分辨率下都能保持合适的垂直位置不贴顶也不贴底。很多新手写界面总觉得“控件不听使唤”本质上就是没理解 sizePolicy 和 stretch 的配合这两个概念吃透了布局这块基本就通了。3.3 Qt Designer 和 VSCode 的配置写界面我不太建议纯代码撸到底太慢。Qt Creator 自带的 Designer 做拖拽布局很高效但如果你习惯用 VSCode 写代码也可以在 VSCode 里配置 Qt Designer实现 ui 文件的可视化编辑。具体做法是装一个 Qt 相关插件然后在设置里指定 designer 可执行文件路径通常就是 Qt 安装目录下bin/designer.exeWindows或bin/designerLinux。配置好之后双击 ui 文件会自动用 Designer 打开保存后用构建工具重新生成对应的 ui_xxx.h 头文件再在代码里 include 就能用了。这里有个经验要提Designer 里拖出来的控件属性面板默认会写死 geometry如果你的界面是自适应布局记得在改完后点一下“打破布局”再重新布局不然会出现预览正常、运行起来却错位的情况。另外ui 文件改动后如果没有重新编译运行还是旧界面这个问题我见过不下三次都是同事在那使劲改代码结果界面纹丝不动最后发现是没重新生成 ui 头文件。4. 高频实战串口、绘图、表格和外部组件4.1 串口编程QSerialPort 和串口下拉框串口是 Qt 上位机最常用的功能之一QSerialPort 模块用起来非常直接。先枚举当前系统的可用串口把串口号填进 QComboBoxforeach (const QSerialPortInfo info, QSerialPortInfo::availablePorts()) { ui-comboPort-addItem(info.portName()); }然后打开并配置串口参数QSerialPort serial; serial.setPortName(ui-comboPort-currentText()); serial.setBaudRate(QSerialPort::BaudRate::Baud115200); serial.setDataBits(QSerialPort::DataBits::Data8); serial.setParity(QSerialPort::Parity::NoParity); serial.setStopBits(QSerialPort::StopBits::OneStop); serial.open(QIODevice::ReadWrite);接收数据用 readyRead 信号在槽函数里读取readAll()的内容进行解析。踩过的坑主要有两个一个是串口被其他程序占用open 返回 false 却没有提示原因建议 open 失败时打印serial.errorString()帮助定位另一个是接收数据拼包问题串口底层一包数据可能被拆成多次 readyRead 到达不能简单认为每次信号就是完整一帧需要自己做缓存和帧边界判断。4.2 QCustomPlot kissfft时域转频域热词里有“qt 时域图转换为频域图”这是一个很典型的场景采集到一串时域波形想看它的频谱特征。绘图部分我推荐 QCustomPlot使用 kissfft 做傅里叶变换两个库加起来代码量不大效果却很稳定。kissfft 的使用核心就是创建配置对象、填充输入数组、执行变换然后取模算幅值int nfft 1024; kiss_fft_cfg cfg kiss_fft_alloc(nfft, 0, nullptr, nullptr); kiss_fft_cpx *in new kiss_fft_cpx[nfft]; kiss_fft_cpx *out new kiss_fft_cpx[nfft]; for (int i 0; i nfft; i) { in[i].r timeData[i]; in[i].i 0.0; } kiss_fft(cfg, in, out, 1); kiss_fft_free(cfg); QVectordouble freqData(nfft / 2); for (int i 0; i nfft / 2; i) { freqData[i] sqrt(out[i].r * out[i].r out[i].i * out[i].i) / (nfft / 2); }拿到频域数据之后用 QCustomPlot 的 addGraph 创建一条曲线setData 设置数据点rescaleAxes 自动缩放坐标轴最后 replot 刷新绘图。这里有个关键细节频谱图横坐标不是采样点序号而是频率值需要根据采样率和 nfft 计算否则画出来的波形横轴和实际频率对不上。实测下来QCustomPlot 对几万个点的绘制依然流畅做实时滚动频谱没有压力。4.3 表格筛选、QChart 缩放和三维曲线表格控件方面经常有人问类似 .NET 里表格控件带 Excel 那种筛选功能Qt 里怎么做。Qt 里对应的方案是 QTableView 加 QSortFilterProxyModel这个代理模型专门用来做排序和过滤。实现思路是给主模型加一层代理界面上看到的排序结果并不会改动原始数据proxyModel new QSortFilterProxyModel(this); proxyModel-setSourceModel(model); proxyModel-setFilterKeyColumn(1); proxyModel-setFilterRegularExpression(QRegularExpression(关键词)); ui-tableView-setModel(proxyModel);用户在某列输入筛选条件代理模型自动过滤源数据效果和 Excel 的列筛选非常像。图表方面QChart 说白了就是 Qt 自家的图表库想要图片缩放功能直接设置 rubberBand 就能实现框选放大chartView-setRubberBand(QChartView::RectangleRubberBand);三维曲线可以用 Qt Data Visualization 模块里的 Q3DSurface常用在三维地形和频谱瀑布图pro 文件里要记得加QT datavisualization。4.4 Qt 和外部生态的协作实际项目很少只用 Qt 自己免不了要和各种外部组件打交道。调用 Halcon 做视觉处理是常见需求核心思路是把 Halcon 的图像对象 HObject 和 Qt 的 QImage 互相转换然后把 Halcon 的处理结果封装成一个独立算法模块界面只负责显示这样两边能保持解耦。行业里还有一套 PageOffice 这样的 Office 控件在 Qt 里可以通过 QAxWidget 嵌入 ActiveX相当于在 Qt 界面上挂载一个 COM 组件。这里有个很典型的坑PageOffice 控件安装后仍然提示需要安装通常不是控件本身没装而是 DLL 没有成功注册。Windows 下用系统管理员权限运行regsvr32 控件路径如果系统是 64 位而控件是 32 位注册命令的路径也不一样位数不匹配会一直注册失败。还有 Win7 系统下面注册 ActiveX 时报错十有八九是权限问题右键“以管理员身份运行”命令提示符再执行注册基本能解决。5. 打包发布与崩溃排查5.1 windeployqt 打包一条命令背后的坑Qt 程序开发完要发给别人用直接拷贝 exe 双击通常报错因为缺动态库。Qt 官方提供的 windeployqt 工具就是干这个的用法很简单打开 Qt 对应的命令行环境进入 exe 所在目录执行windeployqt YourApp.exe它会自动把依赖的 Qt 库、平台插件、样式插件都拷贝到 exe 同目录。但要注意几件事第一必须用和编译套件对应的 windeployqt比如 MinGW 编译的工程不要用 MSVC 版本的 windeployqt不然打出来的包缺东西或者版本不对。第二如果程序里用了 QCustomPlot、Halcon 等第三方库windeployqt 不会处理这些需要手动拷贝对应的 dll。第三打包完成后要把整个目录压缩发给别人不要只发一个 exe。5.2 platform plugin could not be initialized热词里出现“windows no qt platform plugin could be initialized”这大概是 Qt 打包发布最常见的报错。这个错误的意思是程序启动时找不到平台插件所谓平台插件就是 Qt 用来对接操作系统的底层模块Windows 下对应的是 platforms 目录里的 qwindows.dll。最常见的原因是 windeployqt 没有正确执行platforms 文件夹没生成或者程序是从别的机器拷过来缺少对应编译套件的插件文件。解决办法分三步排查第一步确认 exe 同目录下存在 platforms/qwindows.dll第二步确认插件位数和应用位数一致32 位应用配 32 位插件第三步如果你在代码里手动设置过插件路径可以用QApplication::addLibraryPath()把插件目录加进去而不要依赖系统环境变量。这个错误还有一个变种是开发机上跑得好好的拿到别的电脑就报错多半是目标机器缺少 VC 运行库装上对应版本的 vcredist 就能解决。5.3 POST 请求拿不到数据、QML 点击报错Qt 里面做 POST 请求一般用 QNetworkAccessManager代码模式很固定QNetworkAccessManager *manager new QNetworkAccessManager(this); QNetworkRequest request; request.setUrl(QUrl(http://your-api.com/submit)); request.setHeader(QNetworkRequest::ContentTypeHeader, application/json); QNetworkReply *reply manager-post(request, jsonData.toUtf8()); connect(reply, QNetworkReply::finished, this, []() { if (reply-error() QNetworkReply::NoError) { QString result QString::fromUtf8(reply-readAll()); } reply-deleteLater(); });“post 请求 无法获取”这个问题常见原因有三个。第一个是服务器返回了不支持的响应格式但 QNetworkReply 没有实时输出错误信息建议在 finished 里先打印 reply-errorString()。第二个是请求头设置不对接口要求 JSON你发的是表单格式服务器直接拒绝这种情况要严格按接口文档设置 Content-Type。第三个是同步等待的问题新手喜欢用 QEventLoop 把请求变成“同步”但其实很容易死锁真正需要等待时建议把流程拆成状态机或者用异步回调链。QML 控件点击事件报错之后界面无响应也是常见问题。QML 里的 JS 函数一旦抛异常如果没做捕获最直观的表现是 UI 卡住或者状态不刷新。处理方式是在每个点击处理函数里加 try/catch把错误信息打印到控制台同时在 catch 之后用一个 reset 函数把界面状态恢复到初始值避免一个错误把整个界面的交互逻辑拖垮。我的几点体会最后再分享一点实操层面的感受。Qt 控件这个东西文档和列表都只是入门素材真正拉开差距的是组合使用能力和问题排查能力。我自己在项目里最深刻的体会是布局、绘图、串口、打包这些环节看着各自独立实际环环相扣比如布局没做好后面加功能就要大面积返工打包流程没走通功能再完善也交付不了。建议新手朋友不要急着追新版本先把一个 LTS 版本吃透从环境安装到发布部署完整走一遍流程这个过程中踩过的坑比你看十遍文档都值钱。希望这篇内容能帮你在 Qt 控件的路上少走几步弯路。本文还有配套的精品资源点击获取