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

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

技术教程gslnedu2025-05-12 12:17:114A+A-


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

点击这里复制本文地址 以上内容由朽木教程网整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!
qrcode

朽木教程网 © All Rights Reserved.  蜀ICP备2024111239号-8