Qt5实现文本编辑器(附图片转PDF与详细代码)

1. 功能介绍

老规矩,我们直接上截图

这是主界面
在这里插入图片描述
文件菜单界面
在这里插入图片描述

编辑菜单界面
在这里插入图片描述
设置菜单界面
在这里插入图片描述
关于菜单界面

在这里插入图片描述

2. 功能演示

设置字体颜色
在这里插入图片描述
在这里插入图片描述
设置字体大小

在这里插入图片描述
在这里插入图片描述
点击关于菜单
在这里插入图片描述
点击关于Qt菜单
在这里插入图片描述
会自动跳转到Qt的官网

点击图片转PDF
在这里插入图片描述
打开文件等对话框
在这里插入图片描述

3. 代码

我们直接上代码

aboutwidget.h

#ifndef ABOUTWIDGET_H
#define ABOUTWIDGET_H

#include <QWidget>

namespace Ui {
class AboutWidget;
}

class AboutWidget : public QWidget
{
    Q_OBJECT

public:
    explicit AboutWidget(QWidget *parent = nullptr);
    ~AboutWidget();

private:
    Ui::AboutWidget *ui;
};

#endif // ABOUTWIDGET_H

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QFont>
#include <QColor>


QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();




private slots:
    void on_actionexit_triggered();

    void on_actioncolor_triggered();

    void on_actionfont_triggered();

    void on_actionne_triggered();

    void on_actionopen_triggered();

    void on_actionsave_triggered();

    void on_actionasfile_triggered();

    void on_actioncut_triggered();

    void on_actioncopy_triggered();

    void on_actionundo_triggered();

    void on_actionredo_triggered();

    void on_actionpatse_triggered();

    void on_actionAbout_triggered();

    void on_actionAboutQT_triggered();

    void on_actionPDF_triggered();

private:
    Ui::MainWindow *ui;
    QFont font;
    QColor color;
    QString currentFile;
};
#endif // MAINWINDOW_H

topdf.h

#ifndef TOPDF_H
#define TOPDF_H

#include <QWidget>

namespace Ui {
class ToPdf;
}

class ToPdf : public QWidget
{
    Q_OBJECT

public:
    explicit ToPdf(QWidget *parent = nullptr);
    ~ToPdf();
    bool pictureToPDF(QString sourth,QString sDir);

private slots:
    void on_pictureBtn_clicked();

    void on_saveBtn_clicked();

    void on_startBtn_clicked();

private:
    Ui::ToPdf *ui;
};

#endif // TOPDF_H

aboutwidget.cpp

#include "aboutwidget.h"
#include "ui_aboutwidget.h"

AboutWidget::AboutWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::AboutWidget)
{
    ui->setupUi(this);

    ui->Pixmap->setPixmap(QPixmap(":/dog.jpg").scaled(141,131,Qt::KeepAspectRatio));
}

AboutWidget::~AboutWidget()
{
    delete ui;
}

main.cpp

#include "mainwindow.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;

    w.show();
    return a.exec();
}

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFontDialog>
#include <QColorDialog>
#include <QFile>
#include <QFileDialog>
#include <QMessageBox>
#include <QTextStream>
#include <QTextCodec>
#include <QDesktopServices>
#include "aboutwidget.h"
#include "topdf.h"
// #pragma execution_character_set("utf-8")
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);


    // 设置文本框为单工作区
    setCentralWidget(ui->textEdit);

    font = QFont("宋体",18,QFont::Normal,true);
    color = QColor(Qt::black);

    // 工具条,项目默认生成一个
    // 工具条上放的是菜单常用的菜单项
    // 所以工具条和菜单共用QAction,得通过代码添加
    ui->toolBar->addAction(ui->actionne);
    ui->toolBar->addAction(ui->actionopen);
    ui->toolBar->addAction(ui->actionsave);
    ui->toolBar->addAction(ui->actionPDF);
    ui->toolBar->addAction(ui->actionundo);
    ui->toolBar->addAction(ui->actionredo);
    ui->toolBar->addAction(ui->actioncopy);
    ui->toolBar->addAction(ui->actionpatse);
    ui->toolBar->addAction(ui->actioncolor);
    ui->toolBar->addAction(ui->actionfont);
    ui->toolBar->addAction(ui->actioncut);
    ui->toolBar->addSeparator();
    ui->toolBar->addAction(ui->actionexit);




}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::on_actionexit_triggered()
{
    close();
}


