1.01 高 DPI 缩放
在 main() 函数开头调用
// 确保应用在高分辨率屏幕上显示清晰。
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);,
1.02 QApplication:全局事件过滤
全局事件过滤:为 QApplication 安装事件过滤器,可以捕获应用内所有对象的事件,用于实现全局快捷键、空闲检测、统一的日志记录等。
class GlobalFilter : public QObject {
protected:
bool eventFilter(QObject *obj, QEvent *event) override {
if (event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
if (keyEvent->key() == Qt::Key_F12) {
toggleDebugOverlay();
return true; // 消费事件
}
}
return false;
}
};
// 在 main 中
GlobalFilter *filter = new GlobalFilter(&app);
app.installEventFilter(filter);
应用场景:调试工具、监控应用、需要在任何界面响应快捷键的专业软件。
结合 QIcon 的 addPixmap() 方法为按钮的不同状态(正常、悬停、按下禁用)设置不同的图标。
应用场景:制作美观的工具栏按钮或游戏 UI,提供清晰的视觉反馈:
QIcon icon;
icon.addPixmap(QPixmap(":/icons/normal.png"), QIcon::Normal);
icon.addPixmap(QPixmap(":/icons/hover.png"), QIcon::Active);
icon.addPixmap(QPixmap(":/icons/pressed.png"), QIcon::Selected);
button->setIcon(icon);
1.04 QLineEdit:输入验证与自定义补全
使用 QValidator (如 QIntValidator, QDoubleValidator, QRegExpValidator) 或重写 validate() 方法实现严格的输入控制。
结合 QCompleter 实现智能提示。
限制为 1-100 的整数:
lineEdit->setValidator(new QIntValidator(1, 100, this));
应用场景:自定义补全(表单输入、搜索框、代码编辑器的关键字提示)
QStringList words = {"apple", "application", "banana", "cherry"};
QCompleter *completer = new QCompleter(words, lineEdit);
completer->setCaseSensitivity(Qt::CaseInsensitive);
lineEdit->setCompleter(completer);
1.05 QComboBox:可编辑组合框与模型视图集成
启用 setEditable(true) 并连接 editTextChanged() 信号,实现类似搜索引擎的“搜索并选择”功能。
将 QComboBox 与自定义的 QAbstractItemModel 子类结合,显示复杂数据(如带图标的条目)
应用场景:地址选择、标签输入、需要用户输入新选项的选择框
comboBox->setEditable(true);
connect(comboBox, &QComboBox::editTextChanged, this, [this](const QString &text) {
// 动态过滤下拉列表或触发搜索
updateSuggestions(text);
});
继承 QStyledItemDelegate 创建自定义委托,用于在表格单元格中嵌入复杂控件(如进度条、复选框、按钮)或实现特殊的绘制逻辑。
示例:创建一个 ProgressDelegate,在特定列显示 QProgressBar
void ProgressDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) {
int progress = index.model()->data(index).toInt();
QStyleOptionProgressBar progressBarOption;
progressBarOption.rect = option.rect;
progressBarOption.minimum = 0;
progressBarOption.maximum = 100;
progressBarOption.progress = progress;
progressBarOption.text = QString::number(progress) + "%";
progressBarOption.textVisible = true;
QApplication::style()->drawControl(QStyle::CE_ProgressBar, &progressBarOption, painter);
}
tableView->setItemDelegateForColumn(2, new ProgressDelegate(this)); // 第3列显示进度条
应用场景:任务管理器、下载列表、任何需要可视化数据状态的表格。
启用 setDragEnabled(true) 和 setAcceptDrops(true),并重写 dragEnterEvent, dragMoveEvent, dropEvent 等方法,
实现项目在列表内或不同列表间的拖拽排序和移动。
应用场景:播放列表排序、待办事项管理、文件管理器。
// 内部拖拽排序
listWidget->setDragDropMode(QAbstractItemView::InternalMove);
// 支持外部拖入
listWidget->setDragDropMode(QAbstractItemView::DragDrop);
10.8 QTextEdit / QTextEdit:富文本处理与语法高亮
使用 QSyntaxHighlighter 子类为 QTextEdit 添加语法高亮功能(如 Python、C++ 代码)。
利用 QTextDocument 和 QTextCursor 进行复杂的文本格式化和内容操作。
示例:创建一个 CppHighlighter 类,根据 C++ 关键字、注释、字符串等应用不同的字符格式 (QTextCharFormat)。
应用场景:代码编辑器、配置文件查看器、支持格式化的笔记应用。
10.9 QSlider:非线性刻度与双滑块
通过重写 value() 和 setValue() 或使用映射函数,实现对数或其他非线性刻度的滑块(例如音量控制常使用对数刻度)。
虽然 QSlider 本身不直接支持双滑块,但可以通过组合两个 QSlider 或自定义控件来模拟范围选择滑块。
应用场景:音量/亮度调节、时间轴范围选择、参数范围设定
使用 setTabsClosable(true) 允许用户关闭标签页,并连接 tabCloseRequested(int index) 信号。
通过 setCornerWidget() 在角落添加按钮(如“新建标签页”)。
更高级的做法是自定义 QTabBar 的样式或行为。
tabWidget->setTabsClosable(true);
connect(tabWidget, &QTabWidget::tabCloseRequested, this, [this](int index){
tabWidget->removeTab(index);
});
应用场景:多文档界面 (MDI)、浏览器、设置面板
利用 setAllowedAreas() 限制停靠区域,setFeatures() 控制是否可关闭、移动、浮动。使用 restoreGeometry() 和 saveGeometry() 在应用重启后恢复窗口布局。可以创建复杂的主窗口 (QMainWindow) 布局。
应用场景:IDE(如Qt Creator)、图像处理软件(如GIMP)、任何需要高度可定制工作区的应用。
自定义控件:继承 QWidget,重写 paintEvent() 使用 QPainter 绘制完全自定义的外观(如仪表盘、自定义图表)。
事件过滤器:使用 installEventFilter() 监听和处理其他对象的事件(如全局键盘快捷键、鼠标悬停检测),实现跨控件的交互逻辑。
// 在主窗口安装过滤器到目标控件
targetWidget->installEventFilter(this);
// 重写 eventFilter 方法
bool MainWindow::eventFilter(QObject *obj, QEvent *event) {
if (obj == targetWidget) {
if (event->type() == QEvent::HoverEnter) {
// 鼠标进入 targetWidget
return true; // 吃掉事件,阻止进一步传播
}
}
return QMainWindow::eventFilter(obj, event);
}
应用场景:创建独特的 UI 元素、实现全局快捷键、监控用户交互。
1.13 QLabel:动态富文本与交互式内容
使用 setTextFormat(Qt::RichText) 或 Qt::AutoText,
在 QLabel 中嵌入 HTML 标签(如 <a href=...>、<img src=...>),并连接 linkActivated() 信号实现点击链接跳转或触发动作。
结合 QTextDocument 可以实现更复杂的文本布局。
label->setTextFormat(Qt::RichText);
label->setText("点击 <a href='help'>这里</a> 查看帮助");
label->setTextInteractionFlags(Qt::TextBrowserInteraction);
connect(label, &QLabel::linkActivated, this, [](const QString &link){
if (link == "help") showHelpDialog();
});
应用场景:状态栏信息提示、关于对话框、带超链接的说明文本。
1.14 QProgressBar:异步任务集成与样式表美化
将 QProgressBar 与 QFuture / QtConcurrent 或工作线程 (QThread) 结合,通过信号槽实时更新进度。
使用 QSS (Qt Style Sheets) 创建完全自定义的视觉样式(渐变、动画背景、圆角等)。
// 在工作线程中
emit progressUpdated(int value)
connect(worker, &Worker::progressUpdated, progressBar, &QProgressBar::setValue);
// 使用 QSS 美化
progressBar->setStyleSheet(R"(
QProgressBar {
border: 2px solid grey;
border-radius: 5px;
text-align: center;
}
QProgressBar::chunk {
background-color: qlineargradient(x1:0, y1:0, x2:1, y2:0, stop:0 #3498db, stop:1 #2980b9);
width: 10px;
margin: 0.5px;
}
)");
应用场景:文件传输、数据处理、长时间运行任务的可视化反馈。
使用 setTristate(true) 启用三态复选框(勾选、未勾选、部分勾选),
常用于树形控件 (QTreeWidget) 中表示父子项的混合状态。利用 QButtonGroup 集中管理一组 QRadioButton 或 QCheckBox,简化信号处理和状态查询。
QButtonGroup *group = new QButtonGroup(this);
group->addButton(radio1, 1); // ID 为 1
group->addButton(radio2, 2); // ID 为 2
connect(group, QOverload<int>::of(&QButtonGroup::buttonClicked),
this, &MyClass::onRadioClicked); // 根据 ID 处理
应用场景:复杂表单、权限设置、树形结构的全选/反选。
1.16 QSpinBox / QDoubleSpinBox:前缀/后缀与步长控制
使用 setPrefix() 和 setSuffix() 添加单位(如 "€", "kg", "°C")。
重写 stepBy(int steps) 方法或使用 setSingleStep()/setPageStep() 实现非线性或上下文相关的步长变化。
spinBox->setPrefix("$");
spinBox->setSuffix(" per unit");
spinBox->setSpecialValueText("Free"); // 当值为最小值时显示特殊文本
应用场景:价格输入、带单位的数值设置、配置参数。
1.17 QTreeView:自定义模型与延迟加载
继承 QAbstractItemModel 创建高性能的自定义模型,支持大型数据集的延迟加载(Lazy Loading)。
当用户展开节点时,才从数据库或文件系统加载子项,极大提升响应速度。
正确实现 canFetchMore() 和 fetchMore() 方法。
应用场景:文件浏览器、大型数据树(如组织架构、产品分类)、数据库记录树形展示。
1.18 QGraphicsView:场景管理与高级图形项
高级用法:使用 QGraphicsScene 和 QGraphicsItem 构建复杂的 2D 图形场景。
创建自定义 QGraphicsItem 子类,实现 boundingRect(), paint(), mousePressEvent() 等,支持旋转、缩放、碰撞检测。
利用 QGraphicsView 的变换矩阵实现平移、缩放(如地图或图表)。
应用场景:图表绘制、流程图编辑器、游戏、矢量图形编辑。
1.19 QDialog:模态与非模态的灵活使用及结果处理
理解 exec()(模态)和 show()(非模态)的区别。
对于非模态对话框,使用 finished(int result) 信号来处理用户关闭后的逻辑。
使用 QDialogButtonBox 统一管理“确定”、“取消”等按钮,并连接其信号。
MyDialog *dialog = new MyDialog(this);
connect(dialog, &QDialog::finished, this, [dialog](int result){
if (result == QDialog::Accepted) {
// 处理用户点击“确定”
}
dialog->deleteLater(); // 安全删除
});
dialog->show();
应用场景:设置对话框、属性编辑器、向导(Wizard)。
1.20 QMainWindow:中心部件与多窗口集成
利用 setCentralWidget() 设置主窗口的中心部件。
结合 QMdiArea(多文档界面区域)实现类似 Word 或 Photoshop 的多文档界面。
使用 QMenuBar, QToolBar, QStatusBar 的 addAction() 和 insertAction() 精确控制菜单和工具栏布局。
应用场景:IDE、文档编辑器、专业级桌面应用。
将复杂的、可能超出屏幕的 QWidget 嵌入 QScrollArea。
关键点是调用 setWidgetResizable(true),使内部部件能随滚动区域大小自动调整。
对于包含大量项目的列表,考虑使用 QListView + QAbstractItemModel 而非在 QScrollArea 中堆放数百个 QWidget,以获得更好的性能。
应用场景:长表单、图片查看器、日志查看器。