【qt】标准型模型 下

标准型模型

一.前言

书接上回,我们已经实现了导入文件,添加行,插入行,删除行,接下来,我们开始实现接下来的功能。

二.预览数据

1.获取表头

cpp 复制代码
void MainWindow::on_actionSee_triggered()
{
    ui->plainTextEdit->clear();//把上次显示的清空
    QString str;
    for(int i=0;i<colCount;i++)
    {
        auto item=model->horizontalHeaderItem(i);//拿到表头的每项数据
        str+=item->text()+"\t\t";//将每项的内容加到字符串中
    }
    ui->plainTextEdit->appendPlainText(str);//添加到文本编辑器里
}

运行结果:

2.获取数据项

接下来就是拿到数据项了,表格类似于二维数组,所有我们可以用两次for循环来拿。

cpp 复制代码
for(int i=0;i<model->rowCount();i++)
    {
        str="";//每一行都从空字符串相加
        for(int j=0;j<colCount-1;j++)//最一列单独处理
        {
            auto item=model->item(i,j);
            str+=item->text()+"\t\t";
        }

        auto item=model->item(i,colCount-1);//最后一列
        if(item->checkState()==Qt::Checked)//根据是否勾选来选择
        {
            str+="是";
        }
        else
        {
            str+="否";
        }
        ui->plainTextEdit->appendPlainText(str);//会自动换行

    }

运行结果:

三.保存文件

1.文件对话框获取保存文件名

cpp 复制代码
//获取保存文件名
    QString fileName=QFileDialog::getSaveFileName(this,"保存文件",QCoreApplication::applicationDirPath());

防御性编程:

cpp 复制代码
if(fileName.isEmpty())//如果文件名为空,就直接返回
    {
        return;
    }

2.用文件名初始化文件对象

cpp 复制代码
 QFile qFile(fileName);

3.打开文件对象

用读写和文本和截断的方式打开,截断就是打开时里面有文件就清空

cpp 复制代码
 if(!qFile.open(QIODevice::ReadWrite|QIODevice::Text|QIODevice::Truncate))//通过打不开文件直接返回
    {
        return;
    }

4.用文件对象初始化文本流

cpp 复制代码
QTextStream stream(&qFile);

5.写入数据

其实就跟刚刚预览数据的时候一样,只是这里是往文件里面进行添加

cpp 复制代码
QString str;
    for(int i=0;i<colCount;i++)
    {
        auto item=model->horizontalHeaderItem(i);//拿到表头的每项数据
        str+=item->text()+"\t\t";//将每项的内容加到字符串中
    }
    stream<<str<<"\n";//写入文件中

    for(int i=0;i<model->rowCount();i++)
    {
        str="";//每一行都从空字符串相加
        for(int j=0;j<colCount-1;j++)//最一列单独处理
        {
            auto item=model->item(i,j);
            str+=item->text()+"\t\t";
        }

        auto item=model->item(i,colCount-1);
        if(item->checkState()==Qt::Checked)
        {
            str+="是";
        }
        else
        {
            str+="否";
        }
        stream<<str<<"\n";//写入文件中

运行结果保存的文:

四.格式

1.居右

默认单元格内容居左,所以我们先来实现居右的功能

cpp 复制代码
void MainWindow::on_actionRight_triggered()
{
    if(!selectionModel->hasSelection())//没有选择就直接退出
    {
        return;
    }
    auto indexs=selectionModel->selectedIndexes();//通过选择模型可以获取选择的多个单元格的模型索引
    for(int i=0;i<indexs.count();i++)
    {
        QStandardItem * item=model->itemFromIndex(indexs[i]);//通过模型索引获取项
        item->setTextAlignment(Qt::AlignVCenter|Qt::AlignRight);//设置文本对其方式为右对其,垂直居中
    }
}

注释我写的很详细我就不讲了,auto是我偷懒的写法,如果你们要写具体的类型可以点进函数看。

2.居中

同理,只是文本对齐参数不一样

cpp 复制代码
 void MainWindow::on_actionMiddle_triggered()
{
    if(!selectionModel->hasSelection())//没有选择就直接退出
    {
        return;
    }
    auto indexs=selectionModel->selectedIndexes();//通过选择模型可以获取选择的多个单元格的模型索引
    for(int i=0;i<indexs.count();i++)
    {
        QStandardItem * item=model->itemFromIndex(indexs[i]);//通过模型索引获取项
        item->setTextAlignment(Qt::AlignVCenter|Qt::AlignHCenter);//只是这里参数不一样
    }
}

运行结果:

3.居左

cpp 复制代码
void MainWindow::on_actionLeft_triggered()
{   
    if(!selectionModel->hasSelection())//没有选择就直接退出
    {
        return;
    }
    auto indexs=selectionModel->selectedIndexes();//通过选择模型可以获取选择的多个单元格的模型索引
    for(int i=0;i<indexs.count();i++)
    {
        QStandardItem * item=model->itemFromIndex(indexs[i]);//通过模型索引获取项
        item->setTextAlignment(Qt::AlignVCenter|Qt::AlignLeft);
    }
}

4.粗体

粗体action是复选框,用这个信号

cpp 复制代码
void MainWindow::on_actionBold_triggered(bool checked)
{
    if(!selectionModel->hasSelection())//没有选择就直接退出
    {
        return;
    }

    auto indexs=selectionModel->selectedIndexes();//通过选择模型可以获取选择的多个单元格的模型索引

    for(int i=0;i<indexs.count();i++)
    {
        QStandardItem * item=model->itemFromIndex(indexs[i]);//通过模型索引获取项
        QFont font=item->font();
        font.setBold(true);
        item->setFont(font);
    }
}

运行结果:

五.模型的信号

1.解决粗体action问题

但是现在有一个问题,那就是我点粗体action之后,他不会变化,当我选择另外一个单元格的时候,他还是一直选中的,明显不合理,我明明就没有粗体。

就像这样,不是粗体但是复选框也是打开的。

这个时候我们就需要动态的来控制粗体按钮的开与关了。

当我们选择另一个单元格的时候,选择模型就可以发出信号,所以我们来使用选择模型的信号。

因为模型不是ui界面所以只能我们手动关联,和写槽函数。

选信号可以到选择模型里面去找。

槽函数:

cpp 复制代码
void on_currentChanged(const QModelIndex &current, const QModelIndex &previous);

信号槽关联:

cpp 复制代码
connect(selectionModel,SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)),
            this,SLOT(on_currentChanged(const QModelIndex &, const QModelIndex &)));

