zl程序教程

您现在的位置是:首页 >  其他

当前栏目

Qt5开发从入门到精通——第五篇二节( 文本编辑器 Easy Word 开发 V1.1 详解 )

入门开发 详解 精通 word Easy 文本编辑 QT5
2023-09-27 14:19:51 时间

欢迎小伙伴的点评✨✨,相互学习、互关必回、全天在线🍳🍳🍳
博主🧑🧑 本着开源的精神交流Qt开发的经验、将持续更新续章,为社区贡献博主自身的开源精神👩‍🚀


前言

本章节会给大家带来基于文本编辑器 Easy Word V1.0框架开发升级到Easy Word V1.1框架触发信号调用槽函数开发的解析。


一、文本编辑器 Easy Word V1.1 槽函数与框架连接解析

1.1、新建文件

(1) 打开 “mainwindow.h” 头文件,添加 "private slots: "变量:

private slots:
void ShowNewFile();  

(2) 在 createActions() 函数的”“新建“动作“最后添加事件关联:

connect(NewFileAction, SIGNAL (triggered()) , this, SLOT (ShowNewFile())) ;

(3) 实现新建文件功能的函数 ShowNewFile()如下:

void MainWindow::ShowNewFile()                  //新建文件的槽
{
    MainWindow *newMainWindow =new MainWindow;
    newMainWindow->show();
}

1.2、打开文件

利用标准文件对话框 QFileDialog 打开一个已经存在的文件。若当前中央窗体中已有打开的文件,则在一个新的窗口中打开选定的文件;若当前中央窗体是空白的,则在当前中央窗体中打开。
(1)在mainwindow.h中添加如下头文件

#include <QFileDialog>
#include <QFile>
#include <QTextStream>

(2)在 “mainwindow.h” 头文件中添加 "private slots: "变量:

void ShowOpenFile(); 

(3)在 createActions() 函数的”“打开“动作“最后添加事件关联:

connect(openFileAction,SIGNAL(triggered()),this,SLOT(ShowOpenFile()));

(4)实现打开文件功能的函数 ShowOpenFile()如下:

void MainWindow::ShowOpenFile()                  //读取文件的槽
{
    fileName =QFileDialog::getOpenFileName(this);
    if(!fileName.isEmpty())
    {
        if(showWidget->text->document()->isEmpty())
        {
            loadFile(fileName);
        }else
        {
            MainWindow *newMainWindows = new MainWindow;
            newMainWindows->show();
            newMainWindows->loadFile(fileName);
        }


    }
}

其中,loadFile()函数的实现如下,该函数利用 QFile 和 QTextStream 完成具体读取文件内容的工作
注意读取文本时文本格式应该是ANSI格式否则会出现乱码

void MainWindow::loadFile(QString filename)
{

     QFile  file(filename);

    if(file.open(QIODevice::ReadOnly|QIODevice::Text))
    {
         QTextStream textStream(&file);
        while(!textStream.atEnd())
        {


            showWidget->text->append(textStream.readLine());


        }


    }
}

在此仅详细说明标准文件对话框 QFileDialog 的 getOpenFileName()静态函数各个参数的作用,其他文件对话框类中相关的静态函数的参数有与其类似之处。

QString QFileDialog::getOpenFileName
(
	QWidget* parent=O,               //定义标准文件对话框的父窗口
	const QString & caption=QString(), //定义标准文件对话框的标题名
	const QString & dir=QString (),  //指定了默认的目录,若此参数带有文件名,
	                                //则文件将是默认选中的文件。
	const QString & filter=QString (), // 此参数对文件类型进行过滤,只有与过滤器匹配的文件
                                      // 类型才显示,可以同时指定多种过滤方式供用户选择,
                                      //多种过滤器之间用";;"隔开。
	QString * selectedFilter=0,      //用户选择过滤器通过此参数返回
	Options options=O
	
	
);

1.3、打印文件

QPrintDialog 是 Qt 提供的标准打印对话框,为打印机的使用提供了一种方便、规范的方法。QPrintDialog 标准打印对话框提供了打印机的选择、配置功能,并允许用户改变文档有关的设置,如页面范围、打印份数等。
(1)在mainwindow.h中添加如下头文件

#include <QtPrintSupport/QPrintDialog>  //打印文本
#include <QtPrintSupport/QPrinter>
#include <QPainter>   

(2)在ImageProcessor.pro中添加

#打印功能需要添加QT += printsupport
QT += printsupport