void MainWindow::on_actioncolor_triggered()
{
    QColor c = QColorDialog::getColor(color,this,"颜色选择框");
    if(c.isValid()){
        color = c;

        // 设置文本框的文本颜色
        // 1. 从光标开始新输入的文本颜色被设置
        // 2. 鼠标选中的文本颜色设置
        ui->textEdit->setTextColor(c);
    }
}

void MainWindow::on_actionfont_triggered()
{
    bool ok; // 用户字体对话框保存是否选择了字体的结构

    // 第一个参数是判断用户是否选择了字体,第二个是字体对话框的初始值
    QFont f = QFontDialog::getFont(&ok,font,this,"选择文本框要设置的字体");

    if(ok){
        font = f;

        // 1. 从当前光标开始
        // 2. 鼠标选中的文本的字体
        ui->textEdit->setCurrentFont(f);
    }

}

void MainWindow::on_actionne_triggered()
{
    QMessageBox::warning(this,tr("Warning"),
    tr("创建新文件?"),
    QMessageBox::Yes | QMessageBox::Default,
    QMessageBox::No);

    currentFile.clear();
    ui->textEdit->setText(QString());

}

void MainWindow::on_actionopen_triggered()
{
    QString fileName = QFileDialog::getOpenFileName(this, "打开文件");
    QFile file(fileName);
    currentFile = fileName;
    if (!file.open(QIODevice::ReadOnly | QFile::Text)) {
        QMessageBox::warning(this, "警告", "无法打开文件: " + file.errorString());
        return;
     }
     setWindowTitle(fileName);
     QTextStream *in = new QTextStream(&file);
     in->setCodec("UTF-8");
     QString text = in->readAll();

     ui->textEdit->setText(text);
     delete in;
     file.close();
}

void MainWindow::on_actionsave_triggered()
{
    QString fileName;
    // 若没有文件,重新创建一个
    if (currentFile.isEmpty()) {
        fileName = QFileDialog::getSaveFileName(this, "Save");
        currentFile = fileName;
    } else {
        fileName = currentFile;
    }

    // 打开文件
    QFile file(fileName);
    if (!file.open(QIODevice::WriteOnly | QFile::Text)) {
        QMessageBox::warning(this, "警告", "无法打开文件: " + file.errorString());
        return;
    }
    setWindowTitle(fileName);
    QTextStream out(&file);

    out.setCodec("UTF-8");

    QString text = ui->textEdit->toPlainText();
    out << text;
    file.close();

}

void MainWindow::on_actionasfile_triggered()
{
    QString fileName = QFileDialog::getSaveFileName(this, "另存为");
    QFile file(fileName);

    if (!file.open(QFile::WriteOnly | QFile::Text)) {
        QMessageBox::warning(this, "警告", "无法打开文件: " + file.errorString());
        return;
    }
    currentFile = fileName;
    setWindowTitle(fileName);
    QTextStream out(&file);
    QString text = ui->textEdit->toPlainText();
    out << text;
    file.close();

}

void MainWindow::on_actioncut_triggered()
{
    ui->textEdit->cut();
}

void MainWindow::on_actioncopy_triggered()
{
    ui->textEdit->copy();
}


void MainWindow::on_actionundo_triggered()
{
    ui->textEdit->undo();
}

void MainWindow::on_actionredo_triggered()
{
    ui->textEdit->redo();
}

void MainWindow::on_actionpatse_triggered()
{
    ui->textEdit->paste();
}

void MainWindow::on_actionAbout_triggered()
{
    static AboutWidget about;
    about.show();
}

void MainWindow::on_actionAboutQT_triggered()
{
    QDesktopServices::openUrl(QUrl(QLatin1String("https://www.qt.io/zh-cn/")));
}

void MainWindow::on_actionPDF_triggered()
{
    static ToPdf pdf;
    pdf.show();
}

topdf.cpp

#include "topdf.h"
#include "ui_topdf.h"

#include <QFileDialog>
#include <QMessageBox>
#include <QPainter>
#include <QtPrintSupport/QPrinter>
ToPdf::ToPdf(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ToPdf)
{
    ui->setupUi(this);
}

ToPdf::~ToPdf()
{
    delete ui;
}

