Qt扫盲-QTableView理论总结

news2024/11/25 10:43:46

QTableView理论总结

  • 一、概述
  • 二、导航
  • 三、视觉外观
  • 四、坐标系统
  • 五、示例代码
    • 1. 性别代理
    • 2. 学生信息模型
    • 3. 对应视图

一、概述

QTableView实现了一个tableview 来显示model 中的元素。这个类用于提供之前由QTable类提供的标准表,但这个是使用Qt的model/view架构提供的更灵活的方法。

QTableView类是Model/View类之一,是Qt的Model/View框架的一部分。

QTableView实现了由QAbstractItemView类定义的接口,以允许它显示由QAbstractItemModel类派生的 model 提供的数据。
在这里插入图片描述
总的来说,model/view 的方式来查看修改数据更加的方便和容易的。

二、导航

我们可以通过鼠标点击一个单元格,或者使用箭头键来导航表格中的单元格。因为 QTableView 默认启用tabKeyNavigation,我们还可以按Tab键和Backtab键在单元格之间移动。

三、视觉外观

表格的垂直头部可以通过函数verticalHeader()获得,水平头部可以通过函数horizontalHeader()获得。可以使用rowHeight()来获得表中每一行的高度。类似地,列的宽度可以使用columnWidth()得到。由于这两个部件都是普通部件,因此可以使用它们的hide()函数隐藏它们。

可以使用hideRow()、hideColumn()、showRow()和showColumn()来隐藏和显示行和列。可以使用selectRow()和selectColumn()来选择列。表格会根据 showGrid 属性显示一个网格。就想我把这个设置为 false 之后。就没有网格线啦。
在这里插入图片描述

表视图中显示的项与其他项视图中的项一样,都使用标准委托进行渲染和编辑。

我们还可以用 代理的方式:用下列列表来选择性别的方式
在这里插入图片描述

然而,对于某些任务来说,能够在表中插入其他控件有时是有用的。

用setIndexWidget()函数为特定的索引设置窗口组件,然后用indexWidget()检索窗口组件。

默认情况下,表中的单元格不会扩展以填充可用空间。
您可以通过拉伸最后的标题部分来让单元格填充可用空间。使用 horizontalHeader() 或 verticalHeader() 访问相关的 headerview 标题对象,并设置标题的stretchLastSection属性。

要根据每一列或每一行的空间需求来分配可用空间,可以调用视图的resizeColumnsToContents()或resizeRowsToContents()函数。来实现出下面这种效果。

在这里插入图片描述

四、坐标系统

对于某些特殊形式的表,能够在行和列索引以及控件坐标之间进行转换是很有用的。

rowAt()函数提供了指定行的视图的y坐标;行索引可以通过rowViewportPosition()获得对应的y坐标。

columnAt()和columnViewportPosition()函数提供了x坐标和列索引之间等价的转换操作。

五、示例代码

1. 性别代理

// SexComboxDelegate.h
#ifndef SEXCOMBOXDELEGATE_H
#define SEXCOMBOXDELEGATE_H

#include <QObject>
#include <QStyledItemDelegate>
#include <QComboBox>

class SexComboxDelegate : public QStyledItemDelegate
{
    Q_OBJECT
public:
    SexComboxDelegate(QObject *parent = nullptr);

    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
                          const QModelIndex &index) const override;

    void setEditorData(QWidget *editor, const QModelIndex &index) const override;

    void setModelData(QWidget *editor, QAbstractItemModel *model,
                      const QModelIndex &index) const override;

    void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option,
                              const QModelIndex &index) const override;
};

#endif // SEXCOMBOXDELEGATE_H

// SexComboxDelegate.cpp
#include "SexComboxDelegate.h"

SexComboxDelegate::SexComboxDelegate(QObject *parent)
{

}

QWidget *SexComboxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QComboBox *editor = new QComboBox(parent);

    editor->addItems(QStringList{"男", "女"});

    editor->setFrame(false);

    return editor;
}

void SexComboxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
    QComboBox *combox = static_cast<QComboBox*>(editor);

    combox->setCurrentIndex(combox->findText(index.model()->data(index, Qt::DisplayRole).toString()));
}

void SexComboxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
    QComboBox *combox = static_cast<QComboBox*>(editor);

    model->setData(index, combox->currentText(), Qt::EditRole);
}

void SexComboxDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    editor->setGeometry(option.rect);
}

2. 学生信息模型

// StudentModel.h
#ifndef STUDENTMODEL_H
#define STUDENTMODEL_H

#include <QAbstractTableModel>
#include <QDebug>
#include <QColor>
#include <QBrush>
#include <QFont>

