QT QtableView操作详解

本文实现了使用QtableView控件来显示数据,数据源使用txt文本作为数据源,使用了QStandardItemModel作为数据模型来实现了对TableView空间的初始化,和对txt数据源的增删改查功能。

QT QtableView操作详解目录

1. 项目结构&软件界面

2. mainwindow.h文件

3. 构造函数

4. 打开文件

5. 实现监听事件

6. 初始化QtableView控件

7. 实现修改功能

8. 实现添加功能

9. 实现删除功能

10. 功能演示

雷总看了都说Nice的文章,看完记得点关注哈~


1. 项目结构&软件界面

2. mainwindow.h文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QStandardItemModel>
#include <QDebug>
#include <QFile>
#include <QMessageBox>
#include <QModelIndex>
#include <QFileDialog>
#include <functional>
#include <QItemSelectionModel>
//引入头文件
#include "mythread.h"

//加入GBK申明,否则中文乱码 全局使用GBK文件操作因为有中文所以使用utf-8
#pragma execution_character_set("gbk")
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

    void ioDemo();    //初始化 删除修改添加之后也会调用初始化函数
    void deleteOnelineInFile(int nNumLine, QString &filename); //删除函数
    void DeleteOneline(int nNum, QString &strall);             //删除函数


    QLabel *LabCurFile;    //当前文件
    QLabel *LabCellPos;    //当前单元格行列号
    QLabel *LabCellText; //当前单元格内容
    /* 创建数据模型 */
    QStandardItemModel* model = new QStandardItemModel();
    QItemSelectionModel *theSelection; //选择模型

private slots:
    void on_tableView_activated(const QModelIndex &index);

    void on_pushButton_clicked();

    void on_pushButton_2_clicked();

    void on_pushButton_3_clicked();

    void on_pushButton_4_clicked();

    void on_Button_File_clicked();

    //当前选择单元格发生变化
    void on_currentChanged(const QModelIndex &current, const QModelIndex &previous);

    void OnlineTreeViewDoubleClick(const QModelIndex & index);

private:
    Ui::MainWindow *ui;

    //初始化
    mythread * thread;

    //update的行
    QString strUpItem="";
};
#endif // MAINWINDOW_H

3. 构造函数

    ui->setupUi(this);

    //构造函数
    thread = new mythread;  //分配空间
    //关联信号获取结束线程信号
    connect(thread, &mythread::isDone, this, &MainWindow::addSave);

    ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);//不可编辑
    //ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);//设置选中模式为选中行
    //ui->tableView->setSelectionMode( QAbstractItemView::SingleSelection);//设置选中单个
    //QTableWidget类似

4. 打开文件

void MainWindow::on_Button_File_clicked()
{
    /*
    //Button_File
    //定义文件对话框类
    QFileDialog *fileDialog = new QFileDialog(this);
    //定义文件对话框标题
    fileDialog->setWindowTitle(QStringLiteral("选中文件"));
    //设置默认文件路径
    fileDialog->setDirectory(".");
    //设置文件过滤器
    fileDialog->setNameFilter(tr("File(*.*)"));
    //设置可以选择多个文件,默认为只能选择一个文件QFileDialog::ExistingFiles
    fileDialog->setFileMode(QFileDialog::ExistingFiles);
    //设置视图模式
    fileDialog->setViewMode(QFileDialog::Detail);
    //打印所有选择的文件的路径
    QStringList fileNames;
    if (fileDialog->exec()) {
        fileNames = fileDialog->selectedFiles();
        qDebug()<<fileNames;
    }
    */
    //QFile writeFile("E:/QT/Creator/QT_MySQL/aa.txt");	//PATH是自定义写文件的地址

    QString fileName = QFileDialog::getOpenFileName(this,"文件对话框!",".","Text files (*.txt);;Any files (*)");
    ui->lineEdit_5->setText(fileName);

    //QString fileName = QFileDialog::getExistingDirectory(NULL,"caption",".");
    //ui->lineEdit_5->setText(fileName);
    //6. 初始化QtableView控件
    ioDemo();
}

