P3 QT项目----记事本(3.8)

发布于:2025-06-10 ⋅ 阅读:(14) ⋅ 点赞:(0)
3.8 记事本项目总结

项目源码

1.main.cpp

#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}

2.widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QFileDialog>
#include <QDebug>
#include <QList>
#include <QMessageBox>
#include <QShortcut>
Widget::Widget(QWidget *parent) 
   : QWidget(parent)
    , ui(new Ui::Widget)
{ 
   //建立快捷键  
  QShortcut *shortcutOpen = new QShortcut(QKeySequence(tr("Ctrl+o", "File|Open")),this);          //打开  
  QShortcut *shortcutSave = new QShortcut(QKeySequence(tr("Ctrl+s", "File|Save")),this);          //保存 
   QShortcut *shortcutZoomIn = new QShortcut(QKeySequence(tr("Ctrl+Shift+=", "File|Save")),this);  //字体放大
    QShortcut *shortcutZoomOut = new QShortcut(QKeySequence(tr("Ctrl+Shift+-", "File|Save")),this); //字体缩小

    //Lambda表达式
    connect(shortcutOpen,&QShortcut::activated,[=]()
    { 
       on_btnOpen_clicked(); 
   }); 
   connect(shortcutSave,&QShortcut::activated,[=]()
    {
        on_btnSave_clicked();
    });
    connect(shortcutZoomIn,&QShortcut::activated,[=]()
   {      
        ZoomIn();  
  });
    connect(shortcutZoomOut,&QShortcut::activated,[=]()
    {
       ZoomOut();
    }); 

   //进行widget与ui的窗口关联,里面布局不会随窗口变化而变化
    ui->setupUi(this); 
   //下面这行代码进行显示说明,窗口变化时,布局及其子控件随之调整
    this->setLayout(ui->verticalLayout);
    ui->widgetButtom->setLayout(ui->horizontalLayout_3); 

   //信号与槽:编码选择 
   QObject::connect(ui->comboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(onCurrentIndexChanged(int)));   
   //信号与槽:光标位置
    QObject::connect(ui->textEdit,SIGNAL(cursorPositionChanged()),this,SLOT(onCursorPositionChanged()));
}
Widget::~Widget()
{
    delete ui;
}

/* 快捷键字体变大 QApplication类*/
void Widget::ZoomIn()
{
    //获得TextEdit的当前字体信息
    QFont font = ui->textEdit->font();  
    //获得当前字体大小
    int fontSize = font.pointSize();
    if(fontSize == -1) return ;

    //改变大小,并设置字体大小
    int newFontSize = fontSize + 1;
    font.setPointSize(newFontSize);
    ui->textEdit->setFont(font);
}

/* 快捷键字体变小 */
void Widget::ZoomOut()
{
    //获得TextEdit的当前字体信息
    QFont font = ui->textEdit->font();
    //获得当前字体大小
    int fontSize = font.pointSize();
    if(fontSize == -1) return ;

    //改变大小,并设置字体大小
    int newFontSize = fontSize - 1;
    font.setPointSize(newFontSize);
    ui->textEdit->setFont(font);
}

/* 打开按键 */
void Widget::on_btnOpen_clicked()
{
    //建立一个qfiledialog实例化
    QFileDialog qFileDialog;
    //设置对话框为打开文件模式
    qFileDialog.setFileMode(QFileDialog::ExistingFiles);
    //设置文件过滤器
    qFileDialog.selectNameFilter("Text files(*.txt*.doc) ");
    //打开文本框
    if(qFileDialog.exec())
    {
        //获取用户选择的文件列表
        QStringList fileName = qFileDialog.selectedFiles();
        //遍历列表并处理文件
        for(QString str : fileName)
        {
            //输出文件名
            qDebug() << str;
            //清除文本编辑内容
            ui->textEdit->clear();
            //打开文件名
            file.setFileName(str);
            //判断是否成功打开文件
            if(!file.open(QIODevice::ReadWrite | QIODevice::Text))
            {
                qDebug() << "File Open Error!";
            }

            //标题文件名
            //this->setWindowTitle(fileName + "My NoyeBooks");
            //多态
            QTextStream in(&file);
            //读取方式
            //in.setCodec("UTF-8");
            //QString string = ui->comboBox->currentText();                     
            // 从下拉框获取当前选中的字符编码            
            // const char * c_str = string.toStdString().c_str();
//            in.setCodec(c_str);               //QString转为const char*型            

             in.setCodec(ui->comboBox->currentText().toStdString().c_str());     // 设置 QTextStream 的字符编码           
         //按行显示显示文件内容
            while (!file.atEnd())
            {
                QString context = in.readLine();
                ui->textEdit->append(context);
            }
        }
    }
}

/* 保存按键 */
void Widget::on_btnSave_clicked()
{
    if(!file.isOpen())  //有打开的文件直接保存,不需要生成新文件
    {
        QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"),                                                        
"D:/Embedded_learning/03.QT_Codeinlesson/build-P3-1-notebook/untitled.txt",                                                        tr("Text files(*.txt*.doc)")); 
       qDebug() << fileName; 

       file.setFileName(fileName); 
       if(!file.open(QIODevice::WriteOnly | QIODevice::Text))
        { 
           qDebug() << "File Save Error!";
        }
        //标题文件名
        this->setWindowTitle(fileName + "-My NoyeBooks");
    }
    //写入的内容
    QTextStream out(&file);
    //out.setCodec("UTF-8");
    out.setCodec(ui->comboBox->currentText().toStdString().c_str());    //QString转为const char*型
    QString context = ui->textEdit->toPlainText();
    //输入
    out << context;
}

