当前位置: 首页 > news >正文

继续记事本项目

前言:我们以记事本项目引入,期间为完成项目,介绍了许多Qt编程常用方法,本篇我们继续回来完成一个基本的记事本项目。

打开文件

打开开始创建的记事本项目,右键“打开”按钮,点击“转到槽”

void Widget::on_Bopen_clicked()
{QString fileName = QFileDialog::getOpenFileName(this,tr("Open File"),"D:/codefile/Qt code",tr("Text(*.txt)"));       //打开文件选择框并获取选择文件的文件名ui->textEdit->clear();                   //每次选择文件后就将文本控件内容清空,便于下次书写QFile file(fileName);                    //创建QFIle对象if(!file.open(QIODevice::ReadOnly|QIODevice::Text)){          //打开文件qDebug()<<"file open error.";}QTextStream in(&file);in.setCodec("UTF-8");                    //设置字符编码while(!in.atEnd()){QString context=in.readLine();ui->textEdit->append(context);       //以追加的方式添加textEdit的内容}file.close();                            //关闭文件
}

点击“打开”,选择文件后(我选择了text1),文本框能成功显示读取到的内容

保存文件

右键“保存”按钮,点击“转到槽”

void Widget::on_Bsave_clicked()
{QString fileName = QFileDialog::getSaveFileName(this,tr("Save File"),"D:/codefile/Qt code",tr("Text(*.txt *.doc)"));   //打开文件选择框,保存文件QFile file(fileName);                    //创建QFile对象if(!file.open(QIODevice::WriteOnly|QIODevice::Text)){          //打开文件qDebug()<<"file open error.";}QTextStream out(&file);out.setCodec("UTF-8");                            //设置字符编码QString context = ui->textEdit->toPlainText();    //获取控件textEdit上的内容,返回字符串类型out<<context;                                     //将字符串输出到文件file.close();
}

在文本框输入文本

点击“保存”,保存文件(我自定义的文件名为chinese)

后打开文件,查看内容,内容成功载入

通过点击“打开”文件,也能成功加载内容

实现关闭按钮

更符合现实记事本的情况,我们应该把Qfile对象声明为类的公有成员,不是实现一次操作后就自动关闭文件,可以对同一文件进行多次操作,点击“关闭”按钮后再关闭

打开“.h”文件,将file对象声明为公有成员

将之前QFile对象的创建语句改为文件命名语句,同时去掉文件关闭操作

file.setFileName(fileName);

代码示例

void Widget::on_Bclose_clicked()
{ui->textEdit->clear();                         //将文本框上的内容清空if(file.isOpen()){                             //如果文件是打开状态file.close();                              //关闭文件}
}

此时我们打开文件和关闭文件可以正常衔接了

再说编码

在之前的操作中,我们都直接使用QTextStream的setCodec(“UTF-8”)直接写死文件的编码和解码数据类型,但在实际的操作过程中,打开文件和保存文件时,我们应可以自己选择编码类型。

QComboBox是Qt中用于创建下拉列表的控件,并提供了一系列方法来添加、删除和修改列表中的项。

将之前的Label“UTF-8”删掉,添加一个“Combo Box”(在左侧)

双击box,点击左下角的“+”号,输入想要添加的编码格式

完成后点击“OK”

在“widget.cpp”文件中使用connect函数获得选择的编码, 信号为currentIndexChanged(int index)检测当前选择的索引

在.h头文件中声明槽

在.cpp中完成槽实现,槽需要实现什么功能呢?

在打开文件时,我们可以点击组合框选择编码,那此时的编码设置可以在打开文件的槽中设定

void Widget::on_Bopen_clicked()
{QString fileName = QFileDialog::getOpenFileName(this,tr("Open File"),"D:/codefile/Qt code",tr("Text(*.txt)"));       //打开文件选择框并获取选择文件的文件名ui->textEdit->clear();                   //每次选择文件后就将文本控件内容清空,便于下次书写file.setFileName(fileName);              //设置文件名if(!file.open(QIODevice::ReadOnly|QIODevice::Text)){          //打开文件qDebug()<<"file open error.";}QTextStream in(&file);in.setCodec(ui->comboBox->currentText().toStdString().c_str());                    //设置字符编码(获取字符编码,先转为c++类型的字符串再转为char*型)while(!in.atEnd()){QString context=in.readLine();ui->textEdit->append(context);       //以追加的方式添加textEdit的内容}
}

此时我们已经能根据自己选择的编码格式打开文件了,那选择框槽干什么呢?

如果我们在打开文件时已经选择了用一种编码,打开后想更换编码,并在更换后就能更新文本再次查看,就需要通过槽函数来实现了

void Widget::oncurrentIndex(int index)
{ui->textEdit->clear();                          //清空文本框if(file.isOpen()){QTextStream in(&file);in.setCodec(ui->comboBox->currentText().toStdString().c_str());         //设置编码file.seek(0);                               //让光标回到起始位置(第一次使用while读取后光标到了文末)while(!in.atEnd()){QString context=in.readLine();         //按行读取文件ui->textEdit->append(context);         //以追加的方式添加textEdit的内容}}
}

光标行列值显示

窗口捕捉textEdit的光标改变信号cursorPositionChanged()

connect(ui->textEdit,SIGNAL(cursorPositionChanged()),this,SLOT(oncursorPosition()));

并在头文件声明槽函数

在.cpp文件添加实现

