MFC转QT - Qt界面开发 - 常用控件
ccwgpt 2025-06-30 15:00 12 浏览 0 评论
基础控件 (QPushButton, QLabel, QLineEdit等)
按钮控件族
Qt提供了丰富的按钮控件,比MFC的按钮控件更加细分和功能丰富。
QPushButton(标准按钮)
// 创建按钮
QPushButton *button = new QPushButton("点击我");
// 设置图标
button->setIcon(QIcon(":/icons/click.png"));
// 设置快捷键
button->setShortcut(QKeySequence("Ctrl+C"));
// 设置工具提示
button->setToolTip("这是一个按钮");
// 默认按钮(回车激活)
button->setDefault(true);
// 自动重复(按住不放时重复触发clicked信号)
button->setAutoRepeat(true);
button->setAutoRepeatDelay(500); // 首次触发前延迟(ms)
button->setAutoRepeatInterval(100); // 重复间隔(ms)
// 扁平风格按钮
button->setFlat(true);
// 菜单按钮
QMenu *menu = new QMenu();
menu->addAction("选项1");
menu->addAction("选项2");
button->setMenu(menu);
// 信号连接
connect(button, &QPushButton::clicked, this, &MyWidget::onButtonClicked);
QCheckBox(复选框)
// 创建复选框
QCheckBox *checkbox = new QCheckBox("启用特效");
// 设置初始状态
checkbox->setChecked(true);
// 三态复选框
checkbox->setTristate(true);
// 三种状态:Qt::Unchecked, Qt::PartiallyChecked, Qt::Checked
// 信号连接
connect(checkbox, &QCheckBox::stateChanged,
[](int state) { qDebug() << "状态:" << state; });
QRadioButton(单选按钮)
// 创建单选按钮组
QButtonGroup *group = new QButtonGroup();
QRadioButton *option1 = new QRadioButton("选项1");
QRadioButton *option2 = new QRadioButton("选项2");
QRadioButton *option3 = new QRadioButton("选项3");
// 添加到按钮组
group->addButton(option1, 1);
group->addButton(option2, 2);
group->addButton(option3, 3);
// 设置默认选中
option1->setChecked(true);
// 信号连接
connect(group, QOverload<int>::of(&QButtonGroup::buttonClicked),
[](int id) { qDebug() << "选择了ID:" << id; });
与MFC按钮控件对比
功能 | Qt | MFC |
按钮类型区分 | 独立的类 (QPushButton, QCheckBox等) | 统一的CButton + 样式 |
图标支持 | 内置支持,简单设置 | 需要自定义绘制或使用ImageList |
菜单按钮 | 内置支持 | 需要手动处理 |
按钮组 | QButtonGroup管理 | 通过变量和代码管理 |
样式定制 | 样式表简单定制 | 需要Owner Draw |
信号处理 | 多种信号(pressed/released/clicked) | 主要处理BN_CLICKED通知 |
文本显示与编辑控件
QLabel(标签)
QLabel比MFC的静态文本控件功能丰富得多:
// 创建标签
QLabel *label = new QLabel("这是一个<b>标签</b>", this);
// 富文本支持
label->setText("<h1>标题</h1><p>这是<font color='red'>彩色</font>文本</p>");
label->setTextFormat(Qt::RichText);
// 图像显示
label->setPixmap(QPixmap(":/images/logo.png"));
label->setScaledContents(true); // 缩放图像填充标签
// 超链接支持
label->setText("<a href='https://qt.io'>访问Qt官网</a>");
label->setOpenExternalLinks(true); // 点击自动打开浏览器
// 文本对齐
label->setAlignment(Qt::AlignCenter);
// 文本自动换行
label->setWordWrap(true);
// 文本缩进
label->setIndent(10);
// 边框
label->setFrameStyle(QFrame::Panel | QFrame::Sunken);
label->setLineWidth(2);
QLineEdit(单行文本框)
// 创建单行文本框
QLineEdit *lineEdit = new QLineEdit();
// 设置文本
lineEdit->setText("初始文本");
// 设置占位文本
lineEdit->setPlaceholderText("请输入姓名...");
// 最大长度限制
lineEdit->setMaxLength(50);
// 只读模式
lineEdit->setReadOnly(true);
// 输入掩码 (例如电话号码格式)
lineEdit->setInputMask("+99 999 999 9999");
// 输入验证器
QRegularExpressionValidator *validator =
new QRegularExpressionValidator(QRegularExpression("[A-Za-z0-9]+"));
lineEdit->setValidator(validator);
// 密码模式
lineEdit->setEchoMode(QLineEdit::Password);
// 其他模式: Normal, NoEcho, PasswordEchoOnEdit
// 清除按钮
lineEdit->setClearButtonEnabled(true);
// 信号连接
connect(lineEdit, &QLineEdit::textChanged,
[](const QString &text) { qDebug() << "文本变化:" << text; });
connect(lineEdit, &QLineEdit::returnPressed,
[]() { qDebug() << "按下回车"; });
QTextEdit(多行文本编辑器)
// 创建富文本编辑器
QTextEdit *textEdit = new QTextEdit();
// 设置文本(支持HTML)
textEdit->setHtml("<h1>标题</h1><p>段落内容</p>");
// 纯文本设置
textEdit->setPlainText("这是纯文本内容");
// 只读模式
textEdit->setReadOnly(true);
// 文本格式化
QTextDocument *doc = textEdit->document();
QTextCursor cursor(doc);
cursor.movePosition(QTextCursor::End);
QTextCharFormat format;
format.setFontWeight(QFont::Bold);
format.setForeground(Qt::red);
cursor.insertText("这是粗体红色文本", format);
// 设置字体
textEdit->setFont(QFont("Arial", 12));
// 自动换行模式
textEdit->setLineWrapMode(QTextEdit::WidgetWidth);
// 标签编辑器(用于显示HTML)
QTextBrowser *browser = new QTextBrowser();
browser->setSource(QUrl("qrc:/content/help.html"));
browser->setOpenExternalLinks(true);
与MFC文本控件对比
功能 | Qt | MFC |
富文本支持 | 原生支持HTML格式化 | 需使用RichEdit控件 |
验证功能 | 内置验证器框架 | 需自行实现 |
占位文本 | 内置支持 | 需自行绘制 |
超链接 | 原生支持 | 需额外处理 |
撤销/重做 | 内置支持 | 需额外实现 |
国际化支持 | Unicode原生支持 | 需额外配置 |
容器控件 (QTabWidget, QGroupBox, QScrollArea等)
选项卡容器 (QTabWidget)
// 创建选项卡窗口
QTabWidget *tabWidget = new QTabWidget();
// 添加选项卡
QWidget *tab1 = new QWidget();
QWidget *tab2 = new QWidget();
QWidget *tab3 = new QWidget();
// 设置每个选项卡的内容(通常是布局)
QVBoxLayout *layout1 = new QVBoxLayout(tab1);
layout1->addWidget(new QPushButton("Tab 1 按钮"));
// 添加选项卡到TabWidget
tabWidget->addTab(tab1, "选项卡1");
tabWidget->addTab(tab2, QIcon(":/icons/tab2.png"), "选项卡2");
tabWidget->addTab(tab3, "选项卡3");
// 设置默认选中的选项卡
tabWidget->setCurrentIndex(0);
// 选项卡位置
tabWidget->setTabPosition(QTabWidget::North); // 北、南、东、西
// 选项卡形状
tabWidget->setTabShape(QTabWidget::Rounded); // 圆角或方角
// 关闭按钮
tabWidget->setTabsClosable(true);
// 可移动选项卡
tabWidget->setMovable(true);
// 信号连接
connect(tabWidget, &QTabWidget::currentChanged,
[](int index) { qDebug() << "当前选项卡:" << index; });
connect(tabWidget, &QTabWidget::tabCloseRequested,
[tabWidget](int index) { tabWidget->removeTab(index); });
分组框 (QGroupBox)
// 创建分组框
QGroupBox *groupBox = new QGroupBox("设置选项");
// 创建组内布局
QVBoxLayout *groupLayout = new QVBoxLayout(groupBox);
groupLayout->addWidget(new QCheckBox("选项 1"));
groupLayout->addWidget(new QCheckBox("选项 2"));
groupLayout->addWidget(new QCheckBox("选项 3"));
// 可选中的分组框
QGroupBox *checkableGroup = new QGroupBox("高级选项");
checkableGroup->setCheckable(true);
checkableGroup->setChecked(false); // 默认未选中,内部控件被禁用
// 分组框对齐
groupBox->setAlignment(Qt::AlignHCenter);
// 扁平样式
groupBox->setFlat(true);
滚动区域 (QScrollArea)
// 创建滚动区域
QScrollArea *scrollArea = new QScrollArea();
// 创建内容控件(可能比滚动区域大)
QWidget *content = new QWidget();
content->setMinimumSize(1000, 1000); // 设置一个大尺寸
// 设置内容控件的布局
QGridLayout *contentLayout = new QGridLayout(content);
for (int i = 0; i < 20; i++) {
for (int j = 0; j < 10; j++) {
contentLayout->addWidget(
new QPushButton(QString("按钮 %1,%2").arg(i).arg(j)), i, j);
}
}
// 将内容设置到滚动区域
scrollArea->setWidget(content);
// 滚动条策略
scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
// 调整视图
scrollArea->setWidgetResizable(true); // 自动调整内容大小
堆叠窗口部件 (QStackedWidget)
// 创建堆叠窗口部件
QStackedWidget *stackedWidget = new QStackedWidget();
// 添加多个页面
QWidget *page1 = new QWidget();
QWidget *page2 = new QWidget();
QWidget *page3 = new QWidget();
// 设置每个页面的内容
QVBoxLayout *layout1 = new QVBoxLayout(page1);
layout1->addWidget(new QLabel("这是第一页"));
// ...设置其他页面
// 将页面添加到堆叠窗口
stackedWidget->addWidget(page1);
stackedWidget->addWidget(page2);
stackedWidget->addWidget(page3);
// 设置当前显示的页面
stackedWidget->setCurrentIndex(0);
// 通常与其他控件组合使用来切换页面
QComboBox *pageCombo = new QComboBox();
pageCombo->addItems({"页面1", "页面2", "页面3"});
connect(pageCombo, QOverload<int>::of(&QComboBox::currentIndexChanged),
stackedWidget, &QStackedWidget::setCurrentIndex);
分割器 (QSplitter)
// 创建水平分割器
QSplitter *splitter = new QSplitter(Qt::Horizontal);
// 添加窗口部件
QListWidget *list = new QListWidget();
list->addItems({"项目1", "项目2", "项目3"});
splitter->addWidget(list);
QTextEdit *editor = new QTextEdit();
splitter->addWidget(editor);
// 设置初始大小
splitter->setSizes({100, 300});
// 设置拉伸因子
splitter->setStretchFactor(0, 1);
splitter->setStretchFactor(1, 3);
// 处理大小变化
splitter->setOpaqueResize(true); // 调整时实时更新
splitter->setChildrenCollapsible(false); // 防止折叠子窗口
// 获取分割器位置
connect(splitter, &QSplitter::splitterMoved,
[](int pos, int index) { qDebug() << "移动位置:" << pos << "索引:" << index; });
与MFC容器控件对比
功能 | Qt | MFC |
选项卡 | QTabWidget | CTabCtrl |
分组框 | QGroupBox | 使用Group框或静态边框 |
滚动区域 | QScrollArea | 需自行处理滚动条 |
分割窗口 | QSplitter | CSplitterWnd |
窗口堆栈 | QStackedWidget | 需使用CPropertySheet |
可停靠窗口 | QDockWidget | CDockablePane |
布局嵌套 | 原生支持 | 需复杂设计 |
数据控件 (QListView, QTableView, QTreeView等)
Qt提供了强大的模型/视图架构,这是Qt相比MFC最显著的优势之一。这种设计将数据与显示分离,极大提高了代码复用性和灵活性。
模型/视图架构概述
基本组件:
- 模型(Model):负责数据存储和访问
- 视图(View):负责数据显示
- 代理(Delegate):负责数据编辑和自定义显示
优势:
- 同一数据可以多种方式显示
- 数据变化自动更新所有视图
- 自定义显示和编辑行为更简单
- 内置排序和过滤功能
列表控件 (QListView 和 QListWidget)
Qt提供了两套API:
- 模型/视图分离: QListView + QAbstractItemModel
- 简化版: QListWidget (自带内置模型)
使用QListWidget(简单场景)
// 创建列表控件
QListWidget *listWidget = new QListWidget();
// 添加项目
listWidget->addItem("项目1");
listWidget->addItem("项目2");
// 带图标的项目
QListWidgetItem *item = new QListWidgetItem(QIcon(":/icons/item.png"), "带图标项目");
listWidget->addItem(item);
// 设置项目属性
item->setFlags(item->flags() | Qt::ItemIsEditable); // 可编辑
item->setBackground(Qt::lightGray); // 背景色
item->setForeground(Qt::blue); // 文字颜色
// 设置选择模式
listWidget->setSelectionMode(QAbstractItemView::MultiSelection);
// 设置视图模式
listWidget->setViewMode(QListView::IconMode); // 图标模式
listWidget->setFlow(QListView::LeftToRight); // 从左到右排列
listWidget->setWrapping(true); // 允许换行
// 可拖拽项目
listWidget->setDragEnabled(true);
listWidget->setAcceptDrops(true);
listWidget->setDropIndicatorShown(true);
// 信号连接
connect(listWidget, &QListWidget::itemClicked,
[](QListWidgetItem *item) { qDebug() << "点击:" << item->text(); });
connect(listWidget, &QListWidget::itemChanged,
[](QListWidgetItem *item) { qDebug() << "变化:" << item->text(); });
使用QListView和模型(复杂场景)
// 创建模型
QStringListModel *model = new QStringListModel();
model->setStringList({"数据1", "数据2", "数据3"});
// 创建视图
QListView *listView = new QListView();
listView->setModel(model);
// 设置选择和编辑模式
listView->setSelectionMode(QAbstractItemView::ExtendedSelection);
listView->setEditTriggers(QAbstractItemView::DoubleClicked);
// 创建自定义代理
class ColorDelegate : public QStyledItemDelegate {
public:
void paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const override {
if (index.row() % 2 == 0) {
painter->fillRect(option.rect, QColor(240, 240, 255));
}
QStyledItemDelegate::paint(painter, option, index);
}
};
// 设置代理
listView->setItemDelegate(new ColorDelegate());
// 使用模型操作数据
model->insertRows(0, 1);
model->setData(model->index(0), "新插入的数据");
表格控件 (QTableView 和 QTableWidget)
使用QTableWidget(简单场景)
// 创建表格控件
QTableWidget *tableWidget = new QTableWidget(5, 3); // 5行3列
// 设置表头
tableWidget->setHorizontalHeaderLabels({"姓名", "年龄", "职业"});
// 添加数据
tableWidget->setItem(0, 0, new QTableWidgetItem("张三"));
tableWidget->setItem(0, 1, new QTableWidgetItem("28"));
tableWidget->setItem(0, 2, new QTableWidgetItem("工程师"));
// 合并单元格
tableWidget->setSpan(1, 0, 2, 2); // 从(1,0)开始,合并2行2列
// 调整列宽和行高
tableWidget->setColumnWidth(0, 150);
tableWidget->setRowHeight(0, 40);
// 自动调整列宽
tableWidget->resizeColumnsToContents();
// 设置选择行为
tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
// 隔行变色
tableWidget->setAlternatingRowColors(true);
// 设置排序
tableWidget->setSortingEnabled(true);
树形控件 (QTreeView 和 QTreeWidget)
使用QTreeWidget(简单场景)
// 创建树形控件
QTreeWidget *treeWidget = new QTreeWidget();
// 设置列头
treeWidget->setHeaderLabels({"名称", "描述"});
// 创建顶级项目
QTreeWidgetItem *topItem = new QTreeWidgetItem(treeWidget);
topItem->setText(0, "项目一");
topItem->setText(1, "顶级项目");
topItem->setIcon(0, QIcon(":/icons/folder.png"));
// 添加子项目
QTreeWidgetItem *childItem1 = new QTreeWidgetItem(topItem);
childItem1->setText(0, "子项目1");
childItem1->setText(1, "第一个子项目");
QTreeWidgetItem *childItem2 = new QTreeWidgetItem(topItem);
childItem2->setText(0, "子项目2");
childItem2->setText(1, "第二个子项目");
// 添加孙子项目
QTreeWidgetItem *grandChildItem = new QTreeWidgetItem(childItem1);
grandChildItem->setText(0, "孙项目");
grandChildItem->setText(1, "子项目的子项目");
// 展开所有节点
treeWidget->expandAll();
// 响应项目点击
connect(treeWidget, &QTreeWidget::itemClicked,
[](QTreeWidgetItem *item, int column) {
qDebug() << "点击:" << item->text(0) << "列:" << column;
});
对应MFC控件的Qt替代品
MFC开发者在迁移到Qt时,可以使用以下对照表找到相应的替代控件:
MFC控件 | Qt替代控件 | 额外优势 |
CButton | QPushButton | 更统一的事件处理,更易于样式自定义 |
CButton (Check) | QCheckBox | 支持三态,直接支持状态查询 |
CButton (Radio) | QRadioButton | 无需手动互斥处理 |
CEdit | QLineEdit | 内置验证器,更多事件信号 |
CEdit (Multiline) | QTextEdit/QPlainTextEdit | 富文本支持,更好的编辑功能 |
CRichEditCtrl | QTextEdit | 更简单的格式控制 |
CStatic | QLabel | 富文本和HTML支持 |
CListBox | QListWidget | 项目可含多种格式数据 |
CComboBox | QComboBox | 内置模型支持,可自定义显示 |
CListCtrl | QTableWidget/QListView | 与模型分离,更易扩展 |
CTreeCtrl | QTreeWidget/QTreeView | 易于管理复杂数据结构 |
CTabCtrl | QTabWidget | 更方便的选项卡管理 |
CProgressCtrl | QProgressBar | 支持文字覆盖,样式更丰富 |
CSliderCtrl | QSlider | 更易于自定义外观 |
CSpinButtonCtrl | QSpinBox | 更完整的范围控制 |
CScrollBar | QScrollBar | 更一致的事件处理 |
CDialog | QDialog | 更灵活的布局系统 |
CPropertySheet | QTabWidget | 更易于定制 |
CToolBar | QToolBar | 支持拖放和自定义,样式更丰富 |
CStatusBar | QStatusBar | 简化的API |
CReBar | QToolBar+样式 | 无需复杂设置 |
CHotKeyCtrl | QKeySequenceEdit | 更直观的快捷键编辑 |
CDateTimeCtrl | QDateTimeEdit | 更丰富的格式选项 |
CMonthCalCtrl | QCalendarWidget | 更易于自定义 |
CImageList | QIcon,QPixmap | 无需单独管理图像集 |
这些Qt控件不仅提供了与MFC相同的功能,还通过统一的API、信号槽机制和现代化的外观,显著提升了开发效率和用户体验。
相关推荐
- 一个基于.Net Core遵循Clean Architecture原则开源架构
-
今天给大家推荐一个遵循CleanArchitecture原则开源架构。项目简介这是基于Asp.netCore6开发的,遵循CleanArchitecture原则,可以高效、快速地构建基于Ra...
- AI写代码翻车无数次,我发现只要提前做好这3步,bug立减80%
-
写十万行全是bug之后终于找到方法了开发"提示词管理助手"新版本那会儿,我差点被bug整崩溃。刚开始两周,全靠AI改代码架构,结果十万行程序漏洞百出。本来以为AI说没问题就稳了,结果...
- OneCode低代码平台的事件驱动设计:架构解析与实践
-
引言:低代码平台的事件驱动范式在现代软件开发中,事件驱动架构(EDA)已成为构建灵活、松耦合系统的核心范式。OneCode低代码平台通过创新性的注解驱动设计,将事件驱动理念深度融入平台架构,实现了业务...
- 国内大厂AI插件评测:根据UI图生成Vue前端代码
-
在IDEA中安装大厂的AI插件,打开ruoyi增强项目:yudao-ui-admin-vue31.CodeBuddy插件登录腾讯的CodeBuddy后,大模型选择deepseek-v3,输入提示语:...
- AI+低代码技术揭秘(二):核心架构
-
本文档介绍了为VTJ低代码平台提供支持的基本架构组件,包括Engine编排层、Provider服务系统、数据模型和代码生成管道。有关UI组件库和widget系统的信息,请参阅UI...
- GitDiagram用AI把代码库变成可视化架构图
-
这是一个名为gitdiagram的开源工具,可将GitHub仓库实时转换为交互式架构图,帮助开发者快速理解代码结构。核心功能一键可视化:替换GitHubURL中的"hub...
- 30天自制操作系统:第六天:代码架构整理与中断处理
-
1.拆开bootpack.c文件。根据设计模式将对应的功能封装成独立的文件。2.初始化pic:pic(可编程中断控制器):在设计上,cpu单独只能处理一个中断。而pic是将8个中断信号集合成一个中断...
- AI写代码越帮越忙?2025年研究揭露惊人真相
-
近年来,AI工具如雨后春笋般涌现,许多人开始幻想程序员的未来就是“对着AI说几句话”,就能轻松写出完美的代码。然而,2025年的一项最新研究却颠覆了这一期待,揭示了一个令人意外的结果。研究邀请了16位...
- 一键理解开源项目:两个自动生成GitHub代码架构图与说明书工具
-
一、GitDiagram可以一键生成github代码仓库的架构图如果想要可视化github开源项目:https://github.com/luler/reflex_ai_fast,也可以直接把域名替换...
- 5分钟掌握 c# 网络通讯架构及代码示例
-
以下是C#网络通讯架构的核心要点及代码示例,按协议类型分类整理:一、TCP协议(可靠连接)1.同步通信//服务器端usingSystem.Net.Sockets;usingTcpListene...
- 从复杂到优雅:用建造者和责任链重塑代码架构
-
引用设计模式是软件开发中的重要工具,它为解决常见问题提供了标准化的解决方案,提高了代码的可维护性和可扩展性,提升了开发效率,促进了团队协作,提高了软件质量,并帮助开发者更好地适应需求变化。通过学习和应...
- 低代码开发当道,我还需要学习LangChain这些框架吗?| IT杂谈
-
专注LLM深度应用,关注我不迷路前两天有位兄弟问了个问题:当然我很能理解这位朋友的担忧:期望效率最大化,时间用在刀刃上,“不要重新发明轮子”嘛。铺天盖地的AI信息轰炸与概念炒作,很容易让人浮躁与迷茫。...
- 框架设计并不是简单粗暴地写代码,而是要先弄清逻辑
-
3.框架设计3.框架设计本节我们要开发一个UI框架,底层以白鹭引擎为例。框架设计的第一步并不是直接撸代码,而是先想清楚设计思想,抽象。一个一个的UI窗口是独立的吗?不是的,...
- 大佬用 Avalonia 框架开发的 C# 代码 IDE
-
AvalonStudioAvalonStudio是一个开源的跨平台的开发编辑器(IDE),AvalonStudio的目标是成为一个功能齐全,并且可以让开发者快速使用的IDE,提高开发的生产力。A...
- 轻量级框架Lagent 仅需20行代码即可构建自己的智能代理
-
站长之家(ChinaZ.com)8月30日消息:Lagent是一个专注于基于LLM模型的代理开发的轻量级框架。它的设计旨在简化和提高这种模型下代理的开发效率。LLM模型是一种强大的工具,可以...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- 框架图 (58)
- flask框架 (53)
- quartz框架 (51)
- abp框架 (47)
- springmvc框架 (49)
- 分布式事务框架 (65)
- scrapy框架 (56)
- shiro框架 (61)
- 定时任务框架 (56)
- java日志框架 (61)
- mfc框架 (52)
- abb框架断路器 (48)
- beego框架 (52)
- java框架spring (58)
- grpc框架 (65)
- tornado框架 (48)
- 前端框架bootstrap (54)
- orm框架有哪些 (51)
- 知识框架图 (52)
- ppt框架 (55)
- 框架图模板 (59)
- 内联框架 (52)
- cad怎么画框架 (58)
- ssm框架实现登录注册 (49)
- oracle字符串长度 (48)