5 实现文件打开功能

5 实现文件打开功能

5.1 开发流程

  • 为QPushButton对应Open的控件设置槽函数
  • 槽函数代码开发
  • 打开文件
  • 读取文件
  • 把文件数据显示在TextEdit控件上

5.2 代码实现

先选择打开按键,选择点击信号与槽的连接,然后通过代码实现开发流程。

cpp 复制代码
void Widget::on_btnSave_clicked()
{
    QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"),
                                                    "D:/AAA",
                                                    tr("Text(*.txt)"));
    ui->textEdit->clear();

    QFile file;
    file.setFileName(fileName);
    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();
        //qDebug() << context;   显示在应用程序输出,而不是界面
        //ui -> textEdit -> setText(context);   显示不完整
        ui->textEdit->append(context);
    }

    file.close();
}

5.3 打开功能优化

存在问题:字符编码设置

如果按之前代码的功能设置为UTF-8的编码,那么在打开ANSI编码的文件时会出现乱码现象,所以我们不应该像之前那样单一设置,后续内容改正。

UTF-8编码设置:

cpp 复制代码
QTextStream stream(&file);
stream.setCodec("UTF-8");

UTF-16编码设置:

cpp 复制代码
stream.setCodec("UTF-16");

ANSI编码设置:

cpp 复制代码
stream.setCodec("ANSI");

5.4 QComboBox

QComboBox 功能概述

QComboBox 是 Qt 框架中用于创建下拉列表的控件,支持用户从一组选项中选择一个值,并可配置为可编辑模式。

主要功能及对应 API

功能 描述 API 方法
添加选项 向下拉列表添加单个或多个选项 addItem()addItems()
获取选项 获取当前选中的文本或索引 currentText()currentIndex()
设置选项 设置当前选中的项 setCurrentIndex(int)
移除选项 从下拉列表中移除项 removeItem(int)
信号 当选项改变时触发的事件 currentIndexChanged(int)
可编辑性 设置下拉列表是否可编辑 setEditable(bool)
自定义数据 向下拉列表项关联额外的数据 setItemData(int, const QVariant&)
清空列表 移除所有选项 clear()

示例代码

cpp 复制代码
#include <QComboBox>
#include <QVBoxLayout>
#include <QWidget>

//这个示例展示了 QComboBox 的基本用法,
//包括添加选项、设置为可编辑以及连接信号和槽。

class ComboBoxDemo : public QWidget {
    Q_OBJECT
public:
    ComboBoxDemo() {
        QComboBox *comboBox = new QComboBox(this);
        comboBox->addItems({"选项1", "选项2", "选项3"});
        comboBox->setEditable(true);
        connect(comboBox, SIGNAL(currentIndexChanged(int)), 
                this, SLOT(onSelectionChanged(int)));
        
        QVBoxLayout *layout = new QVBoxLayout(this);
        layout->addWidget(comboBox);
    }

private slots:
    void onSelectionChanged(int index) {
  
    }
};

5.5 记事本支持字符编码

文件打开与编码处理实现

cpp 复制代码
void Widget::on_btnFileOpen_clicked()
{
    // 使用文件对话框获取要打开的文件的路径
    QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"),
                                                    "D:/AAA/",
                                                    tr("Text (*.txt)"));
    // 清空文本编辑器的内容
    ui->textEdit->clear();
    // 设置 QFile 对象的文件名
    file.setFileName(fileName);
    // 尝试以只读和文本模式打开文件
    if(!file.open(QIODevice::ReadOnly | QIODevice::Text)){
        // 如果文件打开失败,输出错误信息
        qDebug() << "file open error";
   }
    // 创建 QTextStream 用于读取文件内容
    QTextStream in(&file);
    // 从下拉框获取当前选中的字符编码
    QString str = ui->comboBox->currentText();
    // 将 QString 转化为 char* 类型
    const char* c_str = str.toStdString().c_str();
    // 设置 QTextStream 的字符编码
    in.setCodec(c_str);
    // 循环读取文件直到结束
    while(!in.atEnd()){
        // 读取文件的一行
        QString context = in.readLine();
        // 将读取的内容追加到文本编辑器
        ui->textEdit->append(context);
   }
}

注意事项

  • 确保file是类成员变量(类型为QFile
  • ui->textEdit需要是项目中的QTextEdit组件
  • ui->comboBox应预先填充支持的编码选项(如"UTF-8"、"GBK"等)
  • 获取用户在QComboBox上选择的字符编码,用特定编码打开文件,这里注意QComboBox返回QString类型,setCodec参数要求const char*QString先转成C++的String,再转换成const char *

支持打开文件后进行字符编码的重新选择和显示加载

cpp 复制代码
void Widget::onCurrentIndexChanged(int index)
{
    // 输出调试信息,表示此槽函数被触发
    qDebug() << "currentIndexChanged Signal";
    // 清空文本编辑器的内容
    ui->textEdit->clear();
    // 检查文件是否已经打开
    if(file.isOpen()){
        // 输出调试信息,表示文件是打开状态
        qDebug() << "file is Open";
        // 创建 QTextStream 用于读取文件内容
        QTextStream in(&file);
        // 设置 QTextStream 的字符编码为 QComboBox 当前选中的编码
        in.setCodec(ui->comboBox->currentText().toStdString().c_str());
        // 将文件指针移动到文件开始位置
        file.seek(0);
        // 循环读取文件直到文件结束
        while(!in.atEnd()){
            // 读取文件的一行
            QString context = in.readLine();
            // 将读取的内容追加到文本编辑器
            ui->textEdit->append(context);
       }
   }
}

5.6 添加行列显示

使用QTextEdit的cursorPositionChanged信号,当光标发生移动时候刷新显示

构造函数连接信号与槽

cpp 复制代码
// 在Widget构造函数中添加
connect(ui->textEdit,SIGNAL(cursorPositionChanged()),
         this,SLOT(oncursorPositionChanged()));

槽函数实现

cpp 复制代码
void Widget::onCursorPositionChanged()
{
    QTextCursor cursor =  ui->textEdit->textCursor();
    //qDebug() << cursor.blockNumber()+1 <<","<< cursor.columnNumber() + 1;
    QString blockNum = QString::number(cursor.blockNumber()+1);
    QString columnNum = QString::number(cursor.columnNumber()+1);
    const QString labelMes = "L:"+blockNum+",C:"+columnNum+"   ";
    //const QString labelMes = "行:"+blockNum+",列:"+columnNum+"   ";
    ui->labelPosition->setText(labelMes);
}

注意事项

  1. comboBox需要预先填充编码选项(如"UTF-8"、"GBK"等)
  2. labelPosition需要是界面上的QLabel对象

5.7 添加文件打开提示

目标:比如在打开文件名为"123.txt"时,记事本标题同步此名称。

cpp 复制代码
this->setWindowTitle(fileName + "- MyNoteBook");

将此代码添加到打开文件,保存文件,关闭文件中,完成目标功能。

5.8 设置当前行高亮

5.8.1 QList

QList 基本用法

包含头文件

cpp 复制代码
#include <QList>

创建 QList 实例

cpp 复制代码
QList<int> list;

添加元素

cpp 复制代码
list.append(1);
list.append(2);
list.append(3);

访问元素

cpp 复制代码
int firstElement = list[0];
int secondElement = list.at(1);

遍历列表

cpp 复制代码
// 使用索引遍历
for(int i = 0; i < list.size(); ++i) {
    qDebug() << list[i];
}

// 使用范围基的 for 循环
for(int item : list) {
    qDebug() << item;
}

移除元素

cpp 复制代码
list.removeAt(1); // 移除索引为 1 的元素
list.removeOne(3); // 移除一个值为 3 的元素
list.clear(); // 清空整个列表

QList 内部工作原理

  • 数组式存储

    使用连续内存存储元素,支持快速索引访问([]at())和高效迭代。

  • 动态调整大小

    自动管理内存分配,支持动态增长和缩减。

  • 链表特性

    支持在列表首尾高效添加或移除元素(如 appendprepend)。

  • 隐式共享(写时复制)

    复制时共享内存,仅在修改时进行实际复制,提升性能。

适用场景

  • 需要频繁随机访问(通过索引)的场景。
  • 主要操作集中在列表两端(如添加或删除元素)。

5.8.2 ExtraSelection 简介

QTextEdit::ExtraSelection 用法

结构体组成

  • 包含 QTextCursorQTextCharFormat 两个成员
  • QTextCursor 定义文本位置或区间
  • QTextCharFormat 定义文本格式(颜色、字体等)

应用步骤

创建 ExtraSelection 对象并配置格式后,通过 setExtraSelections() 应用到编辑器:

cpp 复制代码
QTextEdit::ExtraSelection selection;
selection.cursor = textEdit->textCursor();
selection.format.setBackground(Qt::yellow);
textEdit->setExtraSelections({selection});

高亮当前行实现

cursorPositionChanged 信号槽中动态设置高亮:

cpp 复制代码
void Widget::oncursorPositionChanged() {
    //设置高亮
    QList<QTextEdit::ExtraSelection> extraselection;
    QTextEdit::ExtraSelection ext;

    ext.cursor = cursor;
    QBrush qBrush(Qt::yellow);

    ext.format.setBackground(qBrush);
    ext.format.setProperty(QTextFormat::FullWidthSelection, true);

    extraselection.append(ext);
    ui->textEdit->setExtraSelections(extraselection);
}

截至目前,该项目已完成如下功能

相关推荐
weixin_580614002 小时前
如何用 performance.navigation 判断页面刷新并清理缓存
jvm·数据库·python
量子炒饭大师2 小时前
【C++ 进阶】Cyber霓虹掩体下的代码拟态——【面向对象编程 之 多态】一文带你搞懂C++面向对象编程中的三要素之一————多态!
开发语言·c++·多态
21439652 小时前
Golang strings.Builder如何用_Golang Builder拼接教程【对比】
jvm·数据库·python
2301_777599372 小时前
mysql如何配置主机缓存_mysql host_cache_size设置
jvm·数据库·python
伴我与影2 小时前
【记录】复现论文 Dftpav
c++·docker
qq_206901393 小时前
为什么宝塔面板网站无法正常连接外部远程数据库_检查服务器安全组放行端口并开启IP授权
jvm·数据库·python
亚空间仓鼠3 小时前
关系型数据库MySQL(二):高级特性
数据库·sql·mysql
Hical_W3 小时前
深入学习CPP17_PMR
c++·学习
xiaoshuaishuai83 小时前
C# 实现百度搜索算法逆向
开发语言·windows·c#·dubbo
亚空间仓鼠3 小时前
关系型数据库MySQL(五):Galara高可用
数据库·mysql