欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 美景 > 【Qt笔记】QTableView控件详解

【Qt笔记】QTableView控件详解

2024/10/24 3:24:38 来源:https://blog.csdn.net/qq_52924376/article/details/141823346  浏览:    关键词:【Qt笔记】QTableView控件详解

 

目录

引言 

一、定义与架构

二、主要功能与特点

2.1 显示表格数据

2.2 编辑表格数据

2.3 自定义外观和交互

2.4 数据排序和过滤

2.5 支持拖放操作

2.6 自适应大小

2.7 上下文菜单

2.8 信号与槽

三、常用属性设置

3.1 设置模型

3.2 设置选择模型

3.3 隐藏垂直标题

3.4 设置图标大小

3.5 选择模式

3.6 选择行为

3.7 调整列宽

3.8 设置行高

3.9 交替颜色绘制背景

3.10 自动排序功能

四、应用场景

五、代码示例

5.1 自定义模型(MyTableModel) 

5.2 主窗口和QTableView

5.3 解析

5.4 实现效果 

结语


引言 

QTableView是Qt框架中非常重要的一个控件,专门用于展示和编辑二维表格数据。 

一、定义与架构

  • 定义:QTableView是一个基于模型的视图,用于显示和编辑由QAbstractItemModel派生的模型中的数据。
  • 模型-视图架构:QTableView不直接存储数据,而是通过与数据模型(如QStandardItemModel)的交互来展示和编辑数据。这种架构分离了数据的处理和展示,提高了代码的模块化和可维护性。

二、主要功能与特点

2.1 显示表格数据

主要用于显示二维表格形式的数据,其中数据可以来自文件、数据库查询结果或其他来源。

#include <QApplication>  
#include <QTableView>  
#include <QStandardItemModel>  int main(int argc, char *argv[]) {  QApplication app(argc, argv);  // 创建模型  QStandardItemModel *model = new QStandardItemModel(4, 2); // 4行2列  model->setHeaderData(0, Qt::Horizontal, "姓名");  model->setHeaderData(1, Qt::Horizontal, "年龄");  // 填充数据  for (int row = 0; row < 4; ++row) {  for (int column = 0; column < 2; ++column) {  QStandardItem *item = new QStandardItem(QString("数据 %1,%2").arg(row).arg(column));  model->setItem(row, column, item);  }  }  // 创建视图  QTableView *tableView = new QTableView;  tableView->setModel(model);  tableView->show();  return app.exec();  
}

2.2 编辑表格数据

提供了对表格数据的编辑功能,用户可以直接在表格中进行数据的修改和输入。 编辑功能通常不需要额外的代码,因为QTableView和QStandardItemModel默认支持编辑。

// 与上面的示例相同,因为编辑是默认启用的。  
// 如果需要限制编辑,可以在模型的flags()方法中返回不同的标志。

2.3 自定义外观和交互

  • 允许通过自定义委托(QAbstractItemDelegate)或子类化QTableView来实现自定义单元格的外观和交互。
  • 支持设置不同的视图委托来自定义表格单元格的外观和编辑器,以实现对单元格内容的自定义渲染和编辑。
#include <QStyledItemDelegate>  
#include <QPainter>  class MyDelegate : public QStyledItemDelegate {  
public:  void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override {  if (!index.isValid()) return;  QStyleOptionViewItem opt = option;  initStyleOption(&opt, index);  // 自定义绘制逻辑  painter->save();  painter->setBrush(Qt::lightGray);  painter->drawRect(opt.rect);  painter->drawText(opt.rect, Qt::AlignCenter, index.data().toString());  painter->restore();  }  
};  // 在main函数中设置委托  
// ...  
tableView->setItemDelegate(new MyDelegate);  
// ...

2.4 数据排序和过滤

支持用户对表格数据进行排序和过滤,提高数据的查看和管理效率。

// 启用排序  
tableView->setSortingEnabled(true);

过滤通常需要额外的逻辑,这里不展示完整的过滤实现,但您可以通过重写模型的filter()方法或使用代理模型(如QSortFilterProxyModel)来实现。 

2.5 支持拖放操作

允许用户通过拖放操作在表格中移动、复制或重新排列数据。

tableView->setDragEnabled(true);  
tableView->setAcceptDrops(true);  
tableView->setDropIndicatorShown(true);  // 如果需要处理拖放事件,可以重写QTableView的dragEnterEvent()、dragMoveEvent()和dropEvent()

2.6 自适应大小

支持自适应大小,可以根据内容的大小自动调整单元格、行和列的大小,以确保内容适合显示区域。

// 自动调整列宽以适合内容  
tableView->resizeColumnsToContents();  // 自动调整行高到内容的最小高度  
tableView->resizeRowsToContents();

2.7 上下文菜单

可以为QTableView添加上下文菜单,以提供对数据的额外操作(如复制、粘贴、删除等)。

