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

news2024/11/25 9:28:19

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博客

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

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

相关文章

【Redis】Redis位图(bitmap)介绍和在签到场景的应用

文章目录 一、前言二、redis位图相关指令setbit命令getbit命令bitcount命令bitfield命令bitpos命令bitop命令 三、应用场景累计签到应用场景连续签到应用场景日期签到场景应用详情 一、前言 基本原理&#xff1a; 《Redis设计与实现》中对位图的实现描述是&#xff1a;Redis使…

做软件测试我该如何快速摸清一家公司的基本情况?

当你准备进入一家新的公司作为软件测试人员时&#xff0c;了解公司的基本情况对于你快速适应新环境和工作非常重要。下面是几个方面可以帮助你快速摸清一家公司的基本情况&#xff1a; 如果你想学习软件测试&#xff0c;我这边给你推荐一套视频&#xff0c;这个视频可以说是B站…

8. 高性能业务表结构设计和索引知识深化

MySQL性能调优 1. 数据库表设计1.1 范式化设计1.1.1 什么是范式&#xff1f;1.1.2 第一范式&#xff08;1NF&#xff09;1.1.2 第二范式&#xff08;2NF&#xff09;1.1.3 第三范式&#xff08;3NF&#xff09; 1.2 反范式设计1.2.1 什么叫反范式化设计 1.3 范式化和反范式总结…

分析SpringBoot 底层机制【Tomcat 启动分析+Spring 容器初始化+Tomcat 如何关联Spring 容器之源码分析

