一个项目带你入门qt - 记事本(上)

目录

ui布局:

整体

combo Box

上方三个图标按钮样式表

废话少说,放码过来

main.cpp

Widget.h

Widget.cpp

细节拆分

实现文件操作的三个按钮

实现第一个按钮 -- 打开文件

槽函数

演示: 

实现第二个按钮 - 保存文件

槽函数

演示

实现第三个按钮 - 关闭

槽函数

实现在文件头显示文件名

分别在三个按钮中添加

演示

实现编码格式转换

connect

实现槽函数

注意:

演示

实现底部显示光标行列号

connect

槽函数 

演示:


ui布局:

整体

combo Box

(右下角)

上方三个图标按钮样式表

// 格式一样只是,插入图片不同

废话少说,放码过来

main.cpp

#include "widget.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}

Widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QDebug>
#include <QFileDialog>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    QFile   qfile;
    Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    void on_openButton_clicked();

    void on_saveButton_clicked();

    void on_closeButton_clicked();

    void onCurrentIndexChanged(int index);

    void cursorPositionChanged();

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

Widget.cpp

#include "widget.h"
#include "ui_widget.h"



//构造函数
Widget::Widget(QWidget *parent) : QWidget(parent)   , ui(new Ui::Widget) //初始化列表来构造
{
    ui->setupUi(this); //设置QTdesigner 里面的ui 关联到widget类的私有变量ui里面
    //虽然上面这行代码进行了widget 和  ui 窗口的关联,但是如果发生窗口大小变化的时候,里面的的布局不会随之改变
    //通过下面这行代码进行显示说明,让窗口变化时,布局及其子控件随之调整
    this->setLayout(ui->verticalLayout);
    //  ui->widgetBottom->setLayout(ui->horizontalLayout);

    // 关联ComboBox
    connect(ui->comboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(onCurrentIndexChanged(int)));

    // 关联文本框光标改造
    connect(ui->textEdit,SIGNAL(cursorPositionChanged()),this,SLOT(cursorPositionChanged()));

}
//析构函数
Widget::~Widget()
{
    delete ui;
}


void Widget::on_openButton_clicked()
{
    //  先打开文件
    QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), // this --> 指定当前的Widget对象 ,作用打开文件
                            "F:/myqt/project_of_qt_new", // 默认打开的路径
                           tr("Text (*.txt)"));//限制能打开文件的格式

     this->setWindowTitle(fileName +"-mxjun notebook");
     ui->textEdit->clear(); // 清空文本框,避免上次读取的干扰
      qfile.setFileName(fileName);

    if(!qfile.open(QIODevice::ReadOnly | QIODevice::Text)) // Text --> 对\n 做检查,win系统下会转化为\r\n,对换行读取更好
     {
        qDebug()<<"Open Error";
    }

    QTextStream in(&qfile);
    //in.setCodec("UTF-8"); //设置编码格式

    // in.setCodec("ANSI"); // 参数需要是char * 类型 --> 我们需要把QStrng 转化为char*
    QString str =ui->comboBox->currentText(); //  获得编码格式
    const char * c_str =str.toStdString().c_str();// 先把 QString 类型转化为C++中的String,然后c_str()转化为 const char *类型
    in.setCodec(c_str);

    // 读取多行
    while (!in.atEnd()) {// 当没到文件尾部
    QString context =in.readLine(qfile.size());// 每次读一行
    //qDebug() << qPrintable(context);//qPrintable -- 过滤掉 ""
    //将读取到的内容写入我们的 文本框内 -- textEdit, 调用 setText()
    //ui->textEdit->setText(context);//setText --> 作用于真个textEdit 控件-- 覆盖作用 --导致多行的情况下只能读取到一行

    ui->textEdit->append(context);// 以追加的方式读取,能读取到多行
    }
    //qfile.close(); // 这里不用关闭,我们后续close 按钮会关闭

}

void Widget::on_saveButton_clicked()
{

    QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"),//设置为保存文件模式
          "F:/myqt/project_of_qt_new/default.txt", // 默认打开的路径,加上/default.txt,指定默认文件名
           tr("Text (*.txt *.doc)"));//限制能打开文件的格式 ,这里指定保存文件类型了,不写后缀 .txt 只写文件名也可以

    qDebug()<< fileName;
     this->setWindowTitle(fileName +"-mxjun notebook");

     qfile.setFileName(fileName);

    if(!qfile.open(QIODevice::WriteOnly | QIODevice::Text)) // Text --> 对\n 做检查,win系统下会转化为\r\n,对换行读取更好
     {
        qDebug()<<"Open Error";
    }

    QTextStream out(&qfile); // & --拷贝构造函数  -- 指向内存空间的地址
    out.setCodec("UTF-8");
    // 读取文本框 textEdit 里面的内容
    QString  context=ui->textEdit->toPlainText();
    out << context;
    //qfile.close(); // 这里不用关闭,我们后续close 按钮会关闭

}