#include <QMenu>  
#include <QAction>  // ...  
QMenu *menu = new QMenu(tableView);  
QAction *copyAction = menu->addAction("复制");  
QAction *pasteAction = menu->addAction("粘贴");  QObject::connect(tableView, &QTableView::customContextMenuRequested, [&](const QPoint &pos) {  menu->exec(tableView->viewport()->mapToGlobal(pos));  // 这里可以根据选中的动作执行相应的操作,但复制和粘贴需要额外的逻辑  
});  
// ...

2.8 信号与槽

支持信号与槽机制,可以连接特定的信号(如单元格编辑完成、行选中等)到自定义的槽函数,以实现特定的功能。

QObject::connect(tableView->selectionModel(), &QItemSelectionModel::selectionChanged, [&](const QItemSelection &selected, const QItemSelection &deselected) {  qDebug() << "选中了新的行或列";  // 这里可以根据需要处理选中的项  
});  // 对于编辑完成,通常不需要直接连接信号,因为数据变化会通过模型的dataChanged信号发出  
// 但如果您需要,可以像上面那样连接dataChanged信号

三、常用属性设置

3.1 设置模型

设置模型:通过setModel()函数设置QTableView的数据模型。

#include <QTableView>  
#include <QStandardItemModel>  QTableView *tableView = new QTableView;  
QStandardItemModel *model = new QStandardItemModel(4, 2); // 示例:4行2列  
// 填充模型...  
tableView->setModel(model);

3.2 设置选择模型

设置选择模型:通过setSelectionModel()函数设置选择模型,用于跟踪视图上的选择操作。

#include <QItemSelectionModel>  QItemSelectionModel *selectionModel = new QItemSelectionModel(model);  
tableView->setSelectionModel(selectionModel);  
// 注意:这里的model必须是已经设置给tableView的同一个模型

3.3 隐藏垂直标题

隐藏垂直标题:通过verticalHeader()->hide()函数隐藏垂直标题。

tableView->verticalHeader()->hide();

3.4 设置图标大小

设置图标大小:通过setIconSize()函数设置图标大小。

// 假设您已经有一个委托或自定义项设置了图标  
// 通常这里不需要为QTableView设置图标大小
// 如果需要设置
tableView->setIconSize(QSize(32,32));

3.5 选择模式

选择模式:通过setSelectionMode()函数设置选择模式,如单选、多选、扩展选择等。

tableView->setSelectionMode(QAbstractItemView::SingleSelection); // 单选  
// 或  
tableView->setSelectionMode(QAbstractItemView::MultiSelection); // 多选  
// 或  
tableView->setSelectionMode(QAbstractItemView::ExtendedSelection); // 扩展选择

3.6 选择行为

选择行为:通过setSelectionBehavior()函数设置选择行为,如选择项、选择行或选择列。

// 选择模式设置如上,它影响了用户如何做出选择  
// 对于整行/列的选择,更多的是通过样式或委托来实现视觉上的反馈

3.7 调整列宽

调整列宽:可以通过setColumnWidth()或resizeColumnToContents()函数设置列宽。

tableView->setColumnWidth(0, 100); // 将第一列的宽度设置为100  
// 或  
tableView->resizeColumnToContents(1); // 根据内容自动调整第二列的宽度

3.8 设置行高

设置行高:通过verticalHeader()->setDefaultSectionSize()函数设置默认行高。

tableView->verticalHeader()->setDefaultSectionSize(50); // 设置默认行高为50

3.9 交替颜色绘制背景

交替颜色绘制背景:通过setAlternatingRowColors()函数设置是否使用交替颜色绘制背景。

tableView->setAlternatingRowColors(true); // 启用交替颜色绘制背景

3.10 自动排序功能

自动排序功能:通过setSortingEnabled()函数启用或禁用自动排序功能。

tableView->setSortingEnabled(true); // 启用自动排序功能  
// 注意:为了让自动排序工作,您的模型必须支持排序(如QStandardItemModel)  
// 并且您需要确保模型的列是通过sortRole()能够排序的

四、应用场景

QTableView广泛应用于需要展示和编辑二维数据的场景中,如:

  • 数据库管理工具:用于展示和编辑数据库中的数据。
  • 电子表格应用:类似于Microsoft Excel的应用,用于数据处理和分析。
  • 自定义数据展示:在需要以表格形式展示自定义数据的场景中,如科学计算、统计分析等。
  • 报表生成:用于生成和展示报表数据,支持用户查看和编辑报表中的数据。
  • 数据分析工具:在数据分析工具中,QTableView可以显示和分析大量的数据,支持排序和过滤功能。
  • 任务调度管理:在任务调度管理系统中,QTableView可以显示任务列表,支持用户对任务进行编辑和排序。

五、代码示例