5. 实现监听事件

    监听鼠标点击单元格事件,用来在删除操作或者修改操作的时候获取选中的单元格进行操作。

    第一个if是用来获取某一个单元格的X Y位置以及对应的Value值。

    for 中的 3对应着 tableview的列,因为本文数据源有三列所以就直接写死了,后期需要可以设置两个全局变量代替。

    最上方注释的代码是原型代码。

void MainWindow::on_currentChanged(const QModelIndex &current, const QModelIndex &previous)
{
    /*
	//原型代码
    //选择单元格变化时的响应
    if (current.isValid())
    {
        LabCellPos->setText (QString::asprintf ("当前单元格:%d 行,%d 列", current.row(),current.column()));
        QStandardItem* aItem=theModel->itemFromIndex(current);
        this->LabCellText->setText ("单元格内容:"+aItem->text());
        QFont font=aItem->font();
        ui->actFontBold->setChecked(font.bold());
    }
    */
    if (current.isValid())
    {
        //LabCellPos->setText (QString::asprintf ("当前单元格:%d 行,%d 列", current.row(),current.column()));
        qDebug()<<"当前单元格:";
        qDebug()<<QString::number(current.row())<<" 行,";
        //qDebug()<<QString::number(current.column())<<" 列";
        QStandardItem* aItem=model->itemFromIndex(current);
        //this->LabCellText->setText ("单元格内容:"+aItem->text());
        qDebug()<<"单元格内容:"<<aItem->text();
        QFont font=aItem->font();
        qDebug()<<font.bold();
        //ui->actFontBold->setChecked(font.bold());
    }
    strUpItem="";
    for(int i=0;i<3;i++){
        QModelIndex rootIndex = ui->tableView->model()->index(current.row(), i);//最顶层item的index
        QStandardItem* aItem=model->itemFromIndex(rootIndex);
        qDebug()<<"2.单元格内容:"<<aItem->text();
        strUpItem += aItem->text();
    }
	qDebug()<<"2.单元格所选内容:" << strUpItem;
	/*
	strUpItem="";
	for(int i=0;i<3;i++){
		QModelIndex rootIndex = ui->tableView->model()->index(-1, i);//最顶层item的index
		QStandardItem* aItem=model->itemFromIndex(rootIndex);
		qDebug()<<"3.单元格内容:"<<aItem->text();
		strUpItem += aItem->text();
	}
	qDebug()<<"3.单元格所选内容:" << strUpItem;
	*/
}

6. 初始化QtableView控件

    QAbstractItemView参考:Qt QStandardItemModel(1.超级详细用法)_双子座断点的博客-CSDN博客_qstandardmodel
    QAbstractItemView查找函数参考:Qt QStandardItemModel(2.超级详细函数)_双子座断点的博客-CSDN博客_qstandarditemmodel点击事件

    修改样式参考:https://blog.csdn.net/QIJINGBO123/article/details/84186352

    这块因为编码的问题所以全局默认bgk,在进行File文件操作的时候使用的是utf-8格式避免乱码。

    下方数据模型设置部分需要添加函数可以点击QAbstractItemView查找函数进行参考查看