bool ToPdf::pictureToPDF(QString sourth, QString sDir)
{

    try
    {
        QPixmap pixmap(sourth);
        //图片生成pdf
        QPrinter printerPixmap(QPrinter::HighResolution);
        printerPixmap.setPageSize(QPrinter::Custom);  //设置纸张大小为A4
        printerPixmap.setOutputFormat(QPrinter::PdfFormat);  //设置输出格式为pdf
        printerPixmap.setOutputFileName(sDir);   //设置输出路径

        double dHeight = 300;
        double dWidth = (double)pixmap.width() / (double)pixmap.height() * dHeight;
        printerPixmap.setPageSizeMM(QSize(dWidth, dHeight));
        printerPixmap.setPageMargins(0, 0, 0, 0, QPrinter::DevicePixel);

        QPainter painterPixmap;
        painterPixmap.begin(&printerPixmap);
        QRect rect = painterPixmap.viewport();
        float multiple = (double(rect.width()) / pixmap.width());
        float yMultiple = (double(rect.height()) / pixmap.height());
        float fMin = (multiple < yMultiple) ? multiple : yMultiple;
        painterPixmap.scale(fMin, fMin); //将图像(所有要画的东西)在pdf上放大multiple-1倍
        painterPixmap.drawPixmap(0, 0, pixmap.width(), pixmap.height(), pixmap);  //画图
        painterPixmap.end();

        return true;
    }
    catch (...)
    {
        return false;
    }


}

void ToPdf::on_pictureBtn_clicked()
{
    //定义文件对话框类
    QFileDialog *fileDialog = new QFileDialog(this);
    //定义文件对话框标题
    fileDialog->setWindowTitle(tr("选择图片"));

    //设置默认文件路径
    //fileDialog->setDirectory(".");

    //设置文件过滤器
    fileDialog->setNameFilter(tr("Images(*.png *.jpg *.jpeg *.bmp)"));
    //设置可以选择多个文件,默认为只能选择一个文件QFileDialog::ExistingFiles
    //fileDialog->setFileMode(QFileDialog::ExistingFiles);
    //设置视图模式
    fileDialog->setViewMode(QFileDialog::Detail);
    //打印所有选择的文件的路径

    // 获取选择的文件名
    QStringList fileNameList;

    // exec()模态对话框
    if(fileDialog->exec()){

        fileNameList = fileDialog->selectedFiles();
    }
    ui->pictureFileName->setText(fileNameList[0]);
    //emit fileName(fileNameList);
}

void ToPdf::on_saveBtn_clicked()
{
    //定义文件对话框类
    QFileDialog *fileDialog = new QFileDialog(this);
    //定义文件对话框标题
    fileDialog->setWindowTitle(tr("选择PDF"));
    fileDialog->setViewMode(QFileDialog::Detail);
    //打印所有选择的文件的路径

    //设置文件过滤器
    fileDialog->setNameFilter(tr("*.pdf"));
    // 获取选择的文件名
    QStringList fileNameList;

    // exec()模态对话框
    if(fileDialog->exec()){

        fileNameList = fileDialog->selectedFiles();
    }

    ui->saveFileName->setText(fileNameList[0]);

}

void ToPdf::on_startBtn_clicked()
{
    QString picture = ui->pictureFileName->text();
    QString pdf = ui->pictureFileName->text();

    if(pictureToPDF(picture,pdf)){
        QMessageBox::information(this,"转换成功","转换成功!!!");
    }else{
        QMessageBox::information(this,"转换失败","转换失败!");

    }
}

4. 改进

如果您发现我的代码有些什么不足之处,请私信或者评论区告诉我,我会及时改正,转载请注明出处


有许多改进的地方

  • 首先是图片转PDF这块,需要选中一个pdf文件,而不是选中目录
  • 然后可以写一个PDF转图片,加一些小功能,水印什么的
  • 然后可以开始兼容doc,docx文件,实现一个小小的wps
  • 然后程序里没有用到多线程,有些时候会卡顿,有些地方没有异常处理,会造成闪退

总之,如果你真想用这个软件来编辑文本,那还是很难受的,不好用,但是作为练手的项目来说,还不错
最后,如果我以后有时间的话,会对这个项目进行改进,到时候会分享到博客当中,所以好奇的小伙伴可以点个关注哈哈哈


然后,准备去查漏补缺C++的一些基础知识了,到时候也会写成博客分享给大家
posted @ 2021-07-04 16:30  进击的汪sir  阅读(1071)  评论(0编辑  收藏  举报