以下是一个使用QTableView控件的完整Qt6代码示例,该示例将包括自定义模型、排序、筛选以及委托(用于自定义单元格渲染)的高级功能实现与解析。

首先,我们需要定义一个自定义模型,该模型将继承自QAbstractTableModel。然后,我们将创建一个主窗口,其中包含QTableView并使用该自定义模型。接下来,我们将实现排序和筛选功能,并最后通过委托来自定义单元格的渲染。

5.1 自定义模型(MyTableModel) 

#include <QAbstractTableModel>  
#include <QVector>  
#include <QVariant>  class MyTableModel : public QAbstractTableModel {  Q_OBJECT  public:  MyTableModel(QObject *parent = nullptr) : QAbstractTableModel(parent) {  // 初始化数据  headers << "Name" << "Age" << "Email";  data << {"Alice", "30", "alice@example.com"}  << {"Bob", "25", "bob@example.com"}  << {"Charlie", "35", "charlie@example.com"};  }  int rowCount(const QModelIndex &parent = QModelIndex()) const override {  Q_UNUSED(parent);  return data.size();  }  int columnCount(const QModelIndex &parent = QModelIndex()) const override {  Q_UNUSED(parent);  return headers.size();  }  QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override {  if (!index.isValid() || index.row() >= data.size() || index.column() >= headers.size())  return QVariant();  if (role == Qt::DisplayRole) {  const QVector<QString> &row = data[index.row()];  return row[index.column()];  }  return QVariant();  }  QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override {  if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {  return headers[section];  }  return QVariant();  }  bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override {  if (index.isValid() && index.row() < data.size() && index.column() < headers.size() && role == Qt::EditRole) {  QVector<QString> &row = data[index.row()];  row[index.column()] = value.toString();  emit dataChanged(index, index);  return true;  }  return false;  }  Qt::ItemFlags flags(const QModelIndex &index) const override {  if (!index.isValid())  return Qt::NoItemFlags;  return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled;  }  private:  QVector<QString> headers;  QVector<QVector<QString>> data;  
};

5.2 主窗口和QTableView

#include <QAbstractTableModel>  
#include <QVector>  
#include <QVariant>  class MyTableModel : public QAbstractTableModel {  Q_OBJECT  public:  MyTableModel(QObject *parent = nullptr) : QAbstractTableModel(parent) {  // 初始化数据  headers << "Name" << "Age" << "Email";  data << {"Alice", "30", "alice@example.com"}  << {"Bob", "25", "bob@example.com"}  << {"Charlie", "35", "charlie@example.com"};  }  int rowCount(const QModelIndex &parent = QModelIndex()) const override {  Q_UNUSED(parent);  return data.size();  }  int columnCount(const QModelIndex &parent = QModelIndex()) const override {  Q_UNUSED(parent);  return headers.size();  }  QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override {  if (!index.isValid() || index.row() >= data.size() || index.column() >= headers.size())  return QVariant();  if (role == Qt::DisplayRole) {  const QVector<QString> &row = data[index.row()];  return row[index.column()];  }  return QVariant();  }  QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override {  if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {  return headers[section];  }  return QVariant();  }  bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override {  if (index.isValid() && index.row() < data.size() && index.column() < headers.size() && role == Qt::EditRole) {  QVector<QString> &row = data[index.row()];  row[index.column()] = value.toString();  emit dataChanged(index, index);  return true;  }  return false;  }  Qt::ItemFlags flags(const QModelIndex &index) const override {  if (!index.isValid())  return Qt::NoItemFlags;  return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled;  }  private:  QVector<QString> headers;  QVector<QVector<QString>> data;  
};

5.3 解析

自定义模型:MyTableModel类提供了基本的数据存储和访问功能,包括数据获取、设置和头部信息。
主窗口:在MainWindow中,我们创建了QTableView、自定义模型以及一个排序/筛选代理模型。通过代理模型,我们可以轻松地添加排序和筛选功能。
排序和筛选:通过QSortFilterProxyModel,我们可以对模型数据进行排序和筛选,而无需修改原始模型。
委托:虽然在这个示例中没有完全实现,但委托允许您自定义单元格的渲染方式,包括颜色、字体、背景等。

5.4 实现效果 

 

结语

注意事项

  • 在使用QTableView与数据模型配合时,需要注意内存管理,避免内存泄漏。
  • 在处理大量数据时,需要考虑性能优化,如分页加载、异步更新等策略。
  • 为了提供良好的用户体验,需要确保QTableView的响应速度和交互流畅性。

综上所述,QTableView是Qt框架中一个强大且灵活的控件,适用于各种需要展示和编辑二维数据的场景。通过合理地配置和使用,可以构建出功能丰富、交互性强的用户界面。

以上就是关于Qt中QTableView的全部介绍,如有不足与缺陷之处,欢迎评论区留言!!!   

 

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com