槽函数的实现:

cpp 复制代码
void MainWindow::on_currentChanged(const QModelIndex &current, const QModelIndex &previous)
{
    if(current.isValid())//如果当前点击的单元格是有效的。
    {
        auto item=model->itemFromIndex(current);//通过当前模型索引获取单元格
        ui->actionBold->setChecked(item->font().bold());//如果是粗体就打开,不是就关闭
    }
}

就很nice可以去玩玩。

2.状态栏显示信息

cpp 复制代码
statusBar()->addWidget(labelInfo);//状态栏添加一个标签

还是在选择变化的槽函数里面

cpp 复制代码
void MainWindow::on_currentChanged(const QModelIndex &current, const QModelIndex &previous)
{
    if(current.isValid())//如果当前点击的单元格是有效的。
    {
        auto item=model->itemFromIndex(current);//通过当前模型索引获取单元格
        ui->actionBold->setChecked(item->font().bold());//如果是粗体就打开,不是就关闭
        
        labelInfo->setText(QString::asprintf("单元格信息:行:%d  列:%d",current.row(),current.column())+"  内容:"+item->text());
    }
}

运行结果:

六.总结

对于这些功能的处理,拿到item,可以通过行和列坐标,可以通过模型索引。对于上节的内容,我们主要是设置item。所以对于我们学过的东西一定要找相似点,要总结一下。

好了,标准项模型和选择模型就讲到这里了。

慌了,你就慢下来,还慌,你就停下来!

相关推荐
Biomamba生信基地2 分钟前
R语言基础| 功效分析
开发语言·python·r语言·医药
DARLING Zero two♡3 分钟前
【优选算法】Pointer-Slice:双指针的算法切片(下)
java·数据结构·c++·算法·leetcode
手可摘星河4 分钟前
php中 cli和cgi的区别
开发语言·php
虾球xz7 分钟前
游戏引擎学习第58天
学习·游戏引擎
CodeClimb17 分钟前
【华为OD-E卷-木板 100分(python、java、c++、js、c)】
java·javascript·c++·python·华为od
CT随28 分钟前
Redis内存碎片详解
java·开发语言
anlog37 分钟前
C#在自定义事件里传递数据
开发语言·c#·自定义事件
奶香臭豆腐1 小时前
C++ —— 模板类具体化
开发语言·c++·学习
不想当程序猿_1 小时前
【蓝桥杯每日一题】分糖果——DFS
c++·算法·蓝桥杯·深度优先
晚夜微雨问海棠呀1 小时前
长沙景区数据分析项目实现
开发语言·python·信息可视化