面试题:QTableView和QTableWidget的异同

目录

1.QTableView简介

2.QTableWidget简介

3.QTableView和QTableWidget不同

4.总结


1.QTableView简介

        QTableView是一个基于模型-视图架构的表格控件,用于展示表格形式的数据。同样需要关联一个QAbstractTableModel或其子类(如QStandardItemModel)来提供数据。这意味着数据存储在模型中,而 QTableView 只负责显示和编辑这些数据。它将数据显示与数据存储分离,提供了强大的灵活性和可扩展性,适合处理各种复杂的表格场景。

        它在QT中的类继承关系如下图所示:

它的特点有:

1)高性能:采用懒加载机制,仅渲染可见区域的单元格,适合处理大量数据(如数万行以上)。

2)高度可定制化

  • 支持自定义单元格渲染(通过 QAbstractItemDelegate)。
  • 可定制行高、列宽、排序、筛选等功能。
  • 通过样式表(CSS)修改整体外观。

可自定义单元格的渲染和编辑方式,例如显示进度条、下拉框等:

class ProgressDelegate : public QItemDelegate {
public:
    void paint(QPainter *painter, const QStyleOptionViewItem &option,
               const QModelIndex &index) const override {
        // 绘制进度条
        int progress = index.data().toInt();
        QStyleOptionProgressBar progressBar;
        // ... 设置进度条参数
        QApplication::style()->drawControl(QStyle::CE_ProgressBar, &progressBar, painter);
    }
};

// 使用代理
tableView.setItemDelegateForColumn(2, new ProgressDelegate);

排序与筛选

// 启用排序
tableView.setSortingEnabled(true);

// 使用筛选器(如只显示年龄>20的行)
QSortFilterProxyModel proxyModel;
proxyModel.setSourceModel(&originalModel);
proxyModel.setFilterRegExp("^[2-9][0-9]$");
proxyModel.setFilterKeyColumn(1);  // 筛选第2列(年龄)
tableView.setModel(&proxyModel);

3)丰富的交互支持:支持单元格选择、编辑、右键菜单、拖放等操作,并提供相应信号(如 clickeddoubleClicked)。

4)数据库集成:通过 QSqlTableModel 直接连接数据库表:

#include <QSqlTableModel>
QSqlTableModel model;
model.setTable("employees");
model.select();  // 查询数据
tableView.setModel(&model);

2.QTableWidget简介

        QTableWidget继承于QTableView,它是一个结合了模型和视图的控件,它内置了一个简单的表格模型。这意味着你不需要单独管理模型,可以直接通过QTableWidget的方法来操作数据。与 QTableView 相比,QTableWidget 的 API 更简单直接,适合快速开发小规模、静态数据的表格应用。

        它的特点有:

1)集成数据存储:无需额外的数据模型(如 QStandardItemModel),可直接通过 setItem()setCellWidget() 操作单元格数据。

2)简单易用:提供直观的 API,适合初学者快速实现表格功能,例如:

QTableWidget table(4, 2);  // 创建4行2列的表格
table.setItem(0, 0, new QTableWidgetItem("张三"));

3)基本功能齐全: 支持单元格选择、编辑、排序、行 / 列隐藏等常见操作。

4)视觉定制:可通过样式表(CSS)修改外观,或通过 setCellWidget() 添加自定义控件(如按钮、下拉框)。

3.QTableView和QTableWidget不同

特性QTableViewQTableWidget
数据模型基于 MVC(模型 - 视图 - 控制器)架构,需配合QAbstractItemModel子类(如QStandardItemModelQSqlTableModel)使用。数据与视图分离,支持大型数据集。内置数据存储(直接操作单元格),无需额外模型。适合小规模静态数据。
使用复杂度需手动创建和配置模型,学习成本较高,但灵活性极强。开箱即用,API 简单直接,适合快速开发。
性能处理大量数据时性能更佳(如数万行以上),仅渲染可见区域。数据量较大时性能下降,因所有单元格预分配。
扩展性可自定义模型实现高级功能(如异步加载、远程数据)。扩展困难,需继承并重写大量方法。
单元格操作通过模型间接操作数据(如model.setData(index, value))。直接通过setItem()setCellWidget()操作单元格。

典型应用场景

  • QTableView

    • 数据量庞大(如数据库查询结果)。
    • 需要与其他组件共享数据模型。
    • 需要自定义数据展示逻辑(如图标、富文本、进度条)。
  • QTableWidget

    • 数据量较小且固定。
    • 快速原型开发或简单表格需求。
    • 直接操作单元格内容(如 Excel 式编辑)。

示例代码:QTableView + QStandardItemModel(C++)

#include <QApplication>
#include <QTableView>
#include <QStandardItemModel>

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    
    // 创建模型
    QStandardItemModel model(4, 2);  // 4行2列
    model.setHorizontalHeaderLabels({"姓名", "年龄"});
    
    // 设置数据
    model.setItem(0, 0, new QStandardItem("张三"));
    model.setItem(0, 1, new QStandardItem("25"));
    
    // 创建视图并设置模型
    QTableView tableView;
    tableView.setModel(&model);
    tableView.show();
    
    return a.exec();
}

QTableWidget(C++)

#include <QApplication>
#include <QTableWidget>
#include <QTableWidgetItem>

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    
    // 创建表格,设置行列数
    QTableWidget tableWidget(4, 2);
    tableWidget.setHorizontalHeaderLabels({"姓名", "年龄"});
    
    // 设置数据
    tableWidget.setItem(0, 0, new QTableWidgetItem("张三"));
    tableWidget.setItem(0, 1, new QTableWidgetItem("25"));
    
    tableWidget.show();
    return a.exec();
}

4.总结

  • 选 QTableView:当需要处理复杂数据逻辑或大量数据时,它提供更好的性能和可维护性。
  • 选 QTableWidget:当需求简单且数据量较小时,它能快速实现功能。

        实际开发中,建议优先使用QTableView,因为 MVC 架构更符合软件工程原则,便于代码扩展和维护。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值