先按用户要完成的动作选控件
跳转到“先按用户要完成的动作选控件”原笔记汇集了数值输入、选项选择、条目列表和容器控件。它们都属于 Qt Widgets 界面开发,但职责不同:输入控件保存用户选择,容器控件组织其他控件,布局负责分配空间。
| 需求 | 常用控件 | 关键区别 |
|---|---|---|
| 输入有范围的整数 | QSpinBox | 数值与单位显示可以分开处理;小数用 QDoubleSpinBox |
| 从候选项中选一个 | QComboBox | 用紧凑下拉框显示候选项,可按需求允许编辑 |
| 同时看到多个条目并选择 | QListWidget | 条目式便捷列表;复杂或共享数据可考虑 QListView 与模型 |
QSpinBox:数值与单位
跳转到“QSpinBox:数值与单位”转速输入示例设置范围 0~10000,初值 600,后缀为 RPM。后缀只用于显示,程序仍应通过 value() 获取整数,不需要从显示文本里手动删除单位。QSpinBox 文档

原图显示的是 10000 RPM,原代码初值是 600;这只是两个不同状态,不能把截图数值当作代码默认值。范围、步长和零值含义应由业务确定,示例数字不代表电机的实际能力。
QComboBox:文字不是稳定标识
跳转到“QComboBox:文字不是稳定标识”下拉框可以显示 “Option 1” 等文字,但业务上最好同时保存稳定数据,例如整数编号或枚举值,并通过 currentData() 获取。这样重命名和翻译选项不会改变业务含义。
currentIndexChanged 会响应程序设置和用户操作引起的索引变化;activated 主要用于响应用户选择。没有选项时,当前索引可以是 −1,读取数据前应处理空状态。QComboBox 文档

QListWidget:选择、排序和拖动
跳转到“QListWidget:选择、排序和拖动”QListWidgetItem 表示条目,可携带文字、图标、提示等数据。选择模式由 setSelectionMode() 指定:SingleSelection 适合单项,ExtendedSelection 支持常见的组合键多选,MultiSelection 适合逐项切换选择。
排序和手动重排是不同需求。sortItems() 按条目排序;列表内部拖动重排需要显式设置 InternalMove 等拖放行为,不能仅因为类“支持拖放”就假定默认已启用。若要求用户手工控制顺序,通常不应同时开启自动排序。QListWidget、QAbstractItemView 拖放模式

这张原图只展示文字和选择效果,不能证明排序或拖放已经配置。数量变化和空状态的处理另见列表数量变化。
三种控件的完整示例
跳转到“三种控件的完整示例”保存为 main.cpp。正常运行显示界面;附加 --test 参数检查数值约束、稳定选项数据和列表选择状态。
#include <QApplication>#include <QComboBox>#include <QDebug>#include <QFormLayout>#include <QListWidget>#include <QSpinBox>#include <QVariant>#include <QWidget>
int main(int argc, char *argv[]){ QApplication app(argc, argv); QWidget window; window.setWindowTitle(QStringLiteral("输入与选择控件")); auto *form = new QFormLayout(&window);
auto *speed = new QSpinBox(&window); speed->setObjectName("minSpeedSpinBox"); speed->setRange(0, 10000); speed->setValue(600); speed->setSuffix(QStringLiteral(" RPM")); form->addRow(QStringLiteral("最小转速"), speed);
auto *mode = new QComboBox(&window); for (int i = 1; i <= 4; ++i) mode->addItem(QStringLiteral("Option %1").arg(i), i); form->addRow(QStringLiteral("模式"), mode);
auto *list = new QListWidget(&window); list->addItems({QStringLiteral("Item 1"), QStringLiteral("Item 2"), QStringLiteral("Item 3")}); list->setSelectionMode(QAbstractItemView::SingleSelection); list->setDragDropMode(QAbstractItemView::InternalMove); list->setSortingEnabled(false); form->addRow(QStringLiteral("项目"), list);
if (app.arguments().contains(QStringLiteral("--test"))) { const auto expect = [](bool ok, const char *message) { if (!ok) qFatal("Test failed: %s", message); }; expect(speed->value() == 600, "initial speed"); speed->setValue(20000); expect(speed->value() == 10000, "range clamps value"); expect(speed->text().endsWith(" RPM"), "unit suffix"); mode->setCurrentIndex(2); expect(mode->currentData().toInt() == 3, "stable option data"); list->setCurrentRow(1); expect(list->count() == 3 && list->selectedItems().size() == 1, "single selection"); mode->clear(); expect(mode->currentIndex() == -1, "empty combo state"); qInfo() << "Widget selection tests passed"; return 0; }
window.resize(420, 300); window.show(); return app.exec();}使用下面的 CMakeLists.txt,并配置与 Qt 安装匹配的编译器及 CMAKE_PREFIX_PATH:
cmake_minimum_required(VERSION 3.21)project(widget_selection_demo LANGUAGES CXX)set(CMAKE_CXX_STANDARD 17)set(CMAKE_CXX_STANDARD_REQUIRED ON)find_package(Qt6 REQUIRED COMPONENTS Widgets)add_executable(widget_selection_demo main.cpp)target_link_libraries(widget_selection_demo PRIVATE Qt6::Widgets)本例已在 Windows、Qt 6.10.2、MinGW 下编译,并在 offscreen 模式通过上述状态检查。实际拖动、键盘和触摸操作仍应在目标界面上验证。
原笔记中的容器控件清单
跳转到“原笔记中的容器控件清单”容器通常负责容纳页面或子控件,不应代替业务模型。原稿列出的名称整理如下;具体行为可从 Qt Widgets 类别索引进入对应文档。
| 控件 | 主要用途 | 使用时留意 |
|---|---|---|
QDockWidget | 主窗口中的可停靠面板 | 一般配合 QMainWindow 的停靠区域 |
QFrame | 带边框或面板外观的基础容器 | 本身不自动安排子控件位置 |
QGroupBox | 带标题的逻辑分组,可按需带勾选状态 | 需要为内部控件设置布局 |
QScrollArea | 为一个内容控件提供滚动视口 | 多个控件先放进内容容器,再设置布局 |
QMdiArea | 管理多个子窗口 | 适合确有多文档窗口需求的界面 |
QTabWidget | 用标签切换多个页面 | 每页内部仍需独立布局 |
QToolBox | 按分组标题切换内容页 | 适合工具或属性分组 |
QStackedWidget | 保存多个页面并显示当前页 | 切换按钮或导航需要另行提供 |
QWizard | 管理多步骤向导流程 | 前进、后退与完成逻辑由向导协调 |
QWizardPage | 向导中的一个页面 | 与页面校验和字段状态配合 |
来源与修订
跳转到“来源与修订”本页重写自控件了解记录。保留全部控件名称、转速范围及初值、四个下拉选项、列表功能意图和三张图片;将图片可读内容转为文字,去掉双层代码围栏和完全重复的列表程序,并补齐完整示例。