目录 分析SpringBoot 底层机制【Tomcat 启动分析Spring 容器初始化Tomcat 如何关联Spring 容器之源码分析 搭建SpringBoot 底层机制开发环境 创建Maven 项目wyx-springboot 修改pom.xml , 导入相关依赖 创建MainApp.java 启动项目ok, 大家注意Tomcat 也启动了[这里思考, …

机器学习期末复习 BP神经网络的推导,4X4X3,激活函数变为Logistic函数,其他不变

刚写完了bp神经网络的实验课代码&#xff0c;对这个比较熟悉&#xff08;后面给出实现代码&#xff09; Logistic函数也就是sigmod函数&#xff0c;表达式是这样的&#xff1a; def sigmod(x):return 1/(1math.exp(-x)) sigmod函数是隐层和输出层的激活函数&#xff08;sigmo…

如何本地搭建Plex私人影音云盘教程,实现Plex家庭影音中心,打造超级多媒体中心

文章目录 1.前言2. Plex网站搭建2.1 Plex下载和安装2.2 Plex网页测试2.3 cpolar的安装和注册 3. 本地网页发布3.1 Cpolar云端设置3.2 Cpolar本地设置 4. 公网访问测试5. 结语 转发自CSDN远程穿透的文章&#xff1a;免费搭建Plex家庭影音中心 - 打造超级多媒体中心【公网远程访问…

WEBPACK、VITE 常用配置(对照)及迁移指南

文中 Webpack 版本为 5.x&#xff0c;Vite 版本为 4.3.x webpack 是新一代构建工具里面的老大哥了&#xff0c;从 2013 年发布已经持续升级 10 年&#xff0c;形成完备的生态环境。vite 则是下一代前端开发与构建工具&#xff0c;2019年发布&#xff0c;最新发布版本 4.3.3&…

文件操作安全之-文件上传告警运营篇

本文从文件上传的定义&#xff0c;文件上传的IDS规则&#xff0c;文件上传的示例&#xff0c;文件上传的告警研判&#xff0c;文件上传的处置建议等几个方面阐述如何通过文件上传类型的告警的线索&#xff0c;开展日常安全运营工作&#xff0c;从而挖掘有意义的安全事件。 文件…

rtl仿真器-iverilog icarus安装和测试

Icarus Verilog是一个轻量、免费、开源的Verilog编译器&#xff0c;基于C实现&#xff0c;开发者是 Stephen Williams &#xff0c;遵循 GNU GPL license 许可证&#xff0c;安装文件中已经包含 GTKWave支持Verilog/VHDL文件的编译和仿真&#xff0c;命令行操作方式&#xff0c…

C语言函数大全-- _w 开头的函数(1)

C语言函数大全 本篇介绍C语言函数大全-- _w 开头的函数 1. _waccess 1.1 函数说明 函数声明函数功能int _waccess(const wchar_t* path, int mode);用于测试文件或目录是否存在&#xff0c;并检查程序是否具有对它们的访问权限 参数&#xff1a; path &#xff1a; 待测试的…

Elasticsearch(三)

Elasticsearch(三) 数据聚合 聚合的分类 文档&#xff1a;https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations.html 聚合可以实现对文档数据的统计、分析、运算。聚合常见的有三类&#xff1a; 桶聚合&#xff1a;用来对文档做分组 Te…

【P22】JMeter 调试后置处理程序(Debug PostProcessor)

&#xff08;1&#xff09;、测试计划右键 <<< 添加 <<< 线程&#xff08;用户&#xff09;<<< 线程组 默认参数即可 &#xff08;2&#xff09;、线程组右键 <<< 添加 <<< 取样器 <<< 调试取样器 默认参数即可 &…

SQL复习(一)——安装

1 mysql卸载 reference&#xff1a;https://blog.csdn.net/m0_67392273/article/details/126066580 Step1:停止MySql服务 在卸载之前&#xff0c;先停止MySQL8.0的服务 搜索“服务”&#xff0c;找到“MySQL”&#xff0c;右键点击选择“停止” Step2&#xff1a;软件的卸…

Unittest自动化测试之unittestunittest_生成测试报告

unittest_生成测试报告 测试报告为测试结果的统计即展示&#xff0c;是自动化测试不可或缺的一部分&#xff0c;利用unittest 可以生成测试报告 方式一、使用第三方 HTMLTestRunner 执行测试用例集&#xff0c;生成网页版测试报告&#xff08;推荐&#xff09; HTMLTestRunn…

5年软测经验去面试25k测试岗,看到这样的面试题我还是心虚了....

我是着急忙慌的准备简历——5年软件测试经验&#xff0c;可独立测试大型产品项目&#xff0c;熟悉项目测试流程...薪资要求&#xff1f;5年测试经验起码能要个25K吧 我加班肝了一页半简历&#xff0c;投出去一周&#xff0c;面试电话倒是不少&#xff0c;自信满满去面试&#…

系统掌握入河排污口设置论证技术、方法及报告编制框架

在短时间内较系统的掌握入河排污口设置论证技术、方法及报告编制框架&#xff0c;学习内容以城镇生活污水厂、造纸项目、石化项目、制药项目案例为线索&#xff0c;系统讲解入河排污口设置论证报告书编制过程&#xff0c;并以水质模型为手段&#xff0c;讲解水质影响预测模型的…

Voice Control for ChatGPT 沉浸式的与ChatGPT进行交流学习。

Voice Control for ChatGPT 日常生活中&#xff0c;我们与亲人朋友沟通交流一般都是喜欢语音的形式来完成的&#xff0c;毕竟相对于文字来说语音就不会显的那么的苍白无力&#xff0c;同时最大的好处就是能解放我们的双手吧&#xff0c;能更快实现两者间的对话&#xff0c;沟通…

华为OD机试真题 Java 实现【简单的自动曝光】【2023Q1 100分】

一、题目描述 一个图像有 n 个像素点&#xff0c;存储在一个长度为 n 的数组 img 里&#xff0c;每个像素点的取值范围[0,255]的正整数。 请你给图像每个像素点值加上一个整k(可以是负数)&#xff0c;得到新图 newlmg&#xff0c;使得新图 newlmg 的所有像素平均值最接近中位…

响应式设计和移动端优化:如何实现页面在不同设备上的适配和优化

章节一&#xff1a;介绍响应式设计和移动端优化 响应式设计是一种使网页能够自适应不同设备和屏幕尺寸的设计方法。它通过使用流式网格布局、媒体查询和弹性图片等技术&#xff0c;使得网页能够在不同分辨率和设备上呈现出最佳的布局和用户体验。 移动端优化则是针对移动设备…