一、实现简易文本编辑器
- 主要用到带菜单栏的窗口,而非单一窗口。QT已经写好相关操作,就不在重新造轮子了
- 功能设计:新建文本文档,打开文件,保存文件,另存为
这次不同于之前直接可以在控件上面右击槽了;而是需要自己手动去进行连接信号与槽
private slots:
void newTextAction(); //新建文档
void openTextAction(); //打开文档
void saveTextAction(); //保存文档
void saveAnotherAction(); //文档另存为
//构造函数中,连接信号与槽
connect(ui->new_file_Action, &QAction::triggered, this, &MainWindow::newTextAction);
connect(ui->open_file_Action, &QAction::triggered, this, &MainWindow::openTextAction);
connect(ui->save_file_Action, &QAction::triggered, this, &MainWindow::saveTextAction);
connect(ui->save_another_file_Action, &QAction::triggered, this, &MainWindow::saveAnotherAction);
- 新建文本文档:将之前的内容清空
void MainWindow::newTextAction()
{
ui->textEdit->clear();
this->setWindowTitle("新建文本文档.txt");
}
- 打开文档,读取里面内容
void MainWindow::openTextAction()
{
QString current_path = QCoreApplication::applicationFilePath(); //获取当前文件路径
QString file_Name = QFileDialog::getOpenFileName(this, tr("打开文件"),
current_path,
tr("Text files (*.txt *.c *.cpp)"));
if(file_Name.isNull()){
QMessageBox::warning(this, "警告","请选择一个文件");
}else{
QFile file(file_Name);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
return;
QTextStream in(&file);
QString content = in.readAll();
ui->textEdit->setText(content);
file.close();
//记录当前路径
m_current_file_path = file_Name;
}
}
- 保存文档,将编辑框里面的内容写入文档中<=============>将内存中的数据持久化到磁盘上
void MainWindow::saveTextAction()
{
//如果当前没有打开文件,那么就另存为
if(m_current_file_path.isEmpty()){
this->saveAnotherAction();
return;
}
QFile file(m_current_file_path);
if(!file.open(QIODevice::WriteOnly | QIODevice::Text)){
QMessageBox::warning(this, "错误","无法保存文件");
return;
}
QTextStream out(&file);
out<<ui->textEdit->toPlainText();
file.close();
QMessageBox::information(this, "成功","保存文件");
}
- 和保存功能一样,不过需要新添选择新路径这一项
void MainWindow::saveAnotherAction()
{
QString current_path = QCoreApplication::applicationFilePath(); //获取当前文件路径
QString save_path = QFileDialog::getSaveFileName(this, tr("保存文件"),
current_path,
tr("Text files (*.txt *.c *.cpp)"));
if(save_path.isNull()){
QMessageBox::warning(this, "警告","请选择保存位置");
}else{
QFile file(save_path);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)){
QMessageBox::warning(this, "错误", "无法保存文件");
return;
}
QTextStream out(&file);
out<<ui->textEdit->toPlainText();
file.close();
//更新当前路径
m_current_file_path = save_path;
//设置标题
this->setWindowTitle(QFileInfo(save_path).fileName());
QMessageBox::information(this, "成功","保存文件");
}
}
- 实现下快捷键操作,需要添加处理按键的响应函数
void MainWindow::keyPressEvent(QKeyEvent *event)
{
if (event->modifiers() & Qt::ControlModifier){
switch(event->key()){
case Qt::Key_N: this->newTextAction(); break;
case Qt::Key_O: this->openTextAction(); break;
case Qt::Key_S:
{
if(event->modifiers() & Qt::ShiftModifier){
this->saveAnotherAction();
}else{
this->saveTextAction();
}
break;
}
default:
QMainWindow::keyPressEvent(event); // 调用基类处理
}
}else{
QMainWindow::keyPressEvent(event); // 调用基类处理
}
}
二、问题:
2.1 如果文件过大,比如10个G的txt文件,这样操作,肯定不行,那怎么办?
- 采用分块读取,比如每次读取4kb
- 采用内存映射,将文件的部分内容直接映射到内存当中
类似数据库当中的分页或者浏览器,app看小说的滑动栏;实现起来稍微有点复杂,需要记录上一次以及下一次分块的内容,方便快速加载出来