文件操作介绍
目前的很多应用程序都需要具备操作文件的能力,包括对文件内容进行读/写、创建和保存新文件等,甚至某些应用程序的诞生纯粹是为了操作文件,比如 WPS Office、PDFedit 等。为此,Qt 框架提供了 QFile 类专门用来操作文件。
对此我制作了一款简易的记事本程序,目的只在于学习和了解QT的文件操作的相关知识,设计如下所示:
如上图所示,文件的子菜单还有文件的新建、打开、另存为等三项功能,下面我会对这三个功能如何在Qt上实现进行详解。
在UI设计界面,相关的子菜单有与之对应的对象相对应,以便于在代码中与ui界面中的相关控件和指令相连接。
新建文件
新建文件的相关功能,不过多介绍,直接上代码
void MainWindow::newActionSlot()
{
ui->textEdit->clear();//清楚textEdit中的内容
this->setWindowTitle("新建文本文档.txt");//
}
如代码所示,新建文件时的显示框为空白,所以需要对textEdit控件上的内容进行清楚。
然后新建文件时,需要对界面标题有所显示, setWindowTitle函数即是用来设置窗口上的标题显示,如下所示:
注:因为在UI界面中,文件菜单的各种操作无法通过右击转到槽函数建立连接,需要connect函数手动建立连接,如下所示:
connect(ui->newAction,&QAction::triggered,this,&MainWindow::newActionSlot);
打开文件
废话不多说,直接上代码
void MainWindow::openActionSlot()
{
QString filename = QFileDialog::getOpenFileName(this,"选择一个文件",QCoreApplication::applicationFilePath(),"*.cpp");//选中文件之后,返回一个路径字符
if(filename.isEmpty())
{
QMessageBox::warning(this,"警告","请选择一个文件");
}
else
{
//qDebug() <<filename;//选择文件之后
QFile file(filename);//创建文件对象
file.open(QIODevice::ReadOnly);//打开文件
QByteArray ba = file.readAll();//读取文件
ui->textEdit->setText(QString(ba));//文件内容显示在textEdit控件框
}
}
QFileDialog
QFileDialog 提供了一个文件对话框, 作用是生成一个文件对话框,允许用户选择文件或者目录,也允许用户遍历文件系统,用以选择一个或多个文件或者目录
相关函数:
QFileDialog::getOpenFileName() //获取一个打开文件的文件名
QFileDialog::getOpenFileNames() //获取多个打开文件的文件名
QFileDialog::getOpenFileUrl() //获取一个打开文件的统一资源定位符
QFileDialog::getOpenFileUrls() //获取多个打开文件的统一资源定位符
QFileDialog::getSaveFileName() //获取保存的文件名
QFileDialog::getSaveFileUrl() //获取保存的url
如上所示,举例:
QString filename = QFileDialog::getOpenFileName(this,"选择一个文件",QCoreApplication::applicationFilePath(),"*.cpp");//选中文件之后,返回一个路径字符
使用 getOpenFileName函数时,当选中某个文件,点击确定时,该函数的返回值为详细的文件名,若没有则返回"",下面对getOpenFileName依次对传入的参数进行解析:
- 指定父类窗口部件
- 对话框使用的标题
- 默认打开后显示的目录(即告诉它从哪一级目录开始),可以直接为: “./”
- 右下角的文件过滤器,上面代码表示过滤出.cpp文件。
该函数的使用效果如下:
QFile
QFile 类支持对文件进行读取、写入、删除、重命名、拷贝等操作,它既可以操作文件文件,也可以操作二进制文件。
创建文件对象
创建 QFile 类的对象,常用的构造函数有:
QFile::QFile()
QFile::QFile(const QString &name)
参数 name 用来指定要操作的目标文件。
打开文件
使用 QFile 读写文件之前必须先打开文件,调用 open() 成员方法即可,常用的语法格式为:
bool QFile::open(OpenMode mode)//mode 参数用来指定文件的打开方式
mode 参数用来指定文件的打开方式,
传入的参数可以为:
打开方式 | 含 义 |
---|---|
QIODevice::ReadOnly | 只能对文件进行读操作 |
QIODevice::WriteOnly | 只能对文件进行写操作,如果目标文件不存在,会自行创建一个新文件。 |
QIODevice::ReadWrite | 等价于 ReadOnly |
QIODevice::Append | 以追加模式打开文件,写入的数据会追加到文件的末尾(文件原有的内容保留)。 |
QIODevice::Truncate | 以重写模式打开,写入的数据会将原有数据全部清除。注意,此打开方式不能单独使用,通常会和 ReadOnly 或 WriteOnly 搭配。 |
QIODevice::Text | 读取文件时,会将行尾结束符(Unix 系统中是 “\n”,Windows 系统中是 “\r\n”)转换成‘\n’;将数据写入文件时,会将行尾结束符转换成本地格式,例如 Win32 平台上是‘\r\n’。 |
也可以指定多种模式,例如:
QIODevice::ReadOnly | QIODevice::Text:表示只允许对文件进行读操作,读取文件时,会将行尾结束符转换为 ‘\n’;
读取文件
QByteArray ba = file.readAll();//读取文件
ui->textEdit->setText(QString(ba));//文件内容显示在textEdit控件框
如上所示,读取文件的做法是创建一个QByteArray 类型变量,用于存储file.readAll()返回文件的内容,该内容属于字符串形式。
然后再把内容传给控件显示出来
也可以参考其他案例:
//创建一个QFileDialog来获取文件路径
QString path = QFileDialog::getOpenFileName(
this,
"OpenFile",
"../",
"TXT file(*.txt)");
//创建一个QFile对象
QFile file(path);
//打开文件,以只读的方式打开文件
bool isOpen = file.open(QIODevice::ReadOnly|QIODevice::Text);
if(isOpen != false)
{
//QByteArray readAll()
QByteArray fileData;
fileData = file.readAll();
//显示到textEdit中
ui->textEdit->setText(QString(fileData));
}
else
{
qDebug() << "无法打开文件";
}
//关闭文件
file.close();
保存文件
保存文件实质上就是写入文件。
void MainWindow::saveActionSlot()
{
QString filename = QFileDialog::getSaveFileName(this,"选择一个文件",
QCoreApplication::applicationFilePath());
if(filename.isEmpty())
{
QMessageBox::warning(this,"警告","请选择一个文件");
}
else
{
QFile file(filename);//创建文件对象
file.open(QIODevice::WriteOnly);
ui->textEdit->toPlainText();
QByteArray ba;
ba.append(ui->textEdit->toPlainText());
file.write(ba);
file.close();
}
}
-
保存需要先设置文件的存储位置,同样需要使用到QFileDialog类函数,与打开文件getOpenFileName函数不同的是,保存文件需要使用getSaveFileName函数,依次对传入的参数进行解析
第一个参数:指定父类窗口部件
第二个参数:对话框使用的标题
第三个参数:默认保存后显示的目录(即告诉它从哪一级目录开始)
(可选)第四个参数:右下角的文件过滤器 -
创建文件对象,以及设置文件打开模式为只写模式
-
通过 toPlainText获取文本内容,并通过 append赋值给 QByteArray 类型变量。
-
最后通过 file.write写入文件,关闭文件
键盘/鼠标事件组
相信不少人在文件编辑中是通过快捷键Ctrl+s快捷键来保存文件的吧,在QT中快捷键的功能并不是默认存在的,也需要自己去手动编写支持快捷键的功能。
查阅文档,QT已经实现了这一系列的键盘事件
void QWidget::keyPressEvent(QKeyEvent *event) //键盘按下事件
void QWidget::keyReleaseEvent(QKeyEvent *event) //键盘松开事件
具体案例:
快捷键事件
void MainWindow::keyPressEvent(QKeyEvent *k)//文件快捷键事件
{
if(k->modifiers() == Qt::ControlModifier && k->key() == Qt::Key_S)
{
saveActionSlot();//Ctrl+s保存文件
}
}
鼠标事件:
void MainWindow::mousePressEvent(QMouseEvent *m)
{
QPoint pt = m->pos();//获取光标位置
qDebug()<<pt;
if(m->button() == Qt::LeftButton)
{
qDebug("左键被按下");
}
else if(m->button() == Qt::RightButton)
{
qDebug("右键被按下");
}
}