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

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

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

相关推荐
夜夜敲码6 分钟前
C语言教程(十六): C 语言字符串详解
c语言·开发语言
cooldream20097 分钟前
深入理解MVP架构:让UI层与业务逻辑完美分离的设计模式
ui·设计模式·架构·系统架构师
帅云毅7 分钟前
Web3.0的认知补充(去中心化)
笔记·学习·web3·去中心化·区块链
豆豆8 分钟前
day32 学习笔记
图像处理·笔记·opencv·学习·计算机视觉
拖孩10 分钟前
【Nova UI】十一、组件库中 Icon 组件的测试、使用与全局注册全攻略
前端·javascript·vue.js·ui·sass
宋康12 分钟前
C语言结构体和union内存对齐
c语言·开发语言
꧁坚持很酷꧂18 分钟前
Linux Ubuntu18.04下安装Qt Craeator 5.12.9(图文详解)
linux·运维·qt
居然是阿宋22 分钟前
Kotlin高阶函数 vs Lambda表达式:关键区别与协作关系
android·开发语言·kotlin
nenchoumi311929 分钟前
VLA 论文精读(十六)FP3: A 3D Foundation Policy for Robotic Manipulation
论文阅读·人工智能·笔记·学习·vln
ChoSeitaku32 分钟前
17.QT-Qt窗口-工具栏|状态栏|浮动窗口|设置停靠位置|设置浮动属性|设置移动属性|拉伸系数|添加控件(C++)
c++·qt·命令模式