(3)在" mainwindow.h" 头文件中添加 "private slots: "变量:

void ShowPrintText();

(4)在 createActions() 函数的”“打印文本“动作“最后添加事件关联:

 connect (PrintTextAction, SIGNAL (triggered()), this, SLOT (ShowPrintText ()));

(5)实现打印文本功能的函数 ShowPrintText ()如下:

void MainWindow::ShowPrintText()             //文本打印
{
    QPrinter printer;                      //新建一个 QPrinter 对象
    QPrintDialog printDialog(&printer,this); //创建一个 QPrintDialog 对象,
                                            //参数为 QPrinter对象。
    if(printDialog.exec())//判断标准打印对话框显示后用户是否单击“打印”按钮。若单击
                          //“打印”按钮,则相关打印属性将可以通过创建 QPrintDialog 对象时使用的                                           
                          //QPrinter 对象获得;若用户单击“取消”按钮,则不执行后续的打印操作。
    {
        //获得QTextEdit对象的文档
        QTextDocument *doc =showWidget->text->document();
        doc->print(&printer); //打印
    }
}

1.4、图像打印

打印图像实际上是在一个 QPaintDevice 中画图,与平常在 QWidget 、 QPixmap 和 Qlmage中画图相同,都是创建一个 QPainter 对象进行画图,只是打印使用的是 QPrinter, QPrinter 本质上也是一个绘图设备 QPaintDevice。
(1)在mainwindow.h中添加如下头文件

#include <QPainter>               //打印图片

(2)在" mainwindow.h" 头文件中添加 "private slots: "变量:

 void ShowPrintImage();

(3)在 createActions()函数的”“打印图像“动作“最后添加事件关联:

connect(PrintImageAction, SIGNAL (triggered()), this, SLOT (ShowPrintImage()));

(4)实现打印图像功能的函数 ShowPrintImage()如下:

void MainWindow::ShowPrintImage()           //图像打印
{
    QPrinter printer;                    //新建一个 QPrinter 对象
    QPrintDialog printDialog(&printer,this);  //创建一个 QPrintDialog 对象,
                                             // 参数为 QPrinter对象。
    if(printDialog.exec())   // 判断打印对话框显示后用户是否单击
    {
        QPainter painter(&printer);     //创建一个 QPainter 对象,并指定绘图设备为
                                        //一个QPrinte对象。
        QRect rect =painter.viewport();   //获得QPainter对象的视图矩形区域
        QSize size = img.size();          //获得图像的大小
        /*按照图形的比例大小重新设置视图矩形区域*/
        size.scale(rect.size(), Qt::KeepAspectRatio);
        painter.setViewport(rect.x(),rect.y(),size.width(),size.height());
        ///设置 QPainter 窗口大小为图像的大小
        painter.setWindow(img.rect());
        ///打印图像
        painter.drawImage(0,0,img);

    }
}

二、效果实例

图一
在这里插入图片描述
图二
图标和图片放到新建的Resources中
在这里插入图片描述

三、原码解析

工程文件(包含图标)已经上传GitHub,通过git直接拉取即可

git clone https://github.com/dhn111/EasyWord.git

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QImage>
#include <QLabel>
#include <QMenu>
#include <QMenuBar>
#include <QAction>
#include <QComboBox>
#include <QSpinBox>
#include <QToolBar>
#include <QFontComboBox>
#include <QToolButton>
#include <QTextCharFormat>
#include "showwidget.h"
#include <QApplication>
#include <QFileDialog>
#include <QFile>
#include <QTextStream>
#include <QtPrintSupport/QPrintDialog>  //打印文本
#include <QtPrintSupport/QPrinter>
#include <QPainter>
#include <QPainter>               //打印图片

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();
    void createActions();       //创建动作
    void createMenus();         //创建菜单
    void createToolBars ();     //创建工具栏
    void loadFile(QString filename);
    void mergeFormat(QTextCharFormat);

