当前位置:首页 > 文章中心 > 正文内容

MFC转QT - Qt界面开发 - 常用控件


基础控件 (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):负责数据编辑和自定义显示

优势

  1. 同一数据可以多种方式显示
  2. 数据变化自动更新所有视图
  3. 自定义显示和编辑行为更简单
  4. 内置排序和过滤功能

列表控件 (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、信号槽机制和现代化的外观,显著提升了开发效率和用户体验。

扫描二维码推送至手机访问。

版权声明:本文由第六芝士网发布,如需转载请注明出处。

本文链接:http://www.dgx666.com/post/2072.html

分享给朋友:

“MFC转QT - Qt界面开发 - 常用控件” 的相关文章

《魔兽争霸III》官方对战平台1.2.0版本更新公告

《魔兽争霸III》官方对战平台1.2.0版本更新完毕,备受期待的RPG游戏大厅也随之正式上线。以下是本次更新的具体内容:房间列表入口调整:房间列表的入口被调整到标签页的右侧,与游戏大厅互相独立开放RPG游戏大厅,大厅新增功能如下:新增地图分类及搜索功能:玩家可以在游戏大厅内通过地图类型或地图名快速搜...

如何在圆柱与圆锥面上绘制文字,关键在于SolidWorks包覆命令

今天给大家分享一个小技巧,是关于包覆命令在圆柱和圆锥面上的如何使用进行文字内容绘制,以及需要注意的事项。1. 首先我们打开 Solidworks2018软件,点击拉伸凸台,选择上视基准面,绘制一个圆,如图所示:2. 我们绘制好草图之后,选择完成,点击拉伸,如图所示:3.完成拉伸后,我们选择草图里面的...

win11怎么将便签固定在桌面?

用电脑办公的人士或多或少会用到自带的便签工具,在使用便签工具的时候,发现便签无法固定在桌面,每次使用时只能重复操作打开非常浪费时间,要是能将便签固定在桌面就可以快速记录备忘内容,也能节省不少时间,现在有很多第三方的便签软件能够固定在电脑桌面上,那么win11电脑可以用哪款便签软件?固定在桌面使用。小...

桌面日历备忘录添加内容的步骤

桌面日历备忘录添加内容的步骤根据实际需求和习惯,适当地将一些常用工具放在桌面上,可以提高工作效率。比如记录类的日历备忘录,我们将其放在电脑桌面上更加直观和清晰,方便地对它们进行管理;可以快速访问添加内容,省去了搜索和打开的时间,提高了效率。把日历备忘录放在桌面之后,大大节省了时间。如果是像敬业签那就...

msvcr100.dll丢失原因及解决办法

丢失原因:msvcr100.dll是微软的一个文件。它是VC++2010运行库的一个动态链接库。一些程序的安装和运行需要该动态链接库文件的支持,比如声卡等等。很多人在安装一些程序的时候会显示msvcr100.dll丢失。解决办法,亲测有效,而且可以用此中方法解决同类型问题。第一 电脑丢失MSVCR1...

FIFA13跳出、闪退、卡顿等运行问题及解决方法汇总

觉得掉帧可以用D3DOverrider为FIFA13.exe(强制)开启三重缓冲和垂直同步,并也在显卡驱动控制面板中(强制)开启抗锯齿请使用最新版显卡驱动和Direct XAPPCRASH”错误请将fifaconfig.exe 和 FIFA13.exe的属性设为在Win XP SP3兼容模式下运行。...