//初始化view
void MainWindow::ioDemo()
{

    QFile file(ui->lineEdit_5->text());
    ui->tableView->setModel(model);

    /* 设置表格标题行(输入数据为QStringList类型) */
    model->setHorizontalHeaderLabels({"学号", "姓名", "考试题目"});

    /* 自适应所有列,让它布满空间 */
    ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);

    if(! file.open(QIODevice::ReadOnly|QIODevice::Text))
        qDebug()<<file.errorString();
    else
         qDebug()<<"openok";
    file.seek(0);


    QTextStream shuru(&file);
    shuru.setCodec("utf-8"); // 设置文件的编码格式为utf-8
    int ioInt=0;
    QString strID,strName,School;

    while(! shuru.atEnd())
    {
        QString line=shuru.readLine();
        qDebug()<<line;

        model->setItem(ioInt, 0, new QStandardItem(line.left(1)));
        model->setItem(ioInt, 1, new QStandardItem(line.mid(1,3)));
        model->setItem(ioInt, 2, new QStandardItem(line.mid(4,8)));
        ioInt++;
    }
    /* 设置表格视图数据 */
    ui->tableView->setModel(model);

    /* 显示 */
    ui->tableView->show();

    file.close();

    //数据模型
    theSelection = new QItemSelectionModel (model) ;//选择模型
    connect(theSelection,SIGNAL(currentChanged(QModelIndex,QModelIndex)), this,SLOT(on_currentChanged(QModelIndex,QModelIndex)));
    ui->tableView->setSelectionModel(theSelection); //设置选择模型
    ui->tableView->setSelectionMode(QAbstractItemView::ExtendedSelection);
    //ui->tableView->setSelectionBehavior(QAbstractItemView::SelectItems);
    ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);//设置选中模式为选中行
    ui->tableView->setSelectionMode ( QAbstractItemView::SingleSelection);//禁止选择多行

}

7. 实现修改功能

    在修改&添加&删除操作过程中需要小心 ‘\n’ 换行符,因为如果修改完数据多添加一个换行符会导致下次的操作行数+2。

    如果进行删除操作的话,删除会导致数据删除换行符还有存留。

    添加操作的话可能会导致添加完后再次添加可能会添加至下下行。

//修改某一行代码
void MainWindow::on_pushButton_3_clicked()
{
        QString strAll;
        QStringList strList;
        QFile readFile(ui->lineEdit_5->text());
        if(readFile.open((QIODevice::ReadOnly|QIODevice::Text)))
        {
            //把文件所有信息读出来
            QTextStream stream(&readFile);
            stream.setCodec("utf-8"); // 设置文件的编码格式为utf-8
            strAll=stream.readAll();
        }
        readFile.close();
        QFile writeFile(ui->lineEdit_5->text());
        if(writeFile.open(QIODevice::WriteOnly|QIODevice::Text))
        {
                QTextStream stream(&writeFile);
                stream.setCodec("utf-8"); // 设置文件的编码格式为utf-8
                strList=strAll.split("\n");           //以换行符为基准分割文本
                for(int i=0;i<strList.count();i++)    //遍历每一行
                {
                    //strUpItem 全局变量,在鼠标选中行后自动获取value
                    if(strList.at(i).contains(strUpItem))
                    {
                        if(i==strList.count()-1){
                            QString tempStr=strList.at(i);
                            tempStr.replace(0,tempStr.length(),ui->lineEdit_4->text());   //"Hello!"是要替换的内容
                            stream<<tempStr<<'\n';
                        }
                        else{
                            QString tempStr=strList.at(i);
                            tempStr.replace(0,tempStr.length(),ui->lineEdit_4->text());   //"Hello!"是要替换的内容
                            stream<<tempStr<<'\n';
                        }
                    }
                    //如果没有找到要替换的内容,照常写入
                    else
                    {
                        if(i==strList.count()-1)
                        {
                           stream<<strList.at(i);
                        }
                        else
                        {
                           stream<<strList.at(i)<<'\n';//添加<<'\n'换行
                        }
                    }
                }
        }
        writeFile.close();
        ioDemo();
}

8. 实现添加功能

void MainWindow::on_pushButton_clicked()
{
    QFile file(ui->lineEdit_5->text());
    QString n1;
       if (file.open(QIODevice::ReadWrite | QIODevice::Append))
       {
           QTextStream txtOutput(&file);
           txtOutput.setCodec("utf-8"); // 设置文件的编码格式为utf-8
           n1="\n"+ui->lineEdit->text()+" "+ui->lineEdit_2->text()+" "+ui->lineEdit_3->text();
           txtOutput << n1 << endl;
           file.close();
       }
    file.close();
    ioDemo();
}

