MFC转QT - Qt界面开发 - 常用控件
zhezhongyun 2025-05-22 14:56 5 浏览
基础控件 (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、信号槽机制和现代化的外观,显著提升了开发效率和用户体验。
相关推荐
- 办公小技巧:杜绝意外 让字体永不丢失
-
当精心编辑的文档,在其它电脑上打开时,最常见的问题就是页数增加了,表格被撑破了,有些严重的甚至会出现乱码……为什么会这样呢?究其根源都是因为缺少相应的字体。本文介绍各类文档中(包括Word文档、PPT...
- 网站速度优化:从10秒到2秒的极致性能提升方案
-
核心内容:性能诊断工具:PageSpeedInsights与Lighthouse的评分差异解读。WebPageTest多地区、多设备性能对比。前端优化:CSS/JS压缩与合并的自动化方案(如Webp...
- 如何在WordPress中删除谷歌字体(2种简单方法)
-
许多WordPress主题都会用Google字体,然而,Google字体并不存储在网站本地,它是一个第三方资源,这会影响网站的加载速度,让网站变慢,尤其当你的网站面向的是国内用户时,更需要禁用Goog...
- 2019年免费可商用字体大全(附打包下载)
-
私信“字体”可免费获得。附送一个几十G的,有商业授权要求的字体包!不说那么复杂了,简单讲,可能你下载的大多数字体都是收费的。比如方正、文鼎、汉仪等的90%以上需要商业授权,甚至个人授权。这儿的授权,指...
- 开源免费、美观实用的后台管理系统模版,简单轻量、开箱即用!
-
项目介绍ArtDesignPro是一款开源免费(基于MITlicense开源协议)、美观实用的后台管理系统模版,专注于用户体验和快速开发的开源后台管理解决方案。基于ElementPlus设计...
- 【推荐】一款开源免费、美观实用的后台管理系统模版
-
如果您对源码&技术感兴趣,请点赞+收藏+转发+关注,大家的支持是我分享最大的动力!!!项目介绍ArtDesignPro是一款开源免费(基于MITlicense开源协议)、美观实用的后台管理系统模...
- 想要字体图标设计师却给了SVG?没关系,自己转
-
本文为Varlet组件库源码主题阅读系列第三篇,读完本篇,你可以了解到如何将svg图标转换成字体图标文件,以及如何设计一个简洁的Vue图标组件。Varlet提供了一些常用的图标,图标都来自Mater...
- 零基础教你学前端——66、CSS谷歌字体和Icon图标
-
我们学习CSS谷歌字体和CSSIcon图标。我们在应用font-family属性声明样式字体时,除了使用HTML中的标准字体外,还可以使用谷歌字体。谷歌字体是免费使用的,并且有1000多种字体...
- 必须掌握的前端开发基础知识,什么是字体图标?
-
必须掌握的前端开发基础知识,什么是字体图标?显示隐藏元素display显示隐藏none隐藏block显示隐藏后不再占有原来的位置visibility隐藏元素后,继续占有原来的位置visible元...
- 让你的网站速度提升10倍!(四):压缩~~~
-
在前面的内容中讲了如何降低页面大小(给页面瘦身),重点讲的是如何优化图片,而没有讲文本内容如何优化,这是因为与其辛苦的优化文本还不如使用我们的秘密武器:Gzip压缩!如果你还不清楚Gzip是什么,看这...
- MFC转QT - Qt界面开发 - 常用控件
-
基础控件(QPushButton,QLabel,QLineEdit等)按钮控件族Qt提供了丰富的按钮控件,比MFC的按钮控件更加细分和功能丰富。QPushButton(标准按钮)//创建按钮...
- 使用CSS实现苹果官网文字渐入效果
-
效果分析文字是从左到有慢慢呈现出来,不是整体消失和出现,那么肯定不能使用透明度。我们可以想到渐变文字,然后通过改变背景的位置来控制文字的显示与隐藏。渐变文字渐变文字该如何实现呢?这是实现这个效果的关键...
- HarmonyOS NEXT - ArkUI: Text组件
-
Text组件用于在界面上展示一段文本信息,可以包含子组件Span。文本样式包含文本元素的组件,例如Text、Span、Button、TextInput等,都可以使用文本样式。文本样式的属性如下表:.f...
- 计算机网络的 166 个核心概念,你知道吗?
-
上回我整理了一下计算机网络中所有的关键概念,很多小伙伴觉得很有帮助,但是有一个需要优化的点就是这些概念不知道出自哪里,所以理解起来像是在云里穿梭,一会儿在聊应用层的概念,一会儿又跑到网络层协议了。针对...
- 软网推荐:请个多功能纯文本管理助手
-
纯文本不单是指常用的语言文字,还包括各种类型的程序代码、编码等。作为常用的纯文本处理工具,“记事本”显得力不从心。我们可用一款免费软件AlternateTextbrowser,随心所欲地管理各种类型...
- 一周热门
- 最近发表
- 标签列表
-
- HTML 教程 (33)
- HTML 简介 (35)
- HTML 实例/测验 (32)
- HTML 测验 (32)
- HTML 参考手册 (28)
- JavaScript 和 HTML DOM 参考手册 (32)
- HTML 拓展阅读 (30)
- HTML常用标签 (29)
- HTML文本框样式 (31)
- HTML滚动条样式 (34)
- HTML5 浏览器支持 (33)
- HTML5 新元素 (33)
- HTML5 WebSocket (30)
- HTML5 代码规范 (32)
- HTML5 标签 (717)
- HTML5 标签 (已废弃) (75)
- HTML5电子书 (32)
- HTML5开发工具 (34)
- HTML5小游戏源码 (34)
- HTML5模板下载 (30)
- HTTP 状态消息 (33)
- HTTP 方法:GET 对比 POST (33)
- 键盘快捷键 (35)
- 标签 (226)
- HTML button formtarget 属性 (30)