class StudentModel: public QAbstractTableModel
{
    Q_OBJECT
public:
    StudentModel(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 setRow(int newRow);

    void setColumn(int newColumn);

    void setTableHeader(QList<QString> *header);

    void setTableData(QList<QList<QString>> *data);

signals:
    void editCompleted(const QString &);

public slots:
    void SlotUpdateTable();
private:
    int row = 0;
    int column = 0;

    QList<QString> *m_header;
    QList<QList<QString>> *m_data;
};

#endif // STUDENTMODEL_H

// StudentModel.cpp
#include "StudentModel.h"

StudentModel::StudentModel(QObject *parent) : QAbstractTableModel(parent)
{

}

int StudentModel::rowCount(const QModelIndex &parent) const
{
    return row;
}

int StudentModel::columnCount(const QModelIndex &parent) const
{
    return column;
}

QVariant StudentModel::data(const QModelIndex &index, int role) const
{
    if(role == Qt::DisplayRole || role == Qt::EditRole)
    {
        return (*m_data)[index.row()][index.column()];
    }

    if(role == Qt::TextAlignmentRole)
    {
        return Qt::AlignCenter;
    }

    if(role == Qt::BackgroundRole &&  index.row() % 2 == 0)
    {
        return QBrush(QColor(50, 50, 50));
    }

    return QVariant();
}

QVariant StudentModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
        if(m_header->count() - 1 >= section)
            return m_header->at(section);
    }

    //qDebug()<<role << "--" << Qt::BackgroundRole;

//    if(role == Qt::BackgroundRole)
//    {
//        return QBrush(QColor(156, 233, 248));
//    }
//    if(role == Qt::ForegroundRole)
//    {
//         return QBrush(QColor(156, 233, 248));
//    }

    if(role == Qt::FontRole)
    {
         return QFont(tr("微软雅黑"),10, QFont::DemiBold);
    }
    return QVariant();
}

bool StudentModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    if (role == Qt::EditRole) {
         if (!checkIndex(index))
            return false;

         //save value from editor to member m_gridData
         (*m_data)[index.row()][index.column()] = value.toString();
         return true;
    }
    return false;
}

Qt::ItemFlags StudentModel::flags(const QModelIndex &index) const
{
    return Qt::ItemIsEditable | QAbstractTableModel::flags(index);
}

void StudentModel::setRow(int newRow)
{
    row = newRow;
}

void StudentModel::setColumn(int newColumn)
{
    column = newColumn;
}

void StudentModel::setTableHeader(QList<QString> *header)
{
    m_header = header;
}

void StudentModel::setTableData(QList<QList<QString> > *data)
{
    m_data = data;
}

void StudentModel::SlotUpdateTable()
{
    emit dataChanged(createIndex(0, 0), createIndex(row, column), {Qt::DisplayRole});
}

3. 对应视图

// StudentWD.h
#ifndef STUDENTWD_H
#define STUDENTWD_H

#include <QWidget>
#include <Model/StudentModel.h>
#include <QFileDialog>
#include <QStandardPaths>
#include <QFile>
#include <QTextStream>
#include <Delegate/SpinBoxDelegate.h>
#include <Delegate/SexComboxDelegate.h>

namespace Ui {
class StudentWD;
}

class StudentWD : public QWidget
{
    Q_OBJECT

public:
    explicit StudentWD(QWidget *parent = nullptr);
    ~StudentWD();

private slots:
    void on_ImportBtn_clicked();

private:
    Ui::StudentWD *ui;

    StudentModel *model;
    SpinBoxDelegate *spinBoxDelegate;
    SexComboxDelegate *sexBoxDeleage;

    QList<QList<QString>> subject_table;
    QList<QString> subject_title;
};

#endif // STUDENTWD_H
// StudentWD.cpp
#include "StudentWD.h"
#include "ui_StudentWD.h"

StudentWD::StudentWD(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::StudentWD),
    model(new StudentModel),
    spinBoxDelegate(new SpinBoxDelegate),
    sexBoxDeleage(new SexComboxDelegate)
{
    ui->setupUi(this);

    ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);

}

StudentWD::~StudentWD()
{
    delete ui;
}

