QTableView编程——Model/View架构(单元格随意拖拽交换)

QTableView编程——Model/View架构

基础知识

  • 添加表头
     //准备数据模型
    QStandardItemModel *student_model = new QStandardItemModel();
    student_model->setHorizontalHeaderItem(0, new QStandardItem(QObject::tr("Name")));
    student_model->setHorizontalHeaderItem(1, new QStandardItem(QObject::tr("NO.")));
    student_model->setHorizontalHeaderItem(2, new QStandardItem(QObject::tr("Sex")));
    student_model->setHorizontalHeaderItem(3, new QStandardItem(QObject::tr("Age")));
    student_model->setHorizontalHeaderItem(4, new QStandardItem(QObject::tr("College")));
    //利用setModel()方法将数据模型与QTableView绑定
    ui->student_tableview->setModel(student_model);
  • 设置表格属性
    //设置列宽不可变动,即不能通过鼠标拖动增加列宽        
    ui->student_tableview->horizontalHeader()->setResizeMode(0, QHeaderView::Fixed);   
    ui->student_tableview->horizontalHeader()->setResizeMode(1, QHeaderView::Fixed);   
    ui->student_tableview->horizontalHeader()->setResizeMode(2, QHeaderView::Fixed);   
    ui->student_tableview->horizontalHeader()->setResizeMode(3, QHeaderView::Fixed);   
    ui->student_tableview->horizontalHeader()->setResizeMode(4, QHeaderView::Fixed);   
    //设置表格的各列的宽度值        
    ui->student_tableview->setColumnWidth(0,100);    
    ui->student_tableview->setColumnWidth(1,100);    
    ui->student_tableview->setColumnWidth(2,100);    
    ui->student_tableview->setColumnWidth(3,100);    
    ui->student_tableview->setColumnWidth(4,100);        
    //默认显示行头,如果你觉得不美观的话,我们可以将隐藏        
    ui->student_tableview->verticalHeader()->hide();       
    //设置选中时为整行选中        
    ui->student_tableview->setSelectionBehavior(QAbstractItemView::SelectRows);         

    //设置表格的单元为只读属性,即不能编辑        
    ui->student_tableview->setEditTriggers(QAbstractItemView::NoEditTriggers);          
    //如果你用在QTableView中使用右键菜单,需启用该属性        
    ui->tstudent_tableview->setContextMenuPolicy(Qt::CustomContextMenu);
  • 动态添加行
