Qt:多文档(MDI)文档处理软件思路01

文档处理软件是我们日常生活中最为常用的软件之一。在此以将记事本为例子,实现的基本思路描述。

一:基本外观功能。

1)有菜单栏和按钮,根据不同的实现功能,将按钮添加到菜单中,并且添加工具栏。

2)主窗口显示(在此不同于记事本,为多文本窗口)。

在Qt中按钮的显示以QAction来替代,菜单和工具栏为QMenu和QToolBar,部分代码如下:

    //in file menu.
    QAction* pActionNew;
    QAction* pActionOpen;
    QAction* pActionSave;
    QAction* pActionSaveAs;
    QAction* pActionExportPdf;
    QAction* pActionExit;

    QMenu* pMenuFile;
    QMenu* pMenuWindow;

因为主窗口是多文档显示,所以要在主窗口添加QMdiArea,以保存多文档。

QMdiArea* pMdiArea;


因为每个QAction实例都需对应一个相应的方法,故声明new、open、save、saveas、print、exit等file菜单需调用的方法。

以下为完整的mainwindow.h文件:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

class QMdiArea;
class QAction;
class TextEditor;
class QMenu;
class QActionGroup;
class TextEditor;
class QCloseEvent;
class QDragEnterEvent;

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

protected:
    virtual void closeEvent(QCloseEvent* cle);

private:
    void setupFileMenuActions();

    void setupMenusAndToolbar();

    /**
      @brief add TextEditor instance to MDIArea.
      @param editor TextEditor instance.
    */
    void addEditor(TextEditor* editor);

    /**
      @brief new a file in MDIArea.
    */
    void newFile();

    /**
      @brief open a exist file.
    */
    void openFile();

    /**
      @brief save file in defalut configuration.
    */
    bool save();

    /**
      @brief save file by user option.
    */
    bool saveAs();

    /**
      @brief export file in pdf format.
    */
    void exportInPdfFormat();

    /**
      @brief find the active TextEditor and return it.
      @return active TextEditor instance in MDIArea.
    */
    TextEditor* activeEditor();

private:
    Ui::MainWindow *ui;

    //in file menu.
    QAction* pActionNew;
    QAction* pActionOpen;
    QAction* pActionSave;
    QAction* pActionSaveAs;
    QAction* pActionExportPdf;
    QAction* pActionExit;

    QMenu* pMenuFile;
    QMenu* pMenuWindow;

    QMdiArea* pMdiArea;
    QActionGroup* pWindowMenuGroup;

    static QString mResWinPath;
};

#endif // MAINWINDOW_H

因为此程序为多窗口(Mdi)程序,所以针对程序中不同的文本框有不同的配置,例如文档保存情况,是否为active,不同的文件名及路径,所以将具体对文档的操作实现在文档类中(QTextEdit的子类),mainwindow只是对其的具体调用。

以下是mainwindow.cpp的具体实现:

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QMdiArea>
#include <QAction>
#include <QMenu>
#include <QMdiSubWindow>
#include <QActionGroup>
#include <QCloseEvent>
#include <QDragEnterEvent>

#include "texteditor.h"

QString MainWindow::mResWinPath = ":/images/win/";

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    pMdiArea(new QMdiArea(this)),
    pWindowMenuGroup(new QActionGroup(this))
{
    ui->setupUi(this);
    setCentralWidget(pMdiArea);

    setupFileMenuActions();

    setupMenusAndToolbar();

    setAttribute(Qt::WA_DeleteOnClose);
    setAcceptDrops(true);
}

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

void MainWindow::closeEvent(QCloseEvent* cle)
{
    pMdiArea->closeAllSubWindows();

    if ( !pMdiArea->subWindowList().isEmpty()) {
        cle->ignore();
    } else {
        cle->accept();
    }
}

void MainWindow::setupFileMenuActions()
{
    pActionNew = new QAction(QIcon(MainWindow::mResWinPath + "filenew.png"),
                             tr("&New"),
                             this);
    pActionNew->setShortcut(QKeySequence::New);
    pActionNew->setPriority(QAction::LowPriority);
    pActionNew->setStatusTip(tr("Create a new file"));
    connect(pActionNew, &QAction::triggered, this, &MainWindow::newFile);

    pActionOpen = new QAction(QIcon(MainWindow::mResWinPath + "fileopen.png"),
                              tr("&Open"),
                              this);
    pActionOpen->setShortcut(QKeySequence::Open);
    pActionOpen->setPriority(QAction::LowPriority);
    pActionOpen->setStatusTip(tr("Open a file"));
    connect(pActionOpen, &QAction::triggered, this, &MainWindow::openFile);

    pActionSave = new QAction(QIcon(MainWindow::mResWinPath + "filesave.png"),
                              tr("&Save"),
                              this);
    pActionSave->setShortcut(QKeySequence::Save);
    pActionSave->setStatusTip(tr("save this file"));

    pActionSaveAs = new QAction(tr("Save As"), this);
    pActionSaveAs->setShortcut(QKeySequence::SaveAs);
    pActionSaveAs->setStatusTip(tr("Save this file as..."));
    connect(pActionSaveAs, &QAction::triggered, this, &MainWindow::saveAs);

    pActionExportPdf = new QAction(QIcon(MainWindow::mResWinPath + "exportpdf.png"),
                                   tr("Export Pdf"),
                                   this);
    pActionExportPdf->setStatusTip(tr("export file in pdf format"));
    connect(pActionExportPdf, &QAction::triggered, this, &MainWindow::exportInPdfFormat);

    pActionExit = new QAction(tr("E&xit"), this);
    pActionExit->setShortcut(QKeySequence::Quit);
    pActionExit->setStatusTip(tr("Exit this application"));
    connect(pActionExit, &QAction::triggered, qApp, &QApplication::closeAllWindows);
}

void MainWindow::setupMenusAndToolbar()
{
    pMenuFile = ui->menuBar->addMenu(tr("&File"));
    pMenuFile->addAction(pActionNew);
    pMenuFile->addAction(pActionOpen);
    pMenuFile->addAction(pActionSaveAs);
    pMenuFile->addAction(pActionExportPdf);
    pMenuFile->addAction(pActionExit);

    QToolBar* tb = addToolBar(tr("FileToolBar"));
    tb->addAction(pActionNew);
    tb->addAction(pActionOpen);
    tb->addAction(pActionSave);
    tb->addAction(pActionExportPdf);

    pMenuWindow = ui->menuBar->addMenu(tr("&Window"));
}

void MainWindow::addEditor(TextEditor* editor)
{
    //Add action to windowMenuGroup for RadioGroup.
    pMenuWindow->addAction(editor->windowMenuAction());
    pWindowMenuGroup->addAction(editor->windowMenuAction());

    QMdiSubWindow* subWindow = pMdiArea->addSubWindow(editor);
    subWindow->show();
    subWindow->setFocus();
}

void MainWindow::newFile()
{
    //Create a new editor and add it to MDIArea.
    TextEditor* editor(new TextEditor(this));
    editor->newFile();
    addEditor(editor);
}

void MainWindow::openFile()
{
    //Call TextEditor::open method for user to choose file.
    TextEditor* editor = TextEditor::open(this);

    //true If choose file successfully,add the file to MDIArea.
    if ( editor) {
        addEditor(editor);
    }
}

bool MainWindow::save()
{
    TextEditor* editor = activeEditor();

    if ( editor) {
        return editor->save();
    } else {
        return false;
    }
}

bool MainWindow::saveAs()
{
    TextEditor* editor = activeEditor();

    if ( editor) {
        return editor->saveAs();
    }

    return false;
}

void MainWindow::exportInPdfFormat()
{
    TextEditor* editor = activeEditor();

    if ( editor) {
        editor->fileExportToPDF();
    }
}

TextEditor* MainWindow::activeEditor()
{
    QMdiSubWindow* subWindow = pMdiArea->activeSubWindow();

    if ( subWindow) {
        return qobject_cast<TextEditor*>(subWindow->widget());
    } else {
        return 0;
    }
}


你可能感兴趣的:(Qt:多文档(MDI)文档处理软件思路01)