【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。所以对于我们学过的东西一定要找相似点,要总结一下。

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

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

相关推荐
翔云API2 分钟前
身份证识别接口的应用场景和作用
运维·服务器·开发语言·自动化·ocr
张望远-长风万里5 分钟前
运维监控专项学习笔记-id:0-需求场景、监控作用、监控能力
运维·笔记·学习
jun7788957 分钟前
机器学习-监督学习:朴素贝叶斯分类器
人工智能·学习·机器学习
学java的小菜鸟啊16 分钟前
第五章 网络编程 TCP/UDP/Socket
java·开发语言·网络·数据结构·网络协议·tcp/ip·udp
我爱吃福鼎肉片19 分钟前
【C++】——list
c++·vector·list
立黄昏粥可温20 分钟前
Python 从入门到实战22(类的定义、使用)
开发语言·python
PerfMan23 分钟前
基于eBPF的procstat软件追踪程序垃圾回收(GC)事件
linux·开发语言·gc·ebpf·垃圾回收·procstat
程序猿 董班长31 分钟前
socket学习
学习
聆听HJ31 分钟前
java 解析excel
java·开发语言·excel
kgduu34 分钟前
Qt之QFuture理解
qt