private:
    QMenu *fileMenu;                     //各项菜单栏
    QMenu *zoomMenu;
    QMenu *rotateMenu;
    QMenu *mirrorMenu;
    QImage img;
    QString fileName;
    ShowWidget *showWidget;
    QAction *openFileAction;          //文件菜单项
    QAction *NewFileAction;
    QAction *PrintTextAction;
    QAction *PrintImageAction;
    QAction *exitAction;
    QAction *copyAction;           //编辑菜单项
    QAction *cutAction;
    QAction *pasteAction;
    QAction *aboutAction;
    QAction *zoomInAction;
    QAction *zoomOutAction;
    QAction *rotate90Action;       //旋转菜单项
    QAction *rotate180Action;
    QAction *rotate270Action;
    QAction *mirrorVerticalAction;     //镜像菜单项
    QAction *mirrorHorizontalAction;
    QAction *undoAction;
    QAction *redoAction;
    QToolBar *fileTool;              //工具栏
    QToolBar *zoomTool;
    QToolBar *rotateTool;
    QToolBar *mirrorTool;
    QToolBar *doToolBar;
private slots:
void ShowNewFile();
void ShowOpenFile();
void ShowPrintText();
void ShowPrintImage();

};

#endif // MAINWINDOW_H


showwidget.h

#ifndef SHOWWIDGET_H
#define SHOWWIDGET_H

#include <QWidget>
#include <QImage>
#include <QLabel>
#include <QTextEdit>
#include <QHBoxLayout>
class ShowWidget : public QWidget
{
    Q_OBJECT
public:
    explicit ShowWidget(QWidget *parent = nullptr);

    QImage img;
    QLabel *imageLabel;
    QTextEdit *text;


signals:

public slots:
};

#endif // SHOWWIDGET_H


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"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{

    //各项菜单栏
    fileMenu = new QMenu;
    zoomMenu = new QMenu;
    rotateMenu = new QMenu;
    mirrorMenu = new QMenu;
    showWidget = new ShowWidget;


    //文件菜单
    openFileAction =new QAction;
    NewFileAction  =new QAction;
    PrintTextAction =new QAction;
    PrintImageAction =new QAction;
    exitAction       = new QAction;

     //缩放菜单
     copyAction   =new QAction;
     cutAction    =new QAction;
     pasteAction  =new QAction;
     aboutAction  =new QAction;
     zoomInAction =new QAction;
     zoomOutAction=new QAction;

     //旋转菜单项
     rotate90Action =new QAction;
     rotate180Action=new QAction;
     rotate270Action=new QAction;

     //镜像菜单项
     mirrorVerticalAction  =new QAction;
     mirrorHorizontalAction=new QAction;
     undoAction  =new QAction;
     redoAction  =new QAction;

     //工具栏
     fileTool = new  QToolBar;
     zoomTool = new  QToolBar;
     rotateTool = new  QToolBar;
     mirrorTool = new  QToolBar;
     doToolBar = new  QToolBar;

    setWindowTitle(tr("Easy Word"));  //设置窗体标题
    showWidget =new ShowWidget(this); //(a)
    setCentralWidget(showWidget);
    /*创建动作、菜单、工具栏的函数*/
    createActions() ;
    createMenus();
    createToolBars();
    if(img.load(":/src/PKQ.png"))
    {
        //在 imageLabel 对象中放置图片
        showWidget->imageLabel->setPixmap(QPixmap::fromImage(img));
    }
}

MainWindow::~MainWindow()
{

}

void MainWindow::createActions()
{
    //“打开”动作
    openFileAction =new QAction(QIcon(":/src/open.png"),tr("打开"),this);  //(a)
    openFileAction->setShortcut (tr ("Ctrl+O"));                      //(b)
    openFileAction->setStatusTip(tr("打开一个文件 "));                 //(c)
    connect(openFileAction,SIGNAL(triggered()),this,SLOT(ShowOpenFile()));

    //"新建“动作
    NewFileAction =new QAction(QIcon(":/src/new.png"),tr("新建"),this);
    NewFileAction->setShortcut(tr("Ctrl+N"));
    NewFileAction->setStatusTip(tr("新建一个文件"));
    connect(NewFileAction, SIGNAL (triggered()) , this, SLOT (ShowNewFile())) ;

    // "退出“动作
    exitAction =new QAction(tr("退出"),this);
    exitAction->setShortcut(tr("Ctrl+Q"));
    exitAction->setStatusTip(tr("退出程序")) ;
    connect (exitAction, SIGNAL (triggered()), this, SLOT (close()));
    // "复制”动作
    copyAction =new QAction(QIcon(":/src/copy.png"),tr("复制"),this);
    copyAction->setShortcut(tr("Ctrl+C"));
    copyAction->setStatusTip(tr(" 复制文件")) ;
    connect(copyAction,SIGNAL( triggered ()), showWidget->text, SLOT(copy()));
    //"剪切“动作
    cutAction =new QAction(QIcon(":/src/cut.png"),tr("剪切"),this);
    cutAction->setShortcut(tr("Ctrl+X"));
    cutAction->setStatusTip(tr("剪切文件")) ;
    connect(cutAction,SIGNAL( triggered ()), showWidget->text, SLOT (cut()));
    //"粘贴“动作
    pasteAction =new QAction(QIcon(":/src/paste.png"),tr("粘贴"),this);
    pasteAction->setShortcut(tr("Ctrl+V"));
    pasteAction->setStatusTip(tr("粘贴文件")) ;
    connect(pasteAction,SIGNAL(triggered()),showWidget->text,SLOT (paste()));
    //"关于“动作
    aboutAction =new QAction(tr("关于"),this);
    connect(aboutAction,SIGNAL(triggered()),this,SLOT(QApplication::aboutQt()));
    //"打印文本“动作
    PrintTextAction =new QAction(QIcon(":/src/printText.png"),tr(" 打印文本"), this);
    PrintTextAction->setStatusTip(tr("打印一个文本"));
    connect (PrintTextAction, SIGNAL (triggered()), this, SLOT (ShowPrintText ()));

    //"打印图片“动作
    PrintImageAction =new QAction(QIcon (":/src/printimage.png" ), tr("打印图片"), this);
    PrintImageAction->setStatusTip(tr("打印一幅图片"));
    connect(PrintImageAction, SIGNAL (triggered()), this, SLOT (ShowPrintImage()));

    //"放大“动作
    zoomInAction =new QAction (QIcon(":/src/zoomin.png"),tr(" 放大 "),this);
    zoomInAction->setStatusTip(tr("放大一幅图片"));
    //"缩小“动作
    zoomOutAction =new QAction(QIcon(":/src/zoomout.png"),tr("缩小 "),this);
    zoomOutAction->setStatusTip(tr("缩小一幅图片 "));
    //实现图片旋转的动作 (Action)
    //旋转 90°
    rotate90Action =new QAction (QIcon (":/src/rotate90.png"), tr("旋转 90°") ,this);
    rotate90Action->setStatusTip(tr("将一幅图旋转90°"));
    //旋转180°
    rotate180Action =new QAction (QIcon(":/src/rotate180.png"), tr("旋转 180°"), this);
    rotate180Action->setStatusTip(tr("将一幅图旋转180°"));
    //旋转270°
    rotate270Action =new QAction(QIcon (":/src/rotate270.png"), tr("旋转 270°"), this);
    rotate270Action->setStatusTip(tr("将一幅图旋转 270°"));
    //实现图片镜像的动作(Action)
    //纵向镜像
    mirrorVerticalAction =new QAction(QIcon(":/src/mirrorVertical.png"),tr("纵向镜像"), this);
    //横向镜像
    mirrorHorizontalAction =new QAction(QIcon(":/src/mirrorHorizontal.png"),tr("横向镜像 "),this);
    mirrorHorizontalAction->setStatusTip( tr(" 对一幅图做横向镜像")) ;
    //实现撤销和重做的动作(ACtion)
    //撤销和重做
    undoAction =new QAction (QIcon(":/src/undo.png"),"撤销",this);
    connect(undoAction,SIGNAL(triggered()),showWidget->text,SLOT(undo()));
    redoAction =new QAction(QIcon(":/src/redo.png"),"重做",this);
    connect(redoAction, SIGNAL(triggered()),showWidget->text,SLOT(redo()));




}

void MainWindow::createMenus()
{
    //文件菜单

    fileMenu =menuBar()->addMenu(tr("文件")) ;
    fileMenu->addAction(openFileAction);
    fileMenu->addAction(NewFileAction);
    fileMenu->addAction(PrintTextAction);
    fileMenu->addAction(PrintImageAction);
    fileMenu->addSeparator();
    fileMenu->addAction(exitAction);
    //缩放菜单

    zoomMenu =menuBar()->addMenu(tr("编辑")) ;
    zoomMenu->addAction(copyAction);
    zoomMenu->addAction(cutAction);
    zoomMenu->addAction(pasteAction);
    zoomMenu->addAction(aboutAction);
    zoomMenu->addSeparator();
    zoomMenu->addAction(zoomInAction);
    zoomMenu->addAction(zoomOutAction);
    //旋转菜单
    rotateMenu =menuBar ()->addMenu(tr("旋转")) ;
    rotateMenu->addAction(rotate90Action);
    rotateMenu->addAction(rotate180Action);
    rotateMenu->addAction(rotate270Action);
    //镜像菜单
    mirrorMenu =menuBar()->addMenu(tr(" 镜像")) ;
    mirrorMenu->addAction(mirrorVerticalAction);
    mirrorMenu->addAction(mirrorHorizontalAction);
}


void MainWindow::createToolBars()
{
    //文件工具条
    fileTool =addToolBar("File");
    fileTool->addAction(openFileAction);
    fileTool->addAction(NewFileAction);
    fileTool->addAction(PrintTextAction);
    fileTool->addAction(PrintImageAction);
    //编辑工具条
    zoomTool =addToolBar("Edit");
    zoomTool->addAction(copyAction);
    zoomTool->addAction(cutAction);
    zoomTool->addAction(pasteAction);
    zoomTool->addSeparator();
    zoomTool->addAction(zoomInAction);
    zoomTool->addAction(zoomOutAction);
    //旋转工具条
    rotateTool =addToolBar("rotate");
    rotateTool->addAction(rotate90Action);
    rotateTool->addAction(rotate180Action);
    rotateTool->addAction(rotate270Action);
    //撤销和重做工具条
    doToolBar =addToolBar("doEdit");
    doToolBar->addAction(undoAction);
    doToolBar->addAction(redoAction);

}

void MainWindow::ShowNewFile()                  //新建文件的槽
{
    MainWindow *newMainWindow =new MainWindow;
    newMainWindow->show();
}
void MainWindow::ShowOpenFile()                  //读取文件的槽
{
    fileName =QFileDialog::getOpenFileName(this);
    if(!fileName.isEmpty())
    {
        if(showWidget->text->document()->isEmpty())
        {
            loadFile(fileName);
        }else
        {
            MainWindow *newMainWindows = new MainWindow;
            newMainWindows->show();
            newMainWindows->loadFile(fileName);
        }


    }
}
void MainWindow::loadFile(QString filename)
{

     QFile  file(filename);

    if(file.open(QIODevice::ReadOnly|QIODevice::Text))
    {
         QTextStream textStream(&file);
        while(!textStream.atEnd())
        {


            showWidget->text->append(textStream.readLine());


        }


    }
}
void MainWindow::ShowPrintText()             //文本打印
{
    QPrinter printer;                      //新建一个 QPrinter 对象
    QPrintDialog printDialog(&printer,this); //创建一个 QPrintDialog 对象,
                                            //参数为 QPrinter对象。
    if(printDialog.exec())//判断标准打印对话框显示后用户是否单击“打印”按钮。若单击
                          //“打印”按钮,则相关打印属性将可以通过创建 QPrintDialog 对象时使用的
                          //QPrinter 对象获得;若用户单击“取消”按钮,则不执行后续的打印操作。
    {
        //获得QTextEdit对象的文档
        QTextDocument *doc =showWidget->text->document();
        doc->print(&printer); //打印
    }
}

void MainWindow::ShowPrintImage()           //图像打印
{
    QPrinter printer;                    //新建一个 QPrinter 对象
    QPrintDialog printDialog(&printer,this);  //创建一个 QPrintDialog 对象,
                                             // 参数为 QPrinter对象。
    if(printDialog.exec())   // 判断打印对话框显示后用户是否单击
    {
        QPainter painter(&printer);     //创建一个 QPainter 对象,并指定绘图设备为
                                        //一个QPrinte对象。
        QRect rect =painter.viewport();   //获得QPainter对象的视图矩形区域
        QSize size = img.size();          //获得图像的大小
        /*按照图形的比例大小重新设置视图矩形区域*/
        size.scale(rect.size(), Qt::KeepAspectRatio);
        painter.setViewport(rect.x(),rect.y(),size.width(),size.height());
        ///设置 QPainter 窗口大小为图像的大小
        painter.setWindow(img.rect());
        ///打印图像
        painter.drawImage(0,0,img);

    }
}

showwidget.cpp

#include "showwidget.h"

ShowWidget::ShowWidget(QWidget *parent) : QWidget(parent)
{
    imageLabel =new QLabel;
    imageLabel->setScaledContents( true);
    text =new QTextEdit;
    QHBoxLayout *mainLayout =new QHBoxLayout(this);
    mainLayout->addWidget(imageLabel);
    mainLayout->addWidget(text);
}



四、总结

窗口构成会在应用程序开发中经常用到的