void StudentWD::on_ImportBtn_clicked()
{
    QString fileName = QFileDialog::getOpenFileName(this,
                                            tr("打开 csv 文件"), QStandardPaths::writableLocation(QStandardPaths::DesktopLocation), tr("Txt Files (*.txt *.csv *.*)"));

    subject_table.clear();
    subject_title.clear();

    if(!fileName.isNull() && !fileName.isEmpty())
    {
        QFile file(fileName);
        if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
            return;

        int i = 0;
        QTextStream in(&file);
        in.setCodec("UTF-8");
        while (!file.atEnd()) {
            QString line = file.readLine();

            if(i == 0)
            {
                subject_title = line.split(",", QString::SkipEmptyParts);
                subject_title.last() = subject_title.last().trimmed();
                i++;
                continue;
            }
            subject_table.append(line.split(",", QString::SkipEmptyParts));
            subject_table.last().last() = subject_table.last().last().trimmed();
        }

        ui->Total_Subject_SB->setValue(subject_title.count());
        ui->Total_People_SB->setValue(subject_table.count());

        model->setColumn(subject_title.count());
        model->setRow(subject_table.count());

        model->setTableData(& subject_table);
        model->setTableHeader(& subject_title);

        ui->tableView->setModel(model);
        ui->tableView->setItemDelegateForColumn(0, spinBoxDelegate);
        ui->tableView->setShowGrid(true);

        ui->tableView->setItemDelegateForColumn(1, sexBoxDeleage);

        for (int i = 2; i < subject_table.count(); ++i) {
            ui->tableView->setItemDelegateForColumn(i, spinBoxDelegate);
        }
            ui->tableView->horizontalHeader()->setSectionResizeMode(4, QHeaderView::ResizeToContents);
    }

}

对应的ui文件
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/881850.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

mysql 8.0.20不停机主从同步

一、环境 CentOS &#xff1a; 7.3.1611 (Core) mysql&#xff1a;8.0.20 二、遇到的问题 1.查看主从同步发现下列问题 error connecting to master repl192.168.0.21:3306 - retry-time: 60 retries: 4 message: Authentication plugin caching_sha2_password reported e…

https协议的nginx请求http协议tomcat,出现静态文件js访问不到的情况!

复现问题&#xff1a; 访问https://1.1.1.1:443/aaa,页面出现静态js,css请求失败&#xff01; F12查看&#xff1a; 分析问题&#xff1a; 问题的根源应该就是浏览器的安全机制&#xff0c;不允许在嵌套在https的页面中进行http请求吧&#xff0c;结合google想到这个应该可以…

用dcker极简打包java.jar镜像并启动

用dcker极简打包java.jar镜像并启动 一、本地打包好jar包 二、新建文件夹&#xff0c;将步骤1中的jar包拷贝到文件夹下 三、同目录下新建Dockerfile ## 基础镜像&#xff0c;这里用的是openjdk:8 FROM openjdk:8## 将步骤一打包好的jar包 拷贝到镜像的 跟目录下[目录可以自定义…

真想学技术,还是不要去外包了,干了三年,废了....

先说一下自己的情况&#xff0c;大专生&#xff0c;18年通过校招进入湖南某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试…

群折射率$ n_g$与有效折射率$ n_{eff}$的关系详细推导(假设$ \lambda_0$为真空入射光波长)

这个关系应该在环谐振器相关的资料中挺常见的。 其中&#xff1a; 注意 β \beta β为传播常数。

我都30了,还能不能做软件测试?

今天在CSDN看到一个问答&#xff0c;我都30了&#xff0c;还能不能做软件测试&#xff1f;我本来想直接回答&#xff0c;但回答的明显字数不够用。所以就干脆就把想说的都记录下来写一篇文章。 1.我今年30岁了&#xff0c;还适不适合做软件测试&#xff1f; 我认为&#xff0c;…

合并单元格

需求&#xff1a; 合并 相同名称的产品 先说下elementUI合并单元格的方法&#xff0c;先计算好要合并的行数rowspan&#xff0c;return {rowspan&#xff0c;colspan}&#xff0c;其他的单元格return{0,0} getData(params) {//临时数组&#xff0c;存放产品名称相同的数量this…

helm安装harbor + nerdctl 制作push 镜像

参考 文章&#xff1a;Helm部署Harbor_helm harbor_风向决定发型丶的博客-CSDN博客 安装好后使用 nerd containerd对接harbor_containerd 容器 insecure-registries 配置_柠是柠檬的檬的博客-CSDN博客 推送镜像 Containerd 对接私有镜像仓库 Harbor - 知乎 接下来我们来…

2023年7月京东洗衣机行业品牌销售排行榜(京东数据分析软件)

2023年上半年&#xff0c;洗衣机市场表现平淡&#xff0c;同环比来看出货量都有一定程度的下滑。7月份&#xff0c;洗衣机市场仍未改变这一下滑态势。 根据鲸参谋电商数据分析平台的相关数据显示&#xff0c;7月份&#xff0c;京东平台洗衣机的销量为109万&#xff0c;环比下降…