9. 实现删除功能

//删除某一行数据
void MainWindow::on_pushButton_2_clicked()
{
    QString str=ui->lineEdit_5->text();
    deleteOnelineInFile(ui->tableView->currentIndex().row(),str);
    //重新初始化视图
    ioDemo();

    //删除多行
    /*
        出自https://blog.csdn.net/qq_40450386/article/details/82904934
        QItemSelectionModel *model_selection = ui->tableView->selectionModel();
        QModelIndexList IndexList= model_selection->selectedIndexes();
        QMap<int,int>rowMap;
        foreach (QModelIndex index, IndexList)
        {
            //处理略  ...  可以读取、修改其内容;
        }
        上面代码中QModelIndexList记录的是所有选中的item的index,而不是行的index,不管你的选中模式是行还是item;
        如果想对整行处理的话,需要避免对同一行多次操作;比如可以index.column()==0时进行操作处理;
        如果删除选中的多行,更需要当心进坑!model.removeRow(row)之后,之后的行号就变了(减少1),可不幸的是,选中记录里的行号没有变化,还是原来的行号,再进行删除就删错行了。(比如,要删除2,4行,删了第2行后,原来的第4行变成了第3行,可是你删除的还是记录里的第4行!)所以删除多个行时,要从后往前删除,先删除行号大的,对小的没影响。
        可以用Qmap记录删除的行,因为他是排序的,省去麻烦
        删除多行完整代码如下:
        QItemSelectionModel *model_selection = ui->tableView->selectionModel();
        QModelIndexList IndexList= model_selection->selectedIndexes();
        QMap<int,int>rowMap;
        foreach (QModelIndex index, IndexList)
        {
            if(! index.isValid()) return;
            if(index.column()!=0) continue;
            rowMap.insert(index.row(),0);
        }

        QMapIterator<int,int> Iterator(rowMap);
        Iterator.toBack();
        while(rowMapIterator.hasPrevious())
        {
            rowMapIterator.previous();
            int rowm=rowMapIterator.key();
            qDebug()<<"del row..."<<rowm;
            file_model->removeRow(rowm);
        }
    */
}


void MainWindow::deleteOnelineInFile(int nNumLine, QString &filename)
{
    //删除model中的一行视图数据
    model->removeRow(nNumLine);
    QString strall;
    QFile readfile(filename);
    if(readfile.open(QIODevice::ReadOnly))
    {
        QTextStream stream(&readfile);
        strall=stream.readAll();
    }
    readfile.close();
    DeleteOneline(nNumLine, strall);

    //删除File文件内的某一行数据
    QFile writefile(ui->lineEdit_5->text());
    if(writefile.open(QIODevice::WriteOnly))
    {
        QTextStream wrtstream(&writefile);
        // --\n
        wrtstream << strall;
    }
    writefile.close();
}

void MainWindow::DeleteOneline(int nNum, QString &strall)
{
    int nLine=0;
    int Index=0;
    //算出行数nLine
    while(Index!=-1)
    {
        Index=strall.indexOf('\n',Index+1);
        nLine++;
    }

    //如果是直接从位置0开始删除\n算一个字符"abc\nme\ndo" \n的index是3要删除3+1个字符,即index+1个
    if(nNum==0)
    {
        int nIndex=strall.indexOf('\n');
        strall.remove(0,nIndex+1);
    }
    else
    {
        int nTemp=nNum;
        int nIndex=0,nIndex2=0;
        while(nTemp--)
        {
            //
            nIndex=strall.indexOf('\n',nIndex+1);//这里会更新nIndex
            if(nIndex!=-1)//说明是有效的
            {
                nIndex2=strall.indexOf('\n',nIndex+1);
            }
        }
        //删除的行不是最后一行(从nIndex+1这个位置起nIndex2-nIndex个字符全部抹去)
        if(nNum<nLine-1)
        {
            strall.remove(nIndex+1, nIndex2-nIndex);//不用减一
        }
        //删除的是最后一行(从nIndex起始len-nIndex个字符全抹去)
        //不能从nIndex+1处开始,
        else if(nNum==nLine-1)
        {
            int len=strall.length();
            strall.remove(nIndex,len-nIndex);
        }
        else
        {

        }

    }
}