void Widget::on_closeButton_clicked()
{
    if(qfile.isOpen()){
        qfile.close(); // 关闭打开的文件
        ui->textEdit->clear();// 清除文本框
        this->setWindowTitle("mxjun notebook");
    }
    close(); // 关闭窗口
}

void Widget::onCurrentIndexChanged(int index)
{
 // 实现功能,对打开的文件修改编码类型,同时能实现重新生成文本框内容
 // 先清屏
 ui->textEdit->clear();
 if(qfile.isOpen()){ // 判断文件是否打开



     //这个函数与修改编码格式的信号绑定了,只能编码类型发生变化的情况下才会使用
     QTextStream in(&qfile); // 实例化对象 -- 来操作这个文件
      //修改对应的编码格式
     in.setCodec(ui->comboBox->currentText().toStdString().c_str());
     //将修改后的文本打印出来
     // 注意前面打开文件的时候,光标已经到了最后面,我们需要给光标复位一下
     qfile.seek(0);//光标复位 --> 回到文件头
     while(!in.atEnd()){
     QString context = in.readLine();
     ui->textEdit->append(context);
     }
 }

}

void Widget::cursorPositionChanged()
{// 与光标位置改变的信号进行绑定

    // 获取文本框的光标位置
    QTextCursor cursor  = ui->textEdit->textCursor();
    //  输出对应行列
    qDebug()<<cursor.blockNumber() +1<<',' <<cursor.columnNumber()+1;

    QString lableLine =  QString::number(cursor.blockNumber() +1);
    QString lableRow =  QString::number(cursor.columnNumber() +1);
    const QString lableMes  ="Line:"+lableLine + "Row:"+lableRow+"  ";

    //const QString lableMes  ="行:"+lableLine + "列:"+lableRow+"  "; //需要在设置里面把编码格式改为utf-8

     ui->labelLR->setText(lableMes);
}

细节拆分

实现文件操作的三个按钮

不了解QFile 文件操作的朋友推荐看这篇来快速入门: 一文带你入门QFile-CSDN博客

实现第一个按钮 -- 打开文件

添加槽函数方式:

进入ui界面--> 右键按钮-->转到槽函数

希望了解其他更多方式,推荐看这篇:一文带你入门信号与槽-CSDN博客

槽函数
void Widget::on_openButton_clicked()
{
    //  先打开文件
    QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), // this --> 指定当前的Widget对象 ,作用打开文件
                            "F:/myqt/project_of_qt_new", // 默认打开的路径
                           tr("Text (*.txt)"));//限制能打开文件的格式

     this->setWindowTitle(fileName +"-mxjun notebook");
     ui->textEdit->clear(); // 清空文本框,避免上次读取的干扰
      qfile.setFileName(fileName);

    if(!qfile.open(QIODevice::ReadOnly | QIODevice::Text)) // Text --> 对\n 做检查,win系统下会转化为\r\n,对换行读取更好
     {
        qDebug()<<"Open Error";
    }

    QTextStream in(&qfile);
    //in.setCodec("UTF-8"); //设置编码格式

    // in.setCodec("ANSI"); // 参数需要是char * 类型 --> 我们需要把QStrng 转化为char*
    QString str =ui->comboBox->currentText(); //  获得编码格式
    const char * c_str =str.toStdString().c_str();// 先把 QString 类型转化为C++中的String,然后c_str()转化为 const char *类型
    in.setCodec(c_str); // 需要const char * 类型的数据

    // 读取多行
    while (!in.atEnd()) {// 当没到文件尾部
    QString context =in.readLine(qfile.size());// 每次读一行
    //qDebug() << qPrintable(context);//qPrintable -- 过滤掉 ""
    //将读取到的内容写入我们的 文本框内 -- textEdit, 调用 setText()
    //ui->textEdit->setText(context);//setText --> 作用于真个textEdit 控件-- 覆盖作用 --导致多行的情况下只能读取到一行

    ui->textEdit->append(context);// 以追加的方式读取,能读取到多行
    }
    //qfile.close(); // 这里不用关闭,我们后续close 按钮会关闭

}
演示: 

点击图标

选择需要打开的文件:

这里我选择test.txt

可以看到我们打开了目标文件

实现第二个按钮 - 保存文件

添加槽函数的方式和上面一样,这里就不演示了