企业为什么需要档案管理系统?

在当今的信息化社会&#xff0c;企业的数据和信息越来越多&#xff0c;而且日益复杂。而这些数据和信息都是企业运营的重要资源&#xff0c;它们的管理与否&#xff0c;直接影响到企业的决策效率&#xff0c;甚至是企业的生存发展。然而&#xff0c;传统的纸质档案管理方式已经…

机器学习实战:Python基于KDE核密度估计进行分布估计(十六)

文章目录 1. 前言1.1 KDE简介1.2 KDE应用领域 2. diy数据集实战演示2.1 导入函数2.2 自定义数据2.3 可视化数据2.4 KDE建模 3. 参数探讨3.1 带宽3.2 选择最佳带宽3.2 核函数 3.4 挑选合适核函数4. 讨论 1. 前言 1.1 KDE简介 核密度估计&#xff08;Kernel Density Estimation…

结构体和数组结合使用

1、定义结构体 struct Student {int num;char name[32]; }; 2、结构体数组定义 #include<iostream> using namespace std;struct Student {int num;char name[32]; }; int main() {//结构体变量复制方式2struct Student arr[2] { {1,"张三"}, {2,"李四…

从系统角度,看智能制造|百世慧®

7月31日我们结束了智能制造专题第二期“电池智能制造质量管理应用及案例分享”的线上研讨会&#xff0c;有不少朋友没有来得及参加智能制造专题第一期研讨会&#xff0c;同时又工作繁忙。所以&#xff01;今天就由我百小能为大家快速讲解第一期研讨会——“电池智能制造应用”的…

【C++】移动赋值运算符

2023年8月15日&#xff0c;周二上午 概述 移动赋值运算符是一个特殊的赋值运算符&#xff0c;用于从一个对象中移动&#xff08;转移&#xff09;资源到另一个对象&#xff0c;而不是进行复制操作。它通常与右值引用一起使用&#xff0c;以实现高效的资源转移&#xff0c;提高…

用AI解锁声音的奥秘——启英泰伦新成果发布交流会

声音&#xff0c;是由物体或介质的振动引起的&#xff0c;振动源的多样性、振动的频率和波形的差异、传播介质的差异等因素共同作用&#xff0c;使我们能够感知到丰富而多样化的声音世界。听得到、听得清、听得懂、辨得明&#xff0c;是AI语音技术的重要研究课题。 启英泰伦一…

leetcode810. 黑板异或游戏(博弈论 - java)

黑板异或游戏 lc 810 - 黑板异或游戏题目描述博弈论 动态规划 lc 810 - 黑板异或游戏 难度 - 困难 原题链接 - 黑板异或游戏 题目描述 黑板上写着一个非负整数数组 nums[i] 。 Alice 和 Bob 轮流从黑板上擦掉一个数字&#xff0c;Alice 先手。如果擦除一个数字后&#xff0c;剩…

考研算法45天:首字母大写 【字符串:简单】

题目前置知识 如何使用scanf输入一个有空格的字符串 如何输入带空格的字符串_我码了的博客-CSDN博客 scanf("%[^\n]",str); 如何用ascll码将字符串的小写换为大写 char a; a a - 32; 题目概况 AC代码 #include <iostream> using namespace std;int main()…

2023年武汉中级工程师职称评审条件是什么?评审材料需要哪些呢?

2023年武汉中级职称评审马上全面开启&#xff0c;预计8月底或者9月初就会开始申报了。 要求&#xff1a;学历、社保、论文、业绩等各类材料等 出证时间&#xff1a;现在申报&#xff0c;年底出结果&#xff0c;次年3-5月出证 一、2023年武汉中级工程师职称评审条件学历条件是什…

insightface安装过程中提示 Microsoft Visual C++ 14.0 or greater is required.

pip install insightface安装过程中提示 Microsoft Visual C 14.0 or greater is required.Get it with "Microsoft C Build Tools": https://visualstudio.microsoft.com/visual-cpp-build-tools/ 根据提示网站访问官网下载生成工具 打开软件后会自动更新环境&#…

一键免费部署自己的GPT网站

先看看效果 https://chat-gpt-next-web2-xi-three.vercel.app 为啥推荐这个呢&#xff0c;其实市面上已经有很多了&#xff0c;这个主要是UI蛮漂亮的&#xff0c;嘿嘿&#xff01; 你要是简单想弄的话&#xff0c;CSDN就能免费搭建一个&#xff0c;这个就自行百度吧&#xff0c…