void Widget::oncursorPosition()
{QTextCursor cursor=ui->textEdit->textCursor();          //获取光标对象QString index=QString::number(cursor.blockNumber()+1);  //获取行号QString column=QString::number(cursor.columnNumber()+1);//列号const QString lPos="第"+index+"行,"+"第"+column+"列   ";ui->Lpos->setText(lPos);                                //设置Lpos显示文本
}

运行代码,可以看到,随着光标移动,右小角的标签显示也改变了

添加打开文件提示

打开文件时,若文件正常打开,设置窗口标题为文件名,显示打开的文件,交互性更好

保存文件后,也算是打开了这个文件,也可以设置标题为文件名

关闭文件后,初始化窗口标题

同时,在.ui文件中,初始化widget的windowTitle为记事本

这样就能让用户知道当下修改的是哪个文件

设置当前行高亮

QTextEdit::ExtraSelection是QTextEdit中用来表示额外的文本选择和高亮的结构,包含了QTextCursor和QTextCharFormat两个成员,QTextCursor表示在文本中的一个位置或区间,QTextCharFormat用于定于这个区间的格式(颜色背景、字体等)

我们应该在获取光标位置的槽函数中编辑代码,这样才能对当前行进行操作

QList

QList是Qt中的一个容器类,内部的实现类似于动态数组,但也提供了一些链表的特性,方便快速添加、删除元素

“CTRL+键盘左键”

“CTRL+键盘左键”点击“yellow”可以查看它声明的头文件位置,可以知道空间中可以使用的颜色有哪些

完善保存逻辑

我们之前的代码是,点击“保存”按钮后就跳出文件选择框,命名保存文件。但如果我们是编辑一个文件后再保存文件,则不需要弹出文件选择框重新创建文件

void Widget::on_Bsave_clicked()
{if(!file.isOpen()){QString fileName = QFileDialog::getSaveFileName(this,tr("Save File"),"D:/codefile/Qt code",tr("Text(*.txt *.doc)"));   //打开文件选择框,保存文件file.setFileName(fileName);              //设置文件名if(!file.open(QIODevice::WriteOnly|QIODevice::Text)){          //打开文件qDebug()<<"file open error.";}this->setWindowTitle(fileName+"-记事本");}QTextStream out(&file);out.setCodec(ui->comboBox->currentText().toStdString().c_str());                            //设置字符编码QString context = ui->textEdit->toPlainText();    //获取控件textEdit上的内容,返回字符串类型out<<context;                                     //将字符串输出到文件
}

并且修改打开文件的方式,修改为可读可写

优化关闭按钮

在点击“关闭”按钮后,我们可以再次询问是否要保存文件,防止误触

在Qt中弹窗一般用QMessageBox这个类创建弹窗

void Widget::on_Bclose_clicked()
{int ret = QMessageBox::warning(this,tr("My notice"),tr("The document has been modified.\n""Do you want to save your changes?"),QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);             //弹窗switch(ret){case QMessageBox::Save:                  //保存on_Bsave_clicked();break;case QMessageBox::Discard:               //丢弃ui->textEdit->clear();                         //将文本框上的内容清空if(file.isOpen()){                             //如果文件是打开状态this->setWindowTitle("记事本");file.close();                              //关闭文件}break;case QMessageBox::Cancel:                //取消break;default:break;}
}
http://www.lryc.cn/news/627004.html

相关文章:

  • 盲盒商城h5源码搭建可二开幸运盲盒回收转增定制开发教程
  • Hyperledger Fabric官方中文教程-改进笔记(十三)-使用测试网络创建通道
  • Google Chrome 扩展不受信任 - 不受支持的清单版本 解决方案
  • 整体设计 之定稿 “凝聚式中心点”原型 --整除:智能合约和DBMS的在表层挂接 能/所 依据的深层套接
  • AR 虚实叠加技术在工业设备运维中的实现流程方案
  • 云原生环境下的ITSM新趋势:从传统运维到智能化服务管理
  • MySQL 50 道经典练习题及答案
  • YOLOv8n-pose 模型使用
  • 学习中需不需要划线、做笔记
  • LLM常见名词记录
  • 【0基础PS】图片格式
  • 奇怪的“bug”--数据库的“隐式转换”行为
  • 深入解析:生产环境 SQL 数据库的架构设计与工程实践
  • 【clion】visual studio的sln转cmakelist并使用clion构建32位
  • 深入理解MySQL Ⅳ -- SQL性能分析工具
  • 欧州服务器String 转 double 有BUG?
  • skyworking 8.9.X 安装配置
  • 云原生俱乐部-RH294知识点归纳(1)
  • 【ElasticSearch实用篇-03】QueryDsl高阶用法以及缓存机制
  • 服务器硬件电路设计之 SPI 问答(二):SPI 与 I2C 的特性博弈及多从机设计之道
  • lesson43:Python操作MongoDB数据库完全指南
  • Eclipse 里Mybatis的xml的头部报错
  • ubuntu privileged cont 一直在读取硬盘
  • 超长视频生成新突破!LongVie框架问世,创作不再受时长限制
  • B站 XMCVE Pwn入门课程学习笔记(7)
  • postman+newman+jenkins接口自动化
  • 【数据结构】排序算法全解析:概念与接口
  • 34-处理https 安全问题或者非信任站点-下
  • TheadLocal相关
  • DOLO 或成 Berachain 生态迎新一轮爆发的信号?