当前位置: 首页 > news >正文

QTableView开发入门

1. QTableView 基础介绍

QTableView 是 Qt 中用于显示表格数据的控件,属于模型/视图架构的一部分。它提供了灵活的方式来展示和编辑二维表格数据。

主要特点:

  • 基于模型/视图架构

  • 支持大型数据集

  • 提供排序、筛选功能

  • 可自定义单元格显示和编辑方式

  • 支持表头自定义

2. 基本使用

2.1 简单示例

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

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
    
    // 创建数据模型
    QStandardItemModel model(4, 3); // 4行3列
    
    // 填充数据
    for (int row = 0; row < 4; ++row) {
        for (int col = 0; col < 3; ++col) {
            QStandardItem *item = new QStandardItem(QString("行%1 列%2").arg(row+1).arg(col+1));
            model.setItem(row, col, item);
        }
    }
    
    // 设置表头
    model.setHorizontalHeaderLabels({"列1", "列2", "列3"});
    model.setVerticalHeaderLabels({"行1", "行2", "行3", "行4"});
    
    // 创建并设置TableView
    QTableView tableView;
    tableView.setModel(&model);
    tableView.setWindowTitle("简单表格示例");
    tableView.resize(500, 300);
    tableView.show();
    
    return app.exec();
}

2.2 常用方法

// 设置选择模式
tableView.setSelectionMode(QAbstractItemView::SingleSelection);  // 单选
tableView.setSelectionMode(QAbstractItemView::MultiSelection);   // 多选

// 设置选择行为
tableView.setSelectionBehavior(QAbstractItemView::SelectRows);   // 整行选择
tableView.setSelectionBehavior(QAbstractItemView::SelectItems);  // 单个单元格选择

// 设置网格线
tableView.setShowGrid(true);  // 显示网格线
tableView.setGridStyle(Qt::DotLine);  // 点线网格

// 设置表头
tableView.horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);  // 自动拉伸
tableView.verticalHeader()->setDefaultSectionSize(30);  // 设置默认行高

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

3. 数据模型使用

3.1 使用 QStandardItemModel

QStandardItemModel *model = new QStandardItemModel(5, 3, this);

// 填充数据
for (int row = 0; row < 5; ++row) {
    for (int col = 0; col < 3; ++col) {
        QStandardItem *item = new QStandardItem(QString("数据 %1-%2").arg(row).arg(col));
        
        // 设置文本颜色
        if (col == 1) {
            item->setForeground(QBrush(Qt::blue));
        }
        
        // 设置背景色
        if (row % 2 == 0) {
            item->setBackground(QBrush(QColor(240, 240, 240)));
        }
        
        // 设置文本对齐
        item->setTextAlignment(Qt::AlignCenter);
        
        model->setItem(row, col, item);
    }
}

// 设置表头
model->setHorizontalHeaderLabels({"姓名", "年龄", "职业"});
ui->tableView->setModel(model);

3.2 使用自定义模型

继承 QAbstractTableModel 创建自定义表格模型:

class CustomTableModel : public QAbstractTableModel {
    Q_OBJECT
    
public:
    explicit CustomTableModel(QObject *parent = nullptr);
    
    // 必须重写的方法
    int rowCount(const QModelIndex &parent = QModelIndex()) const override;
    int columnCount(const QModelIndex &parent = QModelIndex()) const override;
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
    QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
    
    // 可选重写的方法
    bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
    Qt::ItemFlags flags(const QModelIndex &index) const override;
    
    // 自定义方法
    void addData(const QList<QStringList> &newData);
    
private:
    QList<QStringList> m_data;
};

// 实现示例
int CustomTableModel::rowCount(const QModelIndex &parent) const {
    return parent.isValid() ? 0 : m_data.size();
}

int CustomTableModel::columnCount(const QModelIndex &parent) const {
    return parent.isValid() ? 0 : (m_data.isEmpty() ? 0 : m_data.first().size());
}

QVariant CustomTableModel::data(const QModelIndex &index, int role) const {
    if (!index.isValid() || 
        index.row() >= m_data.size() || 
        index.column() >= m_data.first().size())
        return QVariant();
    
    switch (role) {
    case Qt::DisplayRole:
    case Qt::EditRole:
        return m_data[index.row()][index.column()];
    case Qt::TextAlignmentRole:
        return Qt::AlignCenter;
    case Qt::BackgroundRole:
        return index.row() % 2 == 0 ? QColor(240, 240, 240) : QColor(255, 255, 255);
    default:
        return QVariant();
    }
}

4. 表格定制化

4.1 使用委托自定义单元格

class CustomDelegate : public QStyledItemDelegate {
public:
    using QStyledItemDelegate::QStyledItemDelegate;
    
    void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override {
        if (index.column() == 1) {  // 特殊处理第二列
            painter->save();
            
            // 绘制背景
            if (option.state & QStyle::State_Selected) {
                painter->fillRect(option.rect, option.palette.highlight());
            } else {
                painter->fillRect(option.rect, QColor("#f8f8f8"));
            }
            
            // 绘制文本
            painter->setPen(option.state & QStyle::State_Selected ? 
                          option.palette.highlightedText().color() : Qt::darkBlue);
            painter->drawText(option.rect.adjusted(5, 0, -5, 0), 
                            Qt::AlignVCenter | Qt::AlignRight, 
                            index.data().toString());
            
            painter->restore();
        } else {
            QStyledItemDelegate::paint(painter, option, index);
        }
    }
    
    QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override {
        QSize size = QStyledItemDelegate::sizeHint(option, index);
        size.setHeight(35);  // 固定行高
        return size;
    }
};

// 使用委托
ui->tableView->setItemDelegate(new CustomDelegate(this));

4.2 表头定制 

// 设置表头样式
QHeaderView *header = ui->tableView->horizontalHeader();
header->setDefaultAlignment(Qt::AlignCenter);
header->setSectionResizeMode(QHeaderView::Interactive);
header->setStretchLastSection(true);
header->setSectionsClickable(true);

// 自定义表头
class CustomHeader : public QHeaderView {
    // 实现自定义绘制等
};

// 设置自定义表头
ui->tableView->setHorizontalHeader(new CustomHeader(Qt::Horizontal, ui->tableView));

5. 交互功能实现

5.1 选择操作

// 获取选中单元格
QModelIndexList selected = ui->tableView->selectionModel()->selectedIndexes();

// 获取选中行
QModelIndexList selectedRows;
foreach (const QModelIndex &index, ui->tableView->selectionModel()->selectedIndexes()) {
    if (!selectedRows.contains(index.row()))
        selectedRows << index.row();
}

// 获取选中数据
foreach (const QModelIndex &index, selected) {
    qDebug() << "选中的数据:" << index.data().toString()
             << "行:" << index.row() << "列:" << index.column();
}

 5.2 排序和筛选

// 使用代理模型实现排序和筛选
QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel(this);
proxyModel->setSourceModel(sourceModel);
ui->tableView->setModel(proxyModel);

// 设置筛选
proxyModel->setFilterKeyColumn(0);  // 根据第一列筛选
proxyModel->setFilterRegExp(QRegExp("搜索文本", Qt::CaseInsensitive));

// 动态排序
connect(ui->tableView->horizontalHeader(), &QHeaderView::sectionClicked, 
        [proxyModel](int logicalIndex) {
    proxyModel->sort(logicalIndex);
});

6. 高级功能

6.1 合并单元格

// 需要继承QTableView并重写paintEvent
void CustomTableView::paintEvent(QPaintEvent *event) {
    QTableView::paintEvent(event);
    
    QPainter painter(viewport());
    painter.setPen(Qt::red);
    
    // 合并第1行第1列到第3行第2列
    QRect rect1 = visualRect(model()->index(1, 1));
    QRect rect2 = visualRect(model()->index(3, 2));
    QRect mergedRect = rect1.united(rect2);
    
    painter.drawRect(mergedRect.adjusted(0, 0, -1, -1));
    painter.drawText(mergedRect, Qt::AlignCenter, "合并区域");
}

6.2 拖放功能

// 启用拖放
ui->tableView->setDragEnabled(true);
ui->tableView->setAcceptDrops(true);
ui->tableView->setDropIndicatorShown(true);
ui->tableView->setDragDropMode(QAbstractItemView::InternalMove);

// 在模型中实现拖放相关方法
Qt::DropActions CustomModel::supportedDropActions() const {
    return Qt::CopyAction | Qt::MoveAction;
}

// 实现mimeData()和dropMimeData()方法

7. 性能优化

  1. 大数据集处理

    // 使用fetchMore/canFetchMore实现懒加载
    // 设置 uniformRowHeights 提高性能
    ui->tableView->setUniformRowHeights(true);
  2. 减少不必要的刷新

  3. 优化委托:避免在委托中进行复杂计算

  4. 使用模型测试

new QAbstractItemModelTester(model, QAbstractItemModelTester::FailureReportingMode::Warning, this);

相关文章:

  • @DeclareParents 注解实现接口功能增强:Spring中通过接口引入实现功能增强的完整示例
  • 保存预测图像时出现的文件名错误
  • Python----机器学习(KNN:决策边界,决策边界计算,交叉验证步骤)
  • ansible介绍以及安装
  • C++练习
  • C# dataGridView 自动生成几行几列及手动输入整型字符
  • nginx https配置
  • 【算法】并查集基础讲解
  • 每日c/c++题 备战蓝桥杯(全排列问题)
  • DEEPSEEK创业项目推荐:
  • pytorch中不同的mask方法:masked_fill, masked_select, masked_scatter
  • MySQL 当中的锁
  • 网络运维学习笔记(DeepSeek优化版)026 OSPF vlink(Virtual Link,虚链路)配置详解
  • 深度学习 Deep Learning 第13章 线性因子模型
  • PyQt6实例_批量下载pdf工具_批量pdf网址获取
  • 3.30学习总结 Java包装类+高精度算法+查找算法
  • 开发环境解决Secure Cookie导致302重定向
  • VUE实现框架搭建(纯手写)
  • 【Python爬虫神器】requests库常用操作详解 ,附实战案例
  • RocketMQ - 从消息可靠传输谈高可用
  • 网站开发页面设计过程/网络营销知名企业
  • 武城网站建设公司/网络工程师
  • 湖南张家界建设局网站/最好的免费建站网站
  • 哪个网站做免费广告好/媒体营销
  • 网站建设充值入口/指数运算法则
  • 该模板尚未授权此网站/国际机票搜索量大涨