//在第一行添加学生张三的个人信息(setItem函数的第一个参数表示行号,第二个表示列号,第三个为要显示的数据)
    student_model->setItem(0, 0, new QStandardItem(“张三"));
    student_model->setItem(0, 1, new QStandardItem("20120202"));
    student_model->setItem(0, 2, new QStandardItem("男"));
    student_model->setItem(0, 3, new QStandardItem("18"));
    student_model->setItem(0, 4, new QStandardItem("土木学院"));
  • 设置数据显示的样式
 //设置单元格文本居中,张三的数据设置为居中显示
    student_model->item(0, 0)->setTextAlignment(Qt::AlignCenter);
    student_model->item(0, 1)->setTextAlignment(Qt::AlignCenter);
    student_model->item(0, 2)->setTextAlignment(Qt::AlignCenter);
    student_model->item(0, 3)->setTextAlignment(Qt::AlignCenter);
    student_model->item(0, 4)->setTextAlignment(Qt::AlignCenter);
    //设置单元格文本颜色,张三的数据设置为红色
    student_model->item(0, 0)->setForeground(QBrush(QColor(255, 0, 0))); 
    student_model->item(0, 1)->setForeground(QBrush(QColor(255, 0, 0))); 
    student_model->item(0, 2)->setForeground(QBrush(QColor(255, 0, 0))); 
    student_model->item(0, 3)->setForeground(QBrush(QColor(255, 0, 0))); 
    student_model->item(0, 4)->setForeground(QBrush(QColor(255, 0, 0))); 
    //将字体加粗
    student_model->item(0, 0)->setFont( QFont( "Times", 10, QFont::Black ) );
    student_model->item(0, 1)->setFont( QFont( "Times", 10, QFont::Black ) );
    student_model->item(0, 2)->setFont( QFont( "Times", 10, QFont::Black ) );
    student_model->item(0, 3)->setFont( QFont( "Times", 10, QFont::Black ) );
    student_model->item(0, 4)->setFont( QFont( "Times", 10, QFont::Black ) );
    //设置排序方式,按年龄降序显示
    student_model->sort(3, Qt::DescendingOrder);

功能实现

实现功能

  • 实现TableView中的单元格和单元格直接的拖拽替换
  • 如果整行为空的时候,会自动删除该行
  • 如果拖拽的表格的底部,那么自动增加一行

01 随意拖拽替换

替换前:

image-20230515212606637

替换后:

image-20230515212636894

02 整行为空 自动删除空行

image-20230515212743822

03 拖拽到底部自动增加一行

image-20230515212804885

代码实现

main.cpp

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include "MyTableModel.h"
#include "MyStandardItemModel.h"
#include "MyTableView.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    initMyStandardItemModel();
}

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


void MainWindow::initMyStandardItemModel()
{
    //QStandardItemModel类提供用于存储自定义数据的通用模型
    MyStandardItemModel* model = new MyStandardItemModel(this);
    QTableView *view=ui->tableViewB;
    view->setModel(model);

    QStringList headerList;
    headerList << "Driver" << "Dest" << "Choose";
    model->setHorizontalHeaderLabels(headerList);
    model->setItem(0,2, new QStandardItem("driclk1"));
    model->setItem(1,2, new QStandardItem("driclk2"));
    model->setItem(2,2, new QStandardItem("driclk3"));

    view->setSelectionMode(QAbstractItemView::SingleSelection);
    view->setDragEnabled(true);
    view->setDefaultDropAction(Qt::MoveAction);//不是必要的
    view->setDragDropMode(QAbstractItemView::DragDrop);
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

    void initMyStandardItemModel();

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

MyStandardItemModel.cpp

#include "MyStandardItemModel.h"

#include <QMimeData>
#include <QDebug>

MyStandardItemModel::MyStandardItemModel(QObject *parent)
    : QStandardItemModel(parent)
{

}

Qt::ItemFlags MyStandardItemModel::flags(const QModelIndex &index) const
{
    if (index.isValid())
        return Qt::ItemIsDragEnabled  | Qt::ItemIsDropEnabled  | QStandardItemModel::flags(index);
    return QStandardItemModel::flags(index);
}

Qt::DropActions MyStandardItemModel::supportedDropActions() const
{
    return Qt::MoveAction | QStandardItemModel::supportedDropActions();
}

QMimeData *MyStandardItemModel::mimeData(const QModelIndexList &indexes) const
{
    QMimeData *data=QStandardItemModel::mimeData(indexes);
    if(data){
        // parent mimeData中已判断indexes有效性,无效的会返回nullptr
        // 也可以把信息放到model的mutable成员中
        data->setData("row",QByteArray::number(indexes.at(0).row()));
        data->setData("col",QByteArray::number(indexes.at(0).column()));
    }
    return data;
}

bool MyStandardItemModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
{
    if(!data||action!=Qt::MoveAction)
        return false;

    //这里没有判断toint ok(数据转换有效性)   dri
    const QModelIndex old_index=index(data->data("row").toInt(),
                                      data->data("col").toInt());
    const QModelIndex current_index=parent;
    //可以先对index有效性进行判断,无效返回false,此处略过   dest
    QStandardItem *old_item=takeItem(old_index.row(),old_index.column());
    QStandardItem *current_item=takeItem(current_index.row(),current_index.column());


    if (!parent.isValid()) {
        appendRow(QList<QStandardItem *>() << old_item);
    } else {
        //交换两个item
        setItem(old_index.row(),old_index.column(),current_item);
        setItem(current_index.row(),current_index.column(),old_item);
    }


    for (int row = 0; row < rowCount(); ++row) {
        if (isRowEmpty(row)) {
            removeRow(row);
        }
    }

    // 打印修改后的 model 数据
    for (int row = 0; row < rowCount(); row++) {
        for (int col = 0; col < columnCount(); col++) {
            QModelIndex index = this->index(row, col);
            QString data = this->data(index, Qt::DisplayRole).toString();
            qDebug() << "Row " << row << ", Column " << col << ": " << data;

        }
    }
    return true;
}

bool MyStandardItemModel::isRowEmpty(int row)
{
    for (int column = 0; column < columnCount(); ++column) {
        QModelIndex index = this->index(row, column);
        if (index.isValid() && !index.data().toString().isEmpty()) {
            // 如果有一列数据不为空,说明这一行不为空
            return false;
        }
    }

    // 所有列数据都为空,说明这一行为空
    return true;
}

MyStandardItemModel.h

#ifndef MYSTANDARDITEMMODEL_H
#define MYSTANDARDITEMMODEL_H

#include <QStandardItem>
#include <QStandardItemModel>

class MyStandardItemModel : public QStandardItemModel
{
    Q_OBJECT
public:
    explicit MyStandardItemModel(QObject *parent = nullptr);

    // 允许的操作,加上drag drop
    Qt::ItemFlags flags(const QModelIndex &index) const override;
    // 允许move
    Qt::DropActions supportedDropActions() const override;
    // drag时携带的信息  存放拖拽的数据
    QMimeData *mimeData(const QModelIndexList &indexes) const override;
    // drop时根据drag携带的信息进行处理
    bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override;
    bool isRowEmpty(int row);
};

#endif // MYSTANDARDITEMMODEL_H

参考资料

Qt QTableView 表格内添加控件_qt中tableview加入其他控件_师从名剑山的博客-CSDN博客

QTableView拖拽交换行、列、单元格_龚建波的博客-CSDN博客

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python Scrapy爬虫框架安装和创建

1、检查Win环境 python版本 python 2、whl方式安装 twisted twisted异步网络框架&#xff0c;可加快下载速度。优点是用少量的代码实现快速的抓取。 由于scrapy需要twisted的环境&#xff0c;我们直接去下载whl文件根据自己的Python版本选择 https://www.lfd.uci.edu/~gohlke/p…

STM32F103ZET6驱动TOF250激光测距传感器

STM32驱动TOF250激光测距传感器 TOF250介绍I2C通讯协议I2C寄存器地址 TOF250引脚说明和STM32的接线和STM32的接线 程序实验结果总结 TOF250介绍 TOF250是一款基于TOF原理的单点测距雷达&#xff0c;采用940nm红外光源&#xff0c;提供了精确和可重复的远 距离测量用于高速自动对…

集群时间同步

集群时间同步 时间同步的方式&#xff1a;找一个机器&#xff0c;作为时间服务器&#xff0c;所有的机器与这台集群时间进行定时的同步&#xff0c;比如&#xff0c;每隔十分钟&#xff0c;同步一次时间。 1.配置时间同步具体实操&#xff1a; 1.1&#xff09;时间服务器配…

有没有中国版的chatGPT?

ChatGPT是一个基于人工智能的聊天机器人&#xff0c;它可以通过自然语言处理技术与用户进行交互和对话。ChatGPT的目的是为用户提供便捷的问答服务和娱乐&#xff0c;它可以回答各种问题&#xff0c;例如天气、新闻、历史、文化、科技、娱乐等等。ChatGPT的核心技术是基于GPT模…

银河麒麟系统Arm64编译opencv指南

进入opencv官网下载版本&#xff1b;我这边下载的是2.4.13.6 &#xff1b;根据需要下载最新的 Releases - OpenCV 拷贝进麒麟系统我这边是麒麟V10 sp1 2204&#xff1b;并解 cmake 在麒麟应用商城中安装&#xff1b; 打开cmake 设置opencv路径&#xff1b;builder文件夹可以自…

内卷时代,大厂产品经理仅用3步破局

本文首发自「慕课网」&#xff0c;想了解更多IT干货内容&#xff0c;程序员圈内热闻&#xff0c;欢迎关注"慕课网"&#xff01; 作者&#xff1a;申悦|慕课网讲师 在当下互联网环境下&#xff0c;产品经理究竟要如何破局&#xff1f; 我认为&#xff0c;既然要破局…

分组卷积和深度可分离卷积

文章目录 一、常规卷积操作二、分组卷积三、深度可分离卷积 一、常规卷积操作 在图中&#xff0c;输入的特征图大小为 H * W * 4 卷积核个数为 2 个&#xff0c;每个卷积核的大小为 K * K * 4 输出的特征图大小为 H’ * W’ * 2 二、分组卷积 &#xff01;&#xff01;&#…

Maven构建生命周期

目录 Default (Build) 生命周期 命令行调用 Site 生命周期 如何清除本地 Maven 仓库并重新构建项目 Maven 构建配置文件 mvn dependency:purge-local-repository 这个命令是干什么的&#xff1f; mvn clean install这个命令是干什么的&#xff1f; 配置文件激活 1、配…

数据湖与数据仓库区别

数据湖是近两年中比较新的技术在大数据领域中&#xff0c;对于一个真正的数据湖应该是什么样子&#xff0c;现在对数据湖认知还是处在探索的阶段&#xff0c;像现在代表的开源产品有iceberg、hudi、Delta Lake。 那对于数据湖应该是什么样子&#xff0c;先来看数据湖的作者AWS…

【STL】string的使用

放在专栏【C知识总结】&#xff0c;会持续更新&#xff0c;期待支持&#x1f339; STL简介 STL的诞生 STL为英文Standard Template Library的缩写&#xff0c;译为标准模板库。是C标准库的重要组成部分。 长久以来&#xff0c;软件届一直希望建立一种可重复运用的东西。所谓…

元宇宙又“死”了!Epic老板:你当6亿用户是摆设?

“扎克伯格花了数年时间试图让Metaverse成为现实&#xff0c;但现在它已被AI取代&#xff0c;并走向科技创意的坟墓。”一篇表达“元宇宙已死”的文章近期在推特上引发热议&#xff0c;而游戏制作公司Epic Games CEO Tim Sweeney的还击更是让这个话题热上加热。 “搞一次在线守…

远程桌面基本原理

远程桌面基本原理 远程桌面是一种技术&#xff0c;它允许用户通过互联网或局域网远程访问另一台计算机的桌面。这种技术可以让用户在不同的地方使用同一台计算机&#xff0c;或者在同一地方使用不同的计算机。远程桌面技术在现代计算机应用中发挥着重要的作用&#xff0c;本文将…

数据结构(堆)

文章目录 一、概念二、堆的使用三、PriorityQueue 介绍3.1 PriorityQueue 的特性3.2 PriorityQueue 的方法3.3 集合框架中PriorityQueue的比较方式 四、堆的应用 一、概念 1.什么是优先级队列 队列是一种先进先出(FIFO)的数据结构&#xff0c;但有些情况下&#xff0c;操作的数…

发明专利公开 -- CSS动画精准实现时钟

上一篇【setTimeout不准时&#xff0c;CSS精准实现计时器功能】的博文&#xff0c;最后提到了通过 CSS 动画实现计时器的方式。 本文详情描述如何通过 CSS 完整实现时钟效果&#xff0c;这也是团队 21 年专利的一项内容&#xff08;专利公布号&#xff1a;CN114003087A&#x…

Agisoft Metashape 空三导入Photomod

Agisoft Metashape 空三导入Photomod 文章目录 Agisoft Metashape 空三导入Photomod前言一、Metashape空三成果导出1.1导出PAT-B空三格式1.2. 导出相机文件二、Photomod空三成果导入2.1导入PAT-B空三格式2.2导入相机文件前言 本文讲解将Agisoft Metashape的空三成果导入Photom…

【C++初阶】:类与对象(下)

类与对象 一.再谈构造函数1.初始化列表&#xff08;构造函数的一部分&#xff09;2.explicit关键字 二.static成员三.友元1.友元函数2.友元类 四.内部类五.匿名对象六.再次理解类与对象 一.再谈构造函数 1.初始化列表&#xff08;构造函数的一部分&#xff09; 我们可以直接在…

Java 版企业工程项目管理系统平台(三控:进度组织、质量安全、预算资金成本、二平台:招采、设计管理)

工程项目管理软件&#xff08;工程项目管理系统&#xff09;对建设工程项目管理组织建设、项目策划决策、规划设计、施工建设到竣工交付、总结评估、运维运营&#xff0c;全过程、全方位的对项目进行综合管理 工程项目各模块及其功能点清单 一、系统管理 1、数据字典&#…

揭开Facebook数据抓取的面纱,深入了解其运作机制

在互联网时代&#xff0c;数据是一切的基础。而社交媒体作为数据存储与传输的重要渠道&#xff0c;其数据价值不言而喻。 那么&#xff0c;Facebook数据抓取是如何进行的呢&#xff1f; 1.API接口 首先&#xff0c;我们需要了解一些基本的概念。Facebook的API&#xff08;Ap…

基于AT89C51单片机的温度检测报警设计

点击链接获取Keil源码与Project Backups仿真图&#xff1a; https://download.csdn.net/download/qq_64505944/87777752?spm1001.2014.3001.5503 源码获取 主要内容&#xff1a; 基于51单片机设计一个温度检测报警器&#xff0c;至少具有以下功能&#xff1a;温度的检测和超…

计网U+选择题知识点

第一章U 1.Internet 网络本质上属于&#xff08; 分组交换&#xff09;网络。 2.(网络层发送的是分组) 3.在 OSI 参考模型中,自下而上第一个提供端到端服务的是(传输层 )。 4.APRANET 5.三类大家很熟悉的网络是&#xff08;电信网络&#xff0c;有线电视网络&#xff0c;计算机…