QTableView之一:基本使用
Published on 2022-07-12 17:54 in 分类: Qt with 萧海~
分类: Qt

QTableView之一:基本使用

    一、简介

    表格视图控件 QTableView,需要和 QStandardItemModel 配套使用,这套框架是基于 MVC 设计模式设计的,M(Model) 是 QStandardItemModel 数据模型不能单独显示出来。V(view) 是指 QTableView 视图,要来显示数据模型,C(controllor) 控制在 Qt 中被弱化,与 View 合并到一起。

    使用时需要包含#include 和#include ,创建一个QTableView对象和QStandardItemModel并使用QTableView的setModel()函数将视图和模型对象进行绑定。

    二、QTableView基础使用

    QStandardItmeModel 表格的数据模型,那么这个模型需要填上每一行每一列的数据,就像 execl 表格一样。

    widget.h

    #ifndef WIDGET_H
    #define WIDGET_H
    #include <QWidget>
    #include <QTableView>
    #include <QStandardItem>
    #include <QPushButton>
    #include <QHBoxLayout>
    #include <QVBoxLayout>
    #include <QEvent>
    #include <QMenu>
    #include <QDebug>
    class Widget : public QWidget
    {
    Q_OBJECT
    public:
    Widget(QWidget *parent = nullptr);
    protected:
    bool eventFilter(QObject *object, QEvent *event) override; // 事件过滤器
    private:
    QTableView *m_pMyTableView;
    QStandardItemModel* m_model;
    QPushButton *m_pBtnRemove;
    QPushButton *m_pBtnAdd;
    };
    #endif // WIDGET_H

    widget.cpp

    #include "Widget.h"
    Widget::Widget(QWidget *parent)
    : QWidget(parent)
    {
    // 初始化界面
    this->setFixedSize(400, 300);
    // 初始化tableWidget
    m_pMyTableView = new QTableView;
    m_pMyTableView->setFixedSize(300, 300);
    m_pMyTableView->installEventFilter(this);
    // 初始化model
    m_model = new QStandardItemModel();
    m_pMyTableView->setModel(m_model); // 设置m_pMyTableView的数据模型为m_model
    // 设置列字段名
    m_model->setColumnCount(3);
    m_model->setHeaderData(0,Qt::Horizontal, "姓名");
    m_model->setHeaderData(1,Qt::Horizontal, "年龄");
    m_model->setHeaderData(2,Qt::Horizontal, "性别");
    // 设置一条数据
    m_model->setItem(0, 0, new QStandardItem("张三"));
    m_model->setItem(0, 1, new QStandardItem("3"));
    m_model->setItem(0, 2, new QStandardItem("男"));
    // 初始化按钮
    m_pBtnRemove = new QPushButton;
    m_pBtnAdd = new QPushButton;
    m_pBtnRemove->setText("移除");
    m_pBtnAdd->setText("添加");
    connect(m_pBtnRemove, &QPushButton::clicked, [=]{
    m_model->removeRow(m_model->rowCount() - 1);
    });
    connect(m_pBtnAdd, &QPushButton::clicked, [=]{
    QList<QStandardItem*> list;
    list << new QStandardItem("王五") << new QStandardItem("22") << new QStandardItem("男");
    m_model->insertRow(m_model->rowCount(), list); // 插入一条记录
    });
    // 标签、按钮布局
    QVBoxLayout *pLayoutBtn = new QVBoxLayout;
    pLayoutBtn->addStretch();
    pLayoutBtn->addWidget(m_pBtnRemove);
    pLayoutBtn->addSpacing(24);
    pLayoutBtn->addWidget(m_pBtnAdd);
    pLayoutBtn->addStretch();
    pLayoutBtn->setSpacing(0);
    // 主布局
    QHBoxLayout *pLayoutMain = new QHBoxLayout(this);
    pLayoutMain->addStretch();
    pLayoutMain->addWidget(m_pMyTableView);
    pLayoutMain->addStretch();
    pLayoutMain->addLayout(pLayoutBtn);
    pLayoutMain->addStretch();
    pLayoutMain->setSpacing(0);
    pLayoutMain->setMargin(0);
    // 数据变更信号处理
    connect(m_model, &QStandardItemModel::dataChanged, [=](const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles) {
    Q_UNUSED(bottomRight);
    Q_UNUSED(roles);
    qDebug() << m_model->data(topLeft).toString() << endl;
    });
    }
    // 对于表格控件常见的操作就是弹出菜单,当鼠标点击控件时会触发一个QEvent::ContextMenu类型的事件,
    // 通过重载eventFilter()事件过滤器函数,并捕获该类型事件来实现菜单的弹出
    bool Widget::eventFilter(QObject *object, QEvent *event)
    {
    if(object == m_pMyTableView && event->type() == QEvent::ContextMenu) {
    if(m_pMyTableView->currentIndex().isValid()) {
    QMenu * menu = new QMenu();
    menu->addAction("添加数据");
    menu->addAction("删除数据");
    QAction * action = menu->exec(cursor().pos()); // 弹出菜单
    if (action->text().compare("添加数据") == 0) {
    QList<QStandardItem*> list;
    list << new QStandardItem("王五") << new QStandardItem("22") << new QStandardItem("男");
    m_model->insertRow(m_model->rowCount(), list); // 插入一条记录
    }
    if (action->text().compare("删除数据") == 0) {
    m_model->removeRow(m_pMyTableView->currentIndex().row());
    }
    }
    }
    return QWidget::eventFilter(object, event);
    }

    程序执行如下:
    在这里插入图片描述

    三、QTableView属性设置

    对于表格而言可以对其样式进行调整,常见的设置如下:

    设置表格的线属性

    this->setShowGrid(false); // 隐藏网格线
    this->setGridStyle(Qt::DotLine); // 线的样式
    this->setFocusPolicy(Qt::NoFocus); // 取消Item选中后的虚线边框

    设置表格的选中模式等

    this->setWordWrap(false); // 文本过长不换行
    this->setEditTriggers(QAbstractItemView::NoEditTriggers); // 设置不可编辑
    this->setSelectionBehavior(QAbstractItemView::SelectRows); // 设置选中一整行
    this->setSelectionMode (QAbstractItemView::SingleSelection); // 只允许选中单行
    //this->setSelectionMode (QAbstractItemView::ExtendedSelection); // 允许选中多行

    设置表格的表头

    /* 设置垂直表格头的显示、对齐方式、高宽等,水平表格头类似 */
    this->horizontalHeader()->setVisible(false); // 隐藏水平表头
    this->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft); // 设置水平表头为左对齐
    this->verticalHeader()->setDefaultAlignment(Qt::AlignBottom); // 设置垂直表头为底对齐
    this->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed); // 固定表格宽度不可扩展,不可手动调整宽度
    this->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); // 表格宽度随内容自动扩展
    this->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch); // 表格宽度自动根据UI进行计算,不可手动调整宽度
    this->verticalHeader()->setMinimumSectionSize(ITEM_HEIGHT);
    this->verticalHeader()->setDefaultSectionSize(ITEM_HEIGHT);

    设置表格的内置滚动条

    this->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); // 显示垂直滑动条
    this->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); // 隐藏水平滑动条
    this->setVerticalScrollMode(QTableView::ScrollPerPixel); // 垂直滚动条设置为像素滚动
    this->verticalScrollBar()->setSingleStep(ITEM_HEIGHT/3); // 设置滚动条步长(要先设置为像素滚动,才能生效;ITEM_HEIGHT为项的高度)

    其它

    this->verticalHeader()->setHidden(true); // 隐藏默认行号
    this->setIconSize(QSize(30, 30)); // 设置icon尺寸大小(否则显示的图标尺寸很小,即使实际图片文件很大)
    this->setDragEnabled(false); // 禁用拖拽,否则此处添加拖拽的话会生成两个item
    this->setMouseTracking(true); // 设置鼠标追踪,下面的entered才会触发槽函数
    posted @   萧海~  阅读(1028)  评论(0编辑  收藏  举报
    相关博文:
    阅读排行:
    · 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
    · Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
    · 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
    · 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
    · AI技术革命,工作效率10个最佳AI工具
    点击右上角即可分享
    微信分享提示
    电磁波切换