/* 关闭按键 */
void Widget::on_btnClose_clicked()
{
    ui->textEdit->clear();
    //未保存文件按下关闭按键时,会触发警告
    int ret = QMessageBox::warning(this, tr("My NoyeBooks"),
                                    tr("The document has been modified.\n"
                                       "Do you want to save your changes?"),
                                    QMessageBox::Save | QMessageBox::Discard
                                    | QMessageBox::Cancel,
                                    QMessageBox::Save);
    switch (ret)
    {
       case QMessageBox::Save:  //保存
           // Save was clicked
        on_btnSave_clicked();
        qDebug() << "QMessageBox::Save:";
           break;
       case QMessageBox::Discard:   //丢弃
           // Don't Save was clicked
        ui->textEdit->clear();
        if(file.isOpen())
        {
            file.close();
            this->setWindowTitle("My NoyeBooks");
        }
        qDebug() << "QMessageBox::Discard:";
           break;
       case QMessageBox::Cancel:
        qDebug() << "QMessageBox::Cancel:";
           // Cancel was clicked
           break;
       default:
           // should never be reached
           break;
     }
    //检测设备是否打开,打开返回true
    if(file.isOpen())
    {
        file.close();
        this->setWindowTitle("My NoyeBooks");
    }
}

/* 解决乱码问题combobox */
void Widget::onCurrentIndexChanged(int index)
{
    //清除文本
    ui->textEdit->clear();
    //检测设备是否打开,打开返回true
    if(file.isOpen())
    {
        // 创建 QTextStream 用于读取文件内容
        QTextStream in(&file);
        in.setCodec(ui->comboBox->currentText().toStdString().c_str());
        //光标回到初始位置
        file.seek(0);
        //继续显示文件内容
        while (!file.atEnd())   
     {  
          QString context = in.readLine();  
          ui->textEdit->append(context); 
       }
    }
}
/* 光标位置 */
void Widget::onCursorPositionChanged()
{
    QTextCursor cursor = ui->textEdit->textCursor();
    //qDebug() << cursor.blockNumber() + 1 << "," << cursor.columnNumber() + 1;
    //行
    QString blockNum = QString::number(cursor.blockNumber() + 1);
    //列
    QString columNum = QString::number(cursor.columnNumber() + 1);
    const QString labelMes = "L:" + blockNum + ",C:" + columNum + "     ";
    ui->labelPosition->setText(labelMes);  
 
 //设置当前行高亮 
   QList<QTextEdit::ExtraSelection> extraSelection;    //定义qLish集合  
  QTextEdit::ExtraSelection ext;                      //qLish的一个对象   

 //1.知道当前行  
  ext.cursor = ui->textEdit->textCursor(); 
   //2.颜色 
   QBrush qBrush(Qt::yellow); 
   ext.format.setBackground(qBrush); 
   ext.format.setProperty(QTextFormat::FullWidthSelection,true);   //配置段属性,需要整行设置,没有这行不行 
   //3.设置
    extraSelection.append(ext); //把ext加入到ext容器中
    ui->textEdit->setExtraSelections(extraSelection);
}

3.widget.h

#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QFile>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
    Q_OBJECT
public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
    QFile file;
    void ZoomIn();
    void ZoomOut();
private slots:
    void on_btnOpen_clicked();
    void on_btnSave_clicked();
    void on_btnClose_clicked();
    void onCurrentIndexChanged(int index);
    void onCursorPositionChanged();
private:
    Ui::Widget *ui;
};

#endif // WIDGET_H
4.testedit.cpp
#include "testedit.h"
/*
    将QTestEdit提升为testedit的ui界面,经事件处理,
    完成记事本可以通过鼠标滚轮和Ctrl键进行文本放大缩小
*/
#include <QWheelEvent>
#include <QDebug>

testedit::testedit(QWidget *parent) : QTextEdit(parent)
{
}

void testedit::wheelEvent(QWheelEvent *e)
{
    qDebug() << e->angleDelta().y();
    if(ctrlKeyPressed == 1)
    {
        if(e->angleDelta().y() > 0)
        {
            //放大
            zoomIn();
        }
        else if (e->angleDelta().y() < 0)
        {
            zoomOut();
        }
        e->accept();
    }
    else
    {
        QTextEdit::wheelEvent(e);
    }
}

void testedit::keyPressEvent(QKeyEvent *e)
{
    if(e->key() == Qt::Key_Control)
    {
        qDebug() << "Ctrl is Pressed";
        ctrlKeyPressed = 1;
    }
    QTextEdit::keyPressEvent(e);
}

void testedit::keyReleaseEvent(QKeyEvent *e)
{
    if(e->key() == Qt::Key_Control)
    {
        qDebug() << "Ctrl is Released";
        ctrlKeyPressed = 0;
    } 
   QTextEdit::keyReleaseEvent(e);
}

5.testedit.h

#ifndef TESTEDIT_H
#define TESTEDIT_H
#include <QTextEdit>
class testedit : public QTextEdit
{
public:
    testedit(QWidget *parent);
protected:
    void wheelEvent(QWheelEvent *e) override;
    void keyPressEvent(QKeyEvent *e) override;
    void keyReleaseEvent(QKeyEvent *e) override;
private:
    bool ctrlKeyPressed = 0;
};

#endif // TESTEDIT_H