10. 功能演示

本文代码就不放出来了,自己加油加油照着做就可以做出来了。

本文借鉴参考: Qt QStandardItemModel用法(超级详细),其它博客就别瞎看了,参考作者的文章和C语言网的这篇文章是最正确的。

雷总看了都说Nice的文章,看完记得点关注哈~

 其它文章 :

QT TextEdit控件_双子座断点的博客-CSDN博客_qt textedit

QT QComboBox使用详解_双子座断点的博客-CSDN博客

QT QtableView操作详解_双子座断点的博客-CSDN博客_qtableview增删改查

Qt QStandardItemModel(1.超级详细用法)_双子座断点的博客-CSDN博客_qstandardmodel

Qt QStandardItemModel(2.超级详细函数)_双子座断点的博客-CSDN博客_qstandarditemmodel点击事件

QT QRadioButton使用详解_双子座断点的博客-CSDN博客_qt radiobutton

QT QLineEdit使用详解_双子座断点的博客-CSDN博客_qt qlineedit

Qt QMessageBox使用详解_双子座断点的博客-CSDN博客_qt message

QChart折线图、饼状图、条形图、曲线图_双子座断点的博客-CSDN博客_qchart样式

QChart属性详解_双子座断点的博客-CSDN博客_setanimationoptions

QCharts QValueAxis使用_双子座断点的博客-CSDN博客_qvalueaxis

Qt 5 等待提示框(开源 动态图)_双子座断点的博客-CSDN博客_qt 等待对话框

QtDataVisualization 数据3D可视化_双子座断点的博客-CSDN博客_qtdatavisualization

QT QLabel控件(使用详解)_双子座断点的博客-CSDN博客_qt label

`QTableView` 是 Qt 框架中的一个控件,用于显示表格数据。它是一个基于 `QAbstractItemView` 的控件,可以通过设置不同的样式来实现不同的表格外观。下面是一些常用的 `QTableView` 样式: 1. 设置表格行高和列宽: ```python # 设置表格行高 tableView.verticalHeader().setDefaultSectionSize(30) # 设置表格列宽 tableView.horizontalHeader().setDefaultSectionSize(100) ``` 2. 设置表格网格线和表头样式: ```python # 显示表格网格线 tableView.setShowGrid(True) # 设置网格线样式 tableView.setGridStyle(QtCore.Qt.SolidLine) # 设置表头样式 tableView.horizontalHeader().setStyleSheet("QHeaderView::section {background-color: rgba(0, 0, 0, 0.7); color: white;}") ``` 3. 设置表格背景颜色和字体样式: ```python # 设置表格背景颜色 tableView.setStyleSheet("background-color: white;") # 设置字体样式 font = QtGui.QFont() font.setPointSize(12) tableView.setFont(font) ``` 4. 设置表格单元格的对齐方式: ```python # 设置单元格中文本的对齐方式 tableView.horizontalHeader().setDefaultAlignment(QtCore.Qt.AlignLeft) tableView.verticalHeader().setDefaultAlignment(QtCore.Qt.AlignVCenter) ``` 5. 设置表格的选择模式和编辑模式: ```python # 设置选择模式为单选 tableView.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection) # 设置编辑模式为双击编辑 tableView.setEditTriggers(QtWidgets.QAbstractItemView.DoubleClicked) ``` 这些是一些基本的 `QTableView` 样式,可以根据需要进行调整和扩展。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

双子座断点

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值