槽函数
void Widget::on_saveButton_clicked()
{

    QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"),//设置为保存文件模式
          "F:/myqt/project_of_qt_new/default.txt", // 默认打开的路径,加上/default.txt,指定默认文件名
           tr("Text (*.txt *.doc)"));//限制能打开文件的格式 ,这里指定保存文件类型了,不写后缀 .txt 只写文件名也可以

    qDebug()<< fileName;
     this->setWindowTitle(fileName +"-mxjun notebook");

     qfile.setFileName(fileName);

    if(!qfile.open(QIODevice::WriteOnly | QIODevice::Text)) // Text --> 对\n 做检查,win系统下会转化为\r\n,对换行读取更好
     {
        qDebug()<<"Open Error";
    }

    QTextStream out(&qfile); // & --拷贝构造函数  -- 指向内存空间的地址
    out.setCodec("UTF-8");
    // 读取文本框 textEdit 里面的内容
    QString  context=ui->textEdit->toPlainText();
    out << context;
    //qfile.close(); // 这里不用关闭,我们后续close 按钮会关闭

}
演示

运行 - 打开一个新的记事本

编写内容

点击保存按钮

给文件起名,这里不用加后缀名也是可以的,我们代码里面限制了他的格式,后缀名会自动被补充

可以看到新文件已经存在

我们使用我们的open按钮打开查看

使用window 记事本查看

保存成功!

实现第三个按钮 - 关闭

槽函数
void Widget::on_closeButton_clicked()
{
    if(qfile.isOpen()){
        qfile.close(); // 关闭打开的文件
        ui->textEdit->clear();// 清除文本框
        this->setWindowTitle("mxjun notebook");
    }
    close(); // 关闭窗口
}

效果太简单,不演示了

实现在文件头显示文件名

分别在三个按钮中添加



演示

实现编码格式转换

1.在ui界面中加入一个combo Box 控件

2. 向其中添加内容(各种编码格式)

3.添加对应信号与槽函数的连接

connect

// 关联ComboBox
    connect(ui>comboBox,SIGNAL(currentIndexChanged(int)),this,
     SLOT(onCurrentIndexChanged(int));

//这里的信号是当前索引发生变化,对象是comboBox,即选择了其他不同的编码格式

通过这种方式获取combo Box 什么的编码格式,如果再重新设备编码格式

实现编码格式灵活切换

    QString str =ui->comboBox->currentText(); //  获得编码格式
    const char * c_str =str.toStdString().c_str();
    // 先把 QString 类型转化为C++中的String,然   后c_str()转化为 const char *类型
    in.setCodec(c_str); // 需要const char * 类型的数据

实现槽函数

 // 实现功能,对打开的文件修改编码类型,同时能实现重新生成文本框内容

void Widget::onCurrentIndexChanged(int index)
{
 // 实现功能,对打开的文件修改编码类型,同时能实现重新生成文本框内容
 // 先清屏
 ui->textEdit->clear();
 if(qfile.isOpen()){ // 判断文件是否打开



     //这个函数与修改编码格式的信号绑定了,只能编码类型发生变化的情况下才会使用
     QTextStream in(&qfile); // 实例化对象 -- 来操作这个文件
      //修改对应的编码格式
     in.setCodec(ui->comboBox->currentText().toStdString().c_str());
     //将修改后的文本打印出来
     // 注意前面打开文件的时候,光标已经到了最后面,我们需要给光标复位一下
     qfile.seek(0);//光标复位 --> 回到文件头
     while(!in.atEnd()){
     QString context = in.readLine();
     ui->textEdit->append(context);
     }
 }

}

注意:

这里的光标在进来之前就被放到文件尾部了,需要调用seek() 函数去是实现光标复位

演示

以UTF-8格式去打开ANSI的文件 

出现乱码

通过comboBox去选择ANSI格式

选择之后,文件框自动刷新内容

实现底部显示光标行列号

connect


    // 关联文本框光标改造
    connect(ui>textEdit,SIGNAL(cursorPositionChanged()),
    this,SLOT(cursorPositionChanged()));

信号: 文本框内的光标发生改变


//QTextEdit 的一个信号,捕捉光标改变

槽函数 

cursorPositionChanged()

  // 关联文本框光标改造
    connect(ui->textEdit,SIGNAL(cursorPositionChanged()),this,SLOT(cursorPositionChanged()));

void Widget::cursorPositionChanged()
{// 与光标位置改变的信号进行绑定

    // 获取文本框的光标位置
    QTextCursor cursor  = ui->textEdit->textCursor();
    //  输出对应行列
    qDebug()<<cursor.blockNumber() +1<<',' <<cursor.columnNumber()+1;

    QString lableLine =  QString::number(cursor.blockNumber() +1);
    QString lableRow =  QString::number(cursor.columnNumber() +1);
    const QString lableMes  ="Line:"+lableLine + "Row:"+lableRow+"  ";

    //const QString lableMes  ="行:"+lableLine + "列:"+lableRow+"  "; //需要在设置里面把编码格式改为utf-8

     ui->labelLR->setText(lableMes);
}

演示:


=======================================
添加打开文件提示

// 后续还会继续优化,更新记事本的内容,会引入更多QT的API的使用方法,加深对qt的理解
 

  • 38
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值