利用QT5实现一个简单的模拟Word软件

利用QT5实现一个简单的模拟Word软件,该软件的基本功能包括:
基本框架实现:建立MDI程序框架、菜单系统设计、工具栏设计、子窗口管理
基本编辑功能实现:打开文件、保存文件、文本操作
文档排版美化功能实现:字体格式设置、段落对齐设置、颜色设置、段落标号、编号、文档打印与预览

头文件及项目文件

songchao.pro //项目文件

#-------------------------------------------------
#
# Project created by QtCreator 2018-12-05T15:17:29
#
#-------------------------------------------------

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
qtHaveModule(printsupport): QT += printsupport
TARGET = songchao
TEMPLATE = app


SOURCES += main.cpp\
        myword.cpp \
    mychild.cpp

HEADERS  += myword.h \
    mychild.h

RESOURCES += \
    myword.qrc

mychild.h // MDI程序框架

#ifndef MYCHILD_H
#define MYCHILD_H

#include <QTextEdit>
#include <QPrinter>

class MyChild : public QTextEdit    
    Q_OBJECT
public:
    MyChild();
    void newFile();
    bool loadFile(const QString &fileName);
    bool save();
    bool saveAs();
    bool saveFile(QString fileName);
    QString userFriendlyCurrentFile();
    QString currentFile() {return curFile;}
    void mergeFormatOnWordOrSelection(const QTextCharFormat &format);
    void setAlign(int align);
    void setStyle(int style);
protected:
    void closeEvent(QCloseEvent *event);
private slots:
    void documentWasModified();
private:
    bool maybeSave();
    void setCurrentFile(const QString &fileName);
    QString strippedName(const QString &fullFileName);
    QString curFile;
    bool isUntitled;

};
#endif //MYCHILD_H

myword.h //基本编辑功能 文档美化等功能

#ifndef MYWORD_H
#define MYWORD_H

#include <QMainWindow>
#include <QPrintDialog>
#include <QPrinter>
#include <QPrintPreviewDialog>
class MyChild;
class QMdiArea;//声明QMdiArea类
class QAction; //声明动作
class QMenu;//声明菜单
class QComboBox;
class QFontComboBox;
class QMdiSubWindow;
class QSignalMapper;
class MyWord : public QMainWindow
{
    Q_OBJECT

public:
    MyWord(QWidget *parent = 0);
    ~MyWord();
protected:
    void closeEvent(QCloseEvent *event);
private slots:
    void fileNew();
    void fileOpen();
    void fileSave();
    void fileSaveAs();
    void filePrint();
    void filePrintPreview();
    void printPreview(QPrinter *);
    void undo();
    void redo();
    void cut();
    void copy();
    void paste();
    void textAlign(QAction *a);
    void about();
    void textBold();
    void textItalic();
    void textUnderline();
    void textFamily(const QString &f);
    void textSize(const QString &p);
    void textColor();
    void textStyle(int styleIndex);
    MyChild *createMyChild();
    void updateMenus();
    void updateWindowMenu();
private:
    void createActions();//创建动作
    void createMenus();//创建菜单
    void createToolBars();
    void createStatusBars();
    void enabledText();
    void colorChanged(const QColor &c);
    MyChild *activeMyChild();
    QMdiSubWindow *findMyChild(const QString &fileName);
    QSignalMapper *windowMapper;
    QMdiArea *mdiArea;  //定义QMdiArea类变量
    QMenu *fileMenu;
    QMenu *editMenu;
    QMenu *formatMenu;
    QMenu *fontMenu;
    QMenu *alignMenu;
    QMenu *windowMenu;
    QMenu *helpMenu;
    QAction *newAct;
    QAction *openAct;
    QAction *saveAct;
    QAction *saveAsAct;
    QAction *printAct;
    QAction *printPreviewAct;
    QAction *exitAct;
    QAction *undoAct;
    QAction *redoAct;
    QAction *cutAct;
    QAction *copyAct;
    QAction *pasteAct;
    QAction *boldAct;
    QAction *italicAct;
    QAction *underlineAct;
    QAction *leftAlignAct;
    QAction *centerAct;
    QAction *rightAlignAct;
    QAction *justifyAct;
    QAction *colorAct;
    QAction *closeAct;
    QAction *closeAllAct;
    QAction *tileAct;
    QAction *cascadeAct;
    QAction *nextAct;
    QAction *previousAct;
    QAction *separatorAct;
    QAction *aboutAct;
    QAction *aboutQtAct;
    QToolBar *fileToolBar;
    QToolBar *editToolBar;
    QToolBar *formatToolBar;\
    QToolBar *comboToolBar;
    QComboBox *comboStyle;
    QFontComboBox *comboFont;
    QComboBox *comboSize;
};

#endif // MYWORD_H

cpp文件

main.cpp //主文件

#include "myword.h"
#include <QApplication>

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

    return a.exec();
}

mychild.cpp

#include "mychild.h"
#include <QtWidgets>

MyChild::MyChild()
{
    setAttribute(Qt::WA_DeleteOnClose);
    isUntitled = true;

}

void MyChild::newFile()
{
    static int sequenceNumber = 1;
    isUntitled=true;
    curFile=tr("文档 %1").arg(sequenceNumber++);
    setWindowTitle(curFile+"[*]"+tr("-B160602-B16060218-宋超"));
    connect(document(),SIGNAL(contentsChanged()),this,SLOT(documentWasModified()));
}

void MyChild::documentWasModified()
{
    setWindowModified(document()->isModified());
}
QString MyChild::userFriendlyCurrentFile()
{
    return strippedName(curFile);

}
QString MyChild::strippedName(const QString &fullFileName)
{
    return QFileInfo(fullFileName).fileName();
}

void MyChild::closeEvent(QCloseEvent *event)
{
    if (maybeSave()) {
            event->accept();
        } else {
            event->ignore();
        }

}

bool MyChild::loadFile(const QString &fileName)
{
    if (!fileName.isEmpty())
    {
        if (!QFile::exists(fileName))
            return false;
        QFile file(fileName);
        if(!file.open(QFile::ReadOnly))
            return false;

        QByteArray data = file.readAll();
        QTextCodec *codec = Qt::codecForHtml(data);
        QString str = codec->toUnicode(data);
        if (Qt::mightBeRichText(str)){
            this->setHtml(str);
        } else{
            str = QString::fromLocal8Bit(data);
            this->setPlainText(str);
        }
        setCurrentFile(fileName);
        connect(document(),SIGNAL(contentsChanged()),this,SLOT(documentWasModified()));
        return true;
    }
}

void MyChild::setCurrentFile(const QString &fileName)
{
    curFile = QFileInfo(fileName).canonicalFilePath();
    isUntitled = false;
    document()->setModified(false);
    setWindowModified(false);
    setWindowTitle(userFriendlyCurrentFile() + "[*]");
}

bool MyChild::save()
{
    if (isUntitled) {
        return saveAs();
    }else{
        return saveFile(curFile);
    }
}

bool MyChild::saveAs()
{
    QString fileName = QFileDialog::getSaveFileName(this,tr("另存为"),curFile,
                                                    tr("HTML 文档 (*.htm *.html);;所有文件 (*.*"));
    if (fileName.isEmpty())
        return false;
    return saveFile(fileName);
}

bool MyChild::saveFile(QString fileName)
{
    if(!(fileName.endsWith(".htm", Qt::CaseInsensitive) || fileName.endsWith(".htm",Qt::CaseInsensitive)))
    {
        fileName += ".html";
    }
    QTextDocumentWriter writer(fileName);
    bool success = writer.write(this->document());
    if (success)
        setCurrentFile(fileName);
    return success;
}

void MyChild::mergeFormatOnWordOrSelection(const QTextCharFormat &format)
{
    QTextCursor cursor = this->textCursor();
    if (!cursor.hasSelection())
        cursor.select(QTextCursor::WordUnderCursor);
    cursor.mergeCharFormat(format);
    this->mergeCurrentCharFormat(format);
}

void MyChild::setAlign(int align)
{
    if(align == 1)
        this->setAlignment(Qt::AlignLeft | Qt::AlignAbsolute);
    else if (align == 2)
        this->setAlignment(Qt::AlignHCenter);
    else if (align == 3)
        this->setAlignment(Qt::AlignRight | Qt::AlignAbsolute);
    else if (align == 4)
        this->setAlignment(Qt::AlignJustify);

}

bool MyChild::maybeSave()
{
    if (!document()->isModified())
        return true;
    QMessageBox::StandardButton ret;
    ret = QMessageBox::warning(this,tr("xx-xx-xx"),
                               tr("文档'%1'已被修改,保存吗?").arg(userFriendlyCurrentFile()),
                               QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
    if(ret == QMessageBox::Save)
        return save();
    else if (ret == QMessageBox::Cancel)
        return false;
    return true;
}

void MyChild::setStyle(int style)
{
    QTextCursor cursor = this->textCursor();
    if (style !=0){
        QTextListFormat::Style stylename = QTextListFormat::ListDisc;

        switch (style){
            default:
        case 1:
            stylename = QTextListFormat::ListDisc;
            break;
        case 2:
            stylename = QTextListFormat::ListCircle;
            break;
        case 3:
            stylename = QTextListFormat::ListSquare;
            break;
        case 4:
            stylename = QTextListFormat::ListDecimal;
            break;
        case 5:
            stylename = QTextListFormat::ListLowerAlpha;
            break;
        case 6:
            stylename = QTextListFormat::ListLowerAlpha;
            break;
        case 7:
            stylename = QTextListFormat::ListLowerRoman;
            break;
        case 8:
            stylename = QTextListFormat::ListLowerRoman;
            break;
    }
    cursor.beginEditBlock();

    QTextBlockFormat blockFmt = cursor.blockFormat();

    QTextListFormat listFmt;
       if (cursor.currentList()){
           listFmt = cursor.currentList()->format();
       } else{
           listFmt.setIndent(blockFmt.indent() + 1);
           blockFmt.setIndent(0);
           cursor.setBlockFormat(blockFmt);
       }

       listFmt.setStyle(stylename);
       cursor.createList(listFmt);
       cursor.endEditBlock();
    }else{
        QTextBlockFormat bfmt;
        bfmt.setObjectIndex(-1);
        cursor.mergeBlockFormat(bfmt);
    }
}

myword.cpp

#include "myword.h"
#include "mychild.h"
#include <QtWidgets>
const QString rsrcPath=":/images";
MyWord::MyWord(QWidget *parent)
    : QMainWindow(parent)
{
    mdiArea=new QMdiArea;
    //需要时显示水平滚动条
    mdiArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    //需要时显示垂直滚动条
    mdiArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    //设置中心部件
    setCentralWidget(mdiArea);
    connect(mdiArea,SIGNAL(subWindowActivated(QMdiSubWindow*)),this,SLOT(updateMenus()));
    windowMapper = new QSignalMapper(this);
    connect(windowMapper,SIGNAL(mapped(QWidget*)),this,SLOT(setActiveSubWindow(QWidget*)));
    createActions();
    createMenus();
    createToolBars();
    createStatusBars();
    updateMenus();
    move(200,150);
    resize(800,500);
    setWindowTitle(tr("B160602-B16060218-宋超"));
}
void MyWord::createActions()
{
    newAct=new QAction(QIcon(rsrcPath+ "/filenew.png"),tr("新建(&N)"),this);
    newAct->setShortcuts(QKeySequence::New);
    newAct->setToolTip("新建");
    newAct->setStatusTip(tr("创建一个新文档"));
    connect(newAct, SIGNAL(triggered()),this,SLOT(fileNew()));

    openAct = new QAction(QIcon(rsrcPath + "/fileopen.png"), tr("打开(&O)..."),this);
    openAct->setShortcuts(QKeySequence::Open);
    openAct->setToolTip("打开");
    openAct->setStatusTip(tr("打开已存在的文档"));
    connect(openAct, SIGNAL(triggered()),this,SLOT(fileOpen()));

    saveAct = new QAction(QIcon(rsrcPath +"/filesave.png"),tr("保存(&S)"),this);
    saveAct->setShortcuts(QKeySequence::Save);
    saveAct->setToolTip("保存");
    saveAct->setStatusTip(tr("将当前文档存盘"));
    connect(saveAct, SIGNAL(triggered()),this,SLOT(file()));

    saveAsAct = new QAction(tr("另存为(&A)..."),this);
    saveAsAct->setShortcuts(QKeySequence::SaveAs);
    saveAsAct->setStatusTip(tr("以一个新名字保存文档"));
    connect(saveAsAct, SIGNAL(triggered()),this,SLOT(fileSaveAs()));

    printAct = new QAction(QIcon(rsrcPath + "/fileprint.png"), tr("打印(&P)..."),this);
    printAct->setShortcuts(QKeySequence::Print);
    printAct->setToolTip("打印");
    printAct->setStatusTip(tr("打印文档"));
    connect(printAct, SIGNAL(triggered()),this,SLOT(filePrint()));

    printPreviewAct = new QAction(tr("打印预览..."),this);
    printPreviewAct->setStatusTip(tr("预览打印效果"));
    connect(printPreviewAct,SIGNAL(triggered()),this,SLOT(filePrintPreview()));

    exitAct = new QAction(tr("退出(&X)"),this);
    exitAct->setShortcuts(QKeySequence::Quit);
    exitAct->setStatusTip(tr("退出应用程序"));
    connect(exitAct,SIGNAL(triggered()),qApp,SLOT(closeAllWindows()));

    undoAct = new QAction(QIcon(rsrcPath +"/editundo.png"),tr("撤销(&U)"),this);
    undoAct->setShortcut(QKeySequence::Undo);
    undoAct->setToolTip("撤销");
    undoAct->setStatusTip(tr("撤销当前操作"));
    connect(undoAct,SIGNAL(triggered()),this,SLOT(undo()));

    redoAct = new QAction(QIcon(rsrcPath +"/editredo.png"),tr("重做(&R)"),this);
    redoAct->setShortcut(QKeySequence::Redo);
    redoAct->setToolTip("重做");
    redoAct->setStatusTip(tr("恢复之前操作"));
    connect(redoAct,SIGNAL(triggered()),this,SLOT(redo()));

    cutAct = new QAction(QIcon(rsrcPath +"/editcut.png"),tr("剪切(&T)"),this);
    cutAct->setShortcuts(QKeySequence::Cut);
    cutAct->setStatusTip(tr("从文档中裁剪所选内容,并将其放入剪切板"));
    connect(cutAct,SIGNAL(triggered()),this,SLOT(cut()));

    copyAct = new QAction(QIcon(rsrcPath +"/editcopy.png"),tr("复制(&C)"),this);
    copyAct->setShortcuts(QKeySequence::Copy);
    copyAct->setToolTip("复制");
    copyAct->setStatusTip(tr("拷贝所选内容,并将其放入剪切板"));
    connect(copyAct,SIGNAL(triggered()),this,SLOT(copy()));

    pasteAct = new QAction(QIcon(rsrcPath +"/editpaste.png"),tr("粘贴(&P)"),this);
    pasteAct->setShortcuts(QKeySequence::Paste);
    pasteAct->setToolTip("粘贴");
    pasteAct->setStatusTip(tr("将剪切板的内容粘贴到文档"));
    connect(pasteAct,SIGNAL(triggered()),this,SLOT(paste()));

    boldAct = new QAction(QIcon(rsrcPath +"/textbold.png"),tr("加粗(&B)"),this);
    boldAct->setCheckable(true);
    boldAct->setShortcut(Qt::CTRL + Qt::Key_B);
    boldAct->setToolTip("加粗");
    boldAct->setStatusTip(tr("将所选文字加粗"));
    QFont bold;
    bold.setBold(true);
    boldAct->setFont(bold);
    connect(boldAct,SIGNAL(triggered()),this,SLOT(textBold()));

    italicAct = new QAction(QIcon(rsrcPath +"/textitalic.png"),tr("倾斜(&I)"),this);
    italicAct->setCheckable(true);
    italicAct->setShortcut(Qt::CTRL + Qt::Key_I);
    italicAct->setToolTip("倾斜");
    italicAct->setStatusTip(tr("将所选文字用斜体表示"));
    QFont italic;
    italic.setItalic(true);
    connect(italicAct,SIGNAL(triggered()),this,SLOT(textItalic()));

    underlineAct = new QAction(QIcon(rsrcPath +"/textunder.png"),tr("下划线(&U)"),this);
    underlineAct->setCheckable(true);
    underlineAct->setShortcut(Qt::CTRL + Qt::Key_U);
    underlineAct->setToolTip("下划线");
    underlineAct->setStatusTip(tr("给所选文字加下划线"));
    QFont underline;
    underline.setUnderline(true);
    underlineAct->setFont(underline);
    connect(underlineAct,SIGNAL(triggered()),this,SLOT(textUnderline()));

    QActionGroup *grp = new QActionGroup(this);
    connect(grp,SIGNAL(triggered(QAction*)),this,SLOT(textAlign(QAction*)));

    if(QApplication::isLeftToRight()){
        leftAlignAct = new QAction(QIcon(rsrcPath + "/textleft.png"),tr("左对齐(&L)"),grp);
        centerAct = new QAction(QIcon(rsrcPath + "/textcenter.png"),tr("居中(&E)"),grp);
        rightAlignAct = new QAction(QIcon(rsrcPath + "/textright.png"),tr("右对齐(&R)"),grp);
    }else {
        rightAlignAct = new QAction(QIcon(rsrcPath + "/textright.png"),tr("右对齐(&R)"),grp);
        centerAct = new QAction(QIcon(rsrcPath + "/textcenter.png"),tr("居中(&E)"),grp);
        leftAlignAct = new QAction(QIcon(rsrcPath + "/textleft.png"),tr("左对齐(&L)"),grp);

    }
    justifyAct = new QAction(QIcon(rsrcPath + "/textjustify.png"),tr("两端对齐(&J)"),grp);

    leftAlignAct->setShortcut(Qt::CTRL + Qt::Key_L);
    leftAlignAct->setCheckable(true);
    leftAlignAct->setToolTip("左对齐");
    leftAlignAct->setStatusTip(tr("将文字左对齐"));

    centerAct->setShortcut(Qt::CTRL + Qt::Key_E);
    centerAct->setCheckable(true);
    centerAct->setToolTip("居中");
    centerAct->setStatusTip(tr("将文字居中对齐"));

    rightAlignAct->setShortcut(Qt::CTRL + Qt::Key_R);
    rightAlignAct->setCheckable(true);
    rightAlignAct->setToolTip("右对齐");
    rightAlignAct->setStatusTip(tr("将文字右对齐"));

    justifyAct->setShortcut(Qt::CTRL + Qt::Key_J);
    justifyAct->setCheckable(true);
    justifyAct->setToolTip("两端对齐");
    justifyAct->setStatusTip(tr("将文字左右两端同时对齐,并根据需要增加字间距"));

    QPixmap pix(16,16);
    pix.fill(Qt::red);
    colorAct = new QAction(pix,tr("颜色(&C)..."),this);
    colorAct->setToolTip("颜色");
    colorAct->setStatusTip(tr("设置文字颜色"));
    connect(colorAct,SIGNAL(triggered()),this,SLOT(textColor()));

    closeAct = new QAction(tr("关闭(&O)"),this);
    closeAct->setStatusTip(tr("关闭活动文档子窗口"));
    connect(closeAct,SIGNAL(triggered()),mdiArea,SLOT(closeActiveSubWindow()));

    closeAllAct = new QAction(tr("关闭所有(&A)"),this);
    closeAllAct->setStatusTip(tr("关闭所有子窗口"));
    connect(closeAllAct,SIGNAL(triggered()),mdiArea,SLOT(closeAllSubWindows()));

    tileAct = new QAction(tr("平铺(&T)"),this);
    tileAct->setStatusTip(tr("平铺子窗口"));
    connect(tileAct,SIGNAL(triggered()),mdiArea,SLOT(tileSubWindows()));

    cascadeAct = new QAction(tr("层叠(&C)"),this);
    cascadeAct->setStatusTip(tr("层叠子窗口"));
    connect(cascadeAct,SIGNAL(triggered()),mdiArea,SLOT(cascadeSubWindows()));

    nextAct = new QAction(tr("下一个(&X)"),this);
    nextAct->setShortcuts(QKeySequence::NextChild);
    nextAct->setStatusTip(tr("移动焦点到下一个子窗口"));
    connect(nextAct,SIGNAL(triggered()),mdiArea,SLOT(activatePreviousSubWindow()));

    previousAct = new QAction(tr("前一个(&V)"),this);
    previousAct->setShortcuts(QKeySequence::PreviousChild);
    previousAct->setStatusTip(tr("移动焦点到前一个子窗口"));
    connect(previousAct,SIGNAL(triggered()),mdiArea,SLOT(activtePreviousSubWindow()));

    separatorAct = new QAction(this);
    separatorAct->setSeparator(true);

    aboutAct = new QAction(tr("关于(&A)"),this);
    aboutAct->setStatusTip(tr("关于 B160602-B16060218-宋超"));
    connect(aboutAct,SIGNAL(triggered()),this,SLOT(about()));

    aboutQtAct = new QAction(tr("关于Qt(&Q)"),this);
    aboutQtAct->setStatusTip(tr("关于 Qt 库"));
    connect(aboutQtAct,SIGNAL(triggered()),qApp,SLOT(aboutQt()));



}

void MyWord::createMenus()
{
    fileMenu = menuBar()->addMenu(tr("文件(&F)"));
    fileMenu->addAction(newAct);
    fileMenu->addAction(openAct);
    fileMenu->addSeparator();
    fileMenu->addAction(saveAct);
    fileMenu->addAction(saveAsAct);
    fileMenu->addSeparator();
    fileMenu->addAction(printAct);
    fileMenu->addAction(printPreviewAct);
    fileMenu->addSeparator();
    fileMenu->addAction(exitAct);
    editMenu = menuBar()->addMenu(tr("编辑(&E)"));
    editMenu->addAction(undoAct);
    editMenu->addAction(redoAct);
    editMenu->addSeparator();
    editMenu->addAction(cutAct);
    editMenu->addAction(copyAct);
    editMenu->addAction(pasteAct);
    formatMenu = menuBar()->addMenu(tr("格式(&O)"));
    fontMenu = formatMenu->addMenu(tr("字体(&D)"));
    fontMenu->addAction(boldAct);
    fontMenu->addAction(italicAct);
    fontMenu->addAction(underlineAct);
    alignMenu = formatMenu->addMenu(tr("段落"));
    alignMenu->addAction(leftAlignAct);
    alignMenu->addAction(centerAct);
    alignMenu->addAction(rightAlignAct);
    alignMenu->addAction(justifyAct);

    formatMenu->addAction(colorAct);

    windowMenu = menuBar()->addMenu(tr("窗口(&W)"));
    updateWindowMenu();
    connect(windowMenu,SIGNAL(aboutToShow()),this,SLOT(updateWindowMenu()));
    menuBar()->addSeparator();

    helpMenu = menuBar()->addMenu(tr("帮助(&H)"));
    helpMenu->addAction(aboutAct);
    helpMenu->addSeparator();
    helpMenu->addAction(aboutQtAct);


}


void MyWord::about()
{
    QMessageBox::about(this,tr("关于"),
                       tr("这是一个基于 Qt 实现的文字处理软件,具备类似微软office Word 的功能,"));
}

void MyWord::textBold()
{
    QTextCharFormat fmt;
    fmt.setFontWeight(boldAct->isChecked()? QFont::Bold : QFont::Normal);
    if(activeMyChild())
        activeMyChild()->mergeFormatOnWordOrSelection(fmt);
}

void MyWord::textItalic()
{
    QTextCharFormat fmt;
    fmt.setFontItalic(italicAct->isChecked());
    if(activeMyChild())
        activeMyChild()->mergeFormatOnWordOrSelection(fmt);

}

void MyWord::textUnderline()
{
    QTextCharFormat fmt;
    fmt.setFontUnderline(underlineAct->isChecked());
    if(activeMyChild())
        activeMyChild()->mergeFormatOnWordOrSelection(fmt);
}

void MyWord::createToolBars()
{
    //"文件"工具栏
    fileToolBar = addToolBar(tr("文件"));
    fileToolBar->addAction(newAct);
    fileToolBar->addAction(openAct);
    fileToolBar->addAction(saveAct);
    fileToolBar->addSeparator();
    fileToolBar->addAction(printAct);

    //“编辑”工具栏
    editToolBar = addToolBar(tr("编辑"));
    editToolBar->addAction(undoAct);
    editToolBar->addAction(redoAct);
    editToolBar->addSeparator();
    editToolBar->addAction(cutAct);
    editToolBar->addAction(copyAct);
    editToolBar->addAction(pasteAct);

    //“格式”工具栏
    formatToolBar = addToolBar(tr("格式"));
    formatToolBar->addAction(boldAct);
    formatToolBar->addAction(italicAct);
    formatToolBar->addAction(underlineAct);\
    formatToolBar->addSeparator();
    formatToolBar->addAction(leftAlignAct);
    formatToolBar->addAction(centerAct);
    formatToolBar->addAction(rightAlignAct);
    formatToolBar->addAction(justifyAct);
    formatToolBar->addSeparator();
    formatToolBar->addAction(colorAct);

    //“组合”工具栏
    addToolBarBreak(Qt::TopToolBarArea);
    comboToolBar = addToolBar(tr("组合选择"));
    comboStyle = new QComboBox();
    comboToolBar->addWidget(comboStyle);
    comboStyle->addItem("标准");
    comboStyle->addItem("项目符号 (●)");
    comboStyle->addItem("项目符号 (○)");
    comboStyle->addItem("项目符号 (■)");
    comboStyle->addItem("编号 (1.2.3.)");
    comboStyle->addItem("编号 (a.b.c.)");
    comboStyle->addItem("编号 (A.B.C.)");
    comboStyle->addItem("编号 (ⅰ.ⅱ.ⅲ.)");
    comboStyle->addItem("编号 (Ⅰ.Ⅱ.Ⅲ.)");
    comboStyle->setStatusTip("段落加标号或编号");
    connect(comboStyle,SIGNAL(activated(int)),this,SLOT(textStyle(int)));

    comboFont = new QFontComboBox();
    comboToolBar->addWidget(comboFont);
    comboFont->setStatusTip("更改字体");
    connect(comboFont,SIGNAL(activated(QString)),this,SLOT(textFamily(QString)));

    comboSize = new QComboBox();
    comboToolBar->addWidget(comboSize);
    comboSize->setEditable(true);
    comboSize->setStatusTip("更改字号");

    QFontDatabase db;
    foreach(int size,db.standardSizes())
        comboSize->addItem(QString::number(size));

    connect(comboSize,SIGNAL(activated(QString)),this,SLOT(textSize(QString)));
    comboSize->setCurrentIndex(comboSize->findText(QString::number(QApplication::font().pointSize())));

}

MyChild *MyWord::createMyChild()
{
    MyChild *child = new MyChild;
    mdiArea->addSubWindow(child);
    connect(child,SIGNAL(copyAvailable(bool)),cutAct,SLOT(setEnabled(bool)));
    connect(child,SIGNAL(copyAvailable(bool)),copyAct,SLOT(setEnabled(bool)));

    return child;
}
void MyWord::fileNew()
{
    MyChild *child = createMyChild();
    child->newFile();
    child->show();
    enabledText();
}

void MyWord::enabledText()
{
    boldAct->setEnabled(true);
    italicAct->setEnabled(true);
    underlineAct->setEnabled(true);
    leftAlignAct->setEnabled(true);
    centerAct->setEnabled(true);
    rightAlignAct->setEnabled(true);
    justifyAct->setEnabled(true);
    colorAct->setEnabled(true);
}

void MyWord::updateMenus()
{
    bool hasMyChild = (activeMyChild()!=0);

    saveAct->setEnabled(hasMyChild);
    saveAsAct->setEnabled(hasMyChild);
    printAct->setEnabled(hasMyChild);
    printPreviewAct->setEnabled(hasMyChild);

    pasteAct->setEnabled(hasMyChild);

    closeAct->setEnabled(hasMyChild);
    closeAllAct->setEnabled(hasMyChild);
    tileAct->setEnabled(hasMyChild);
    cascadeAct->setEnabled(hasMyChild);
    nextAct->setEnabled(hasMyChild);
    previousAct->setEnabled(hasMyChild);
    separatorAct->setVisible(hasMyChild);
    bool hasSelection = (activeMyChild() && activeMyChild()->textCursor().hasSelection());

    cutAct->setEnabled(hasSelection);
    copyAct->setEnabled(hasSelection);

    boldAct->setEnabled(hasSelection);
    italicAct->setEnabled(hasSelection);
    underlineAct->setEnabled(hasSelection);
    leftAlignAct->setEnabled(hasSelection);
    centerAct->setEnabled(hasSelection);
    rightAlignAct->setEnabled(hasSelection);
    justifyAct->setEnabled(hasSelection);
    colorAct->setEnabled(hasSelection);
}

MyChild *MyWord::activeMyChild()
{
    if(QMdiSubWindow *activeSubWindow = mdiArea->activeSubWindow())
        return qobject_cast<MyChild *>(activeSubWindow->widget());
    return 0;

}

void MyWord::updateWindowMenu()
{
    windowMenu->clear();
    windowMenu->addAction(closeAct);
    windowMenu->addAction(closeAllAct);
    windowMenu->addSeparator();
    windowMenu->addAction(tileAct);
    windowMenu->addAction(cascadeAct);
    windowMenu->addSeparator();
    windowMenu->addAction(nextAct);
    windowMenu->addAction(previousAct);
    windowMenu->addAction(separatorAct);
    QList<QMdiSubWindow *> windows = mdiArea->subWindowList();
    separatorAct->setVisible(!windows.isEmpty());
    for (int i=0;i < windows.size(); ++i){
        MyChild *child = qobject_cast<MyChild *>(windows.at(i)->widget());

        QString text;\
        if (i<9){
            text = tr("&%1 %2").arg(i + 1).arg(child->userFriendlyCurrentFile());
        }else{
            text = tr("%1 %2").arg(i + 1).arg(child->userFriendlyCurrentFile());
        }
        QAction *action = windowMenu->addAction(text);
        action->setCheckable(true);
        action->setChecked(child == activeMyChild());
        connect(action,SIGNAL(triggered()),windowMapper,SLOT(map()));
        windowMapper->setMapping(action,windows.at(i));
    }
    enabledText();
}

void MyWord::closeEvent(QCloseEvent *event)
{
    mdiArea->closeAllSubWindows();
    if (mdiArea->currentSubWindow()){
        event->ignore();
    } else{
        event->accept();
    }
}

void MyWord::createStatusBars()
{
    statusBar()->showMessage(tr("就绪"));
}

void MyWord::fileOpen()
{
    QString fileName = QFileDialog::getOpenFileName(this,tr("打开"),QString(),
                                                    tr("HTML 文档 (*.htm *.html);;所有文件 (*.*)"));
    if (!fileName.isEmpty()) {
        QMdiSubWindow *existing = findMyChild(fileName);
        if (existing) {
            mdiArea->setActiveSubWindow(existing);
            return;
        }
        MyChild *child = createMyChild();
        if (child->loadFile(fileName)) {
            statusBar()->showMessage(tr("文件已载入"),2000);
            child->show();
            enabledText();

        } else {
            child->close();
        }
    }

}

QMdiSubWindow *MyWord::findMyChild(const QString &fileName)
{
    QString canonicalFilePath = QFileInfo(fileName).canonicalFilePath();

    foreach (QMdiSubWindow *window,mdiArea->subWindowList()){
        MyChild *myChild = qobject_cast<MyChild *>(window->widget());
        if (myChild->currentFile() == canonicalFilePath);
            return window;
    }
    return 0;
}

void MyWord::fileSave()
{
    if (activeMyChild() && activeMyChild()->save())
        statusBar()->showMessage(tr("保存成功"), 2000);
}

void MyWord::fileSaveAs()
{
    if (activeMyChild() && activeMyChild()->saveAs())
        statusBar()->showMessage(tr("保存成功"), 2000);
}

void MyWord::undo()
{
    if(activeMyChild())
        activeMyChild()->undo();
}

void MyWord::redo()
{
    if(activeMyChild())
        activeMyChild()->redo();
}

void MyWord::cut()
{
    if (activeMyChild())
        activeMyChild()->cut();
}

void MyWord::copy()
{
    if (activeMyChild())
        activeMyChild()->copy();
}

void MyWord::paste()
{
    if (activeMyChild())
        activeMyChild()->paste();
}

void MyWord::textFamily(const QString &f)
{
    QTextCharFormat fmt;
    fmt.setFontFamily(f);
    if(activeMyChild())
        activeMyChild()->mergeFormatOnWordOrSelection(fmt);
}

void MyWord::textSize(const QString &p)
{
    qreal pointSize = p.toFloat();
    if(p.toFloat() >0){
        QTextCharFormat fmt;
        fmt.setFontPointSize(pointSize);
        if(activeMyChild())
            activeMyChild()->mergeFormatOnWordOrSelection(fmt);
    }
}

void MyWord::textAlign(QAction *a)
{
    if(activeMyChild())
    {
        if (a == leftAlignAct)
            activeMyChild()->setAlign(1);
        else if (a == centerAct)
            activeMyChild()->setAlign(2);
        else if (a == rightAlignAct)
            activeMyChild()->setAlign(3);
        else if (a == justifyAct)
            activeMyChild()->setAlign(4);
    }
}

void MyWord::textColor()
{
    if(activeMyChild())
    {
        QColor col = QColorDialog::getColor(activeMyChild()->textColor(),this);
        if (!col.isValid())
            return;
        QTextCharFormat fmt;
        fmt.setForeground(col);
        activeMyChild()->mergeFormatOnWordOrSelection(fmt);
        colorChanged(col);
    }
}

void MyWord::colorChanged(const QColor &c)
{
    QPixmap pix(16,16);
    pix.fill(c);
    colorAct->setIcon(pix);
}

void MyWord::textStyle(int styleIndex)
{
    if(activeMyChild())
    {
        activeMyChild()->setStyle(styleIndex);
    }
}

void MyWord::filePrint()
{
    QPrinter printer(QPrinter::HighResolution);
    QPrintDialog *dlg = new QPrintDialog(&printer,this);
    if (activeMyChild()->textCursor().hasSelection())
        dlg->addEnabledOption(QAbstractPrintDialog::PrintSelection);
    dlg->setWindowTitle(tr("打印文档"));
    if (dlg->exec() == QDialog::Accepted)
        activeMyChild()->print(&printer);
    delete dlg;
}

void MyWord::filePrintPreview()
{
    QPrinter printer(QPrinter::HighResolution);
    QPrintPreviewDialog preview(&printer,this);
    connect(&preview,SIGNAL(paintRequested(QPrinter*)),
            SLOT(printPreview(QPrinter*)));
    preview.exec();
}

void MyWord::printPreview(QPrinter *printer)
{
    activeMyChild()->print(printer);
}


MyWord::~MyWord()
{

}
添加新评论