一、成品界面展示与项目流程
运行程序后会出现主界面,顶端的菜单栏包括“文件”“编辑”“格式”“窗口”和“帮助”五个主菜单。 菜单栏下面是工具栏,包含了系统常用的功能按钮。工具栏有四个工具条,分别将一组相关功能按钮或控件组织在一起。 工具栏的第一行有三个工具条:第一个工具条包括新建、打开、保存、打印等文档管理功能;第二个工具条包括撤销、重做、剪切、复制和粘贴这些最基本的文本编辑功能;第三个工具条是各种较高级的文字字体格式设置按钮,包括加粗、倾斜、加下画线,还包括段落对齐及文本颜色设置等。 在工具栏的第二行的工具条中有三个组合选择框控件,用于为文档添加段落标号和编号,以及选择特殊字体和更改字号。利用该工具条可以完成更复杂的文档排版和字体美化工作。 此外,在图18.1中还给出了使用该软件制作出的三个文档示例。用Qt版MyWord字处理软件制作出的文档统一以HTML格式存盘,可使用Web浏览器打开观看效果,如图所示。
开发这个软件主要分为如下三个阶段进行。
(1)界面设计开发
界面设计开发内容包括菜单系统设计、工具栏设计、多窗体MDI程序框架的建立及多个文档子窗口的管理和控制等。
(2)文本编辑功能实现
文本编辑功能实现主要包括文档的建立、打开和保存,文本的剪切、复制和粘贴,操作撤销与恢复等这些最基本的文档编辑功能。
(3)排版美化功能实现
排版美化功能实现包括字体选择,字形、字号和文字颜色的设置,文档段落标号和编号的添加,段落对齐方式设置等高级功能实现。
二、界面设计开发
三、工程结构
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QMessageBox>
#include "mychildwnd.h"
#include <QMdiSubWindow>
#include <QSignalMapper>
#include <QFileDialog>
#include <QCloseEvent>
#include <QColorDialog>
#include <QPrintDialog>
#include <QPrinter>
#include <QPrintPreviewDialog>
class MyChildWnd;
class QMdiSubWindow;
class QSignalMapper;
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
void initMainWindow();//初始化
void docNew();//新建文档
void docOpen();//打开文档
void docSave();//保存文档
void docSaveAs();//文档另存为
void docUndo();//撤销
void docRedo();//重做
void docCut();//剪切
void docCopy();//复制
void docPaste();//粘贴
void textBold();//加粗
void textItalic();//倾斜
void textUnderline();//加下划线
void textFamily(const QString &fmly);//字体
void textSize(const QString &ps);//字号
void textAlign(QAction *act);//对齐
void textColor();//颜色
void paraStyle(int sidx);//段落标号编号
void docPrint();
void docPrintPreview();
void printPreview(QPrinter *);
private slots:
void on_aboutAction_triggered();
void on_aboutQtAction_triggered();
void on_newAction_triggered();
void refreshMenus();//刷新菜单槽函数
void addSubWndListMenu();//往【窗口】菜单下添加子窗口菜单项列表
void setActiveSubWindow(QWidget *wnd);
void on_openAction_triggered();
void on_saveAction_triggered();
void on_saveAsAction_triggered();
void on_undoAction_triggered();
void on_redoAction_triggered();
void on_cutAction_triggered();
void on_copyAction_triggered();
void on_pasteAction_triggered();
void on_boldAction_triggered();
void on_italicAction_triggered();
void on_underlineAction_triggered();
void on_fontComboBox_activated(const QString &arg1);
void on_sizeComboBox_activated(const QString &arg1);
void on_leftAlignAction_triggered();
void on_centerAction_triggered();
void on_rightAlignAction_triggered();
void on_justifyAction_triggered();
void on_colorAction_triggered();
void on_styleComboBox_activated(int index);
void on_printAction_triggered();
void on_printPreviewAction_triggered();
void on_closeAction_triggered();
void on_closeAllAction_triggered();
void on_tileAction_triggered();
void on_cascadeAction_triggered();
void on_nextAction_triggered();
void on_previousAction_triggered();
protected:
void closeEvent(QCloseEvent *event);
private:
Ui::MainWindow *ui;
void formatEnabled();//使格式菜单及其工具按钮可用
MyChildWnd* activateChildWnd();//活动文档子窗口
QSignalMapper* myWndMapper;//子窗口信号映射器
QMdiSubWindow* findChildWnd(const QString &docName);
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
initMainWindow();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::initMainWindow()
{
//加载系统标准字号集
QFontDatabase fontdb;
foreach (int fontsize, fontdb.standardSizes())
{
ui->sizeComboBox->addItem(QString::number(fontsize));
}
ui->sizeComboBox->setCurrentIndex(ui->sizeComboBox->findText(QString::number
(QApplication::font().pointSize())));
//将【段落】菜单下的各对齐方式功能项加入同一个菜单项组,这样程序运行的任一时刻用户能且只能选中其中一项
QActionGroup* alignGroup = new QActionGroup(this);
alignGroup->addAction(ui->leftAlignAction);
alignGroup->addAction(ui->centerAction);
alignGroup->addAction(ui->rightAlignAction);
alignGroup->addAction(ui->justifyAction);
ui->leftAlignAction->setChecked(true);
//多文档区域设置
ui->mdiArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);//滚动条在需要的时候出现
ui->mdiArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
refreshMenus();
//当有活动文档子窗口时刷新菜单
connect(ui->mdiArea,SIGNAL(subWindowActivated(QMdiSubWindow*)),this,SLOT(refreshMenus()));
//添加子窗口菜单项列表
myWndMapper = new QSignalMapper(this);//创建信号映射器
connect(myWndMapper,SIGNAL(mapped(QWidget*)),this,SLOT(setActiveSubWindow(QWidget*)));
addSubWndListMenu();
connect(ui->menu_W,SIGNAL(aboutToHide()),this,SLOT(addSubWndListMenu()));
}
void MainWindow::on_aboutAction_triggered()
{
QMessageBox::about(this,tr("关于"),tr("这是一个基于Qt5实现的字处理软件\r\n具备类似 微软 Office Word的功能。"));
}
void MainWindow::on_aboutQtAction_triggered()
{
QMessageBox::aboutQt(NULL,"关于 Qt 5");
}
void MainWindow::on_closeAction_triggered()
{
//对应窗口->关闭菜单项
ui->mdiArea->closeActiveSubWindow();
}
void MainWindow::on_closeAllAction_triggered()
{
//对应窗口->关闭所有菜单项
ui->mdiArea->closeAllSubWindows();
}
void MainWindow::on_tileAction_triggered()
{
//对应窗口->平铺所有窗口菜单项
ui->mdiArea->tileSubWindows();
}
void MainWindow::on_cascadeAction_triggered()
{
//对应窗口->层叠所有窗口菜单项
ui->mdiArea->cascadeSubWindows();
}
void MainWindow::on_nextAction_triggered()
{
//对应窗口->下一个菜单项
ui->mdiArea->activateNextSubWindow();
}
void MainWindow::on_previousAction_triggered()
{
//对应窗口->上一个菜单项
ui->mdiArea->activatePreviousSubWindow();
}
void MainWindow::docNew()
{
MyChildWnd* childWnd = new MyChildWnd;//创建MyChildWnd部件
//向多文档区域添加子窗口,childWnd为中心部件
ui->mdiArea->addSubWindow(childWnd);
//根据QTextEdit类是否可以复制信号,设置剪切、复制动作是否可用
connect(childWnd,SIGNAL(copyAvailable(bool)),ui->cutAction,SLOT(setEnabled(bool)));
connect(childWnd,SIGNAL(copyAvailable(bool)),ui->copyAction,SLOT(setEnabled(bool)));
childWnd->newDoc();
childWnd->show();
//使“格式”菜单下各菜单项及其对应的工具按钮变为可用
formatEnabled();
}
void MainWindow::on_openAction_triggered()
{
docOpen();
}
void MainWindow::docOpen()
{
QString docname = QFileDialog::getOpenFileName(this,tr("打开"),QString(),
tr("HTML 文档 (*.htm *.html);;所有文件 (*.*)"));
if(!docname.isEmpty())
{
QMdiSubWindow *exist = findChildWnd(docname);
if(exist)
{
ui->mdiArea->setActiveSubWindow(exist);
return;
}
MyChildWnd* childwnd = new MyChildWnd;
ui->mdiArea->addSubWindow(childwnd);
connect(childwnd,SIGNAL(copyAvailable(bool)),ui->cutAction,SLOT(setEnabled(bool)));
connect(childwnd,SIGNAL(copyAvailable(bool)),ui->copyAction,SLOT(setEnabled(bool)));
if(childwnd->loadDoc(docname))
{
statusBar()->showMessage(tr("文档已打开"),2000);
childwnd->show();
//使字体菜单下的功能可用
formatEnabled();
}
else
{
childwnd->close();
}
}
}
void MainWindow::on_saveAction_triggered()
{
docSave();
}
void MainWindow::docSave()
{
if(activateChildWnd() && activateChildWnd()->saveDoc())
{
statusBar()->showMessage(tr("保存成功"),2000);
}
}
void MainWindow::on_saveAsAction_triggered()
{
docSaveAs();
}
void MainWindow::docSaveAs()
{
if(activateChildWnd() && activateChildWnd()->saveAsDoc())
{
statusBar()->showMessage(tr("保存成功"), 2000);
}
}
void MainWindow::on_undoAction_triggered()
{
docUndo();
}
void MainWindow::on_redoAction_triggered()
{
docRedo();
}
void MainWindow::on_cutAction_triggered()
{
docCut();
}
void MainWindow::on_copyAction_triggered()
{
docCopy();
}
void MainWindow::on_pasteAction_triggered()
{
docPaste();
}
void MainWindow::docUndo()
{
if(activateChildWnd())
activateChildWnd()->undo();
}
void MainWindow::docRedo()
{
if(activateChildWnd())
activateChildWnd()->redo();
}
void MainWindow::docCut()
{
if(activateChildWnd())
activateChildWnd()->cut();
}
void MainWindow::docCopy()
{
if(activateChildWnd())
activateChildWnd()->copy();
}
void MainWindow::docPaste()
{
if(activateChildWnd())
activateChildWnd()->paste();
}
void MainWindow::on_boldAction_triggered()
{
textBold();
}
void MainWindow::on_italicAction_triggered()
{
textItalic();
}
void MainWindow::on_underlineAction_triggered()
{
textUnderline();
}
void MainWindow::textBold()
{
QTextCharFormat fmt;
fmt.setFontWeight(ui->boldAction->isChecked() ? QFont::Bold :QFont::Normal);
if(activateChildWnd())
activateChildWnd()->setFormatOnSelectedWord(fmt);
}
void MainWindow::textItalic()
{
QTextCharFormat fmt;
fmt.setFontItalic(ui->italicAction->isChecked());
if(activateChildWnd())
activateChildWnd()->setFormatOnSelectedWord(fmt);
}
void MainWindow::textUnderline()
{
QTextCharFormat fmt;
fmt.setFontUnderline(ui->underlineAction->isChecked());
if(activateChildWnd())
activateChildWnd()->setFormatOnSelectedWord(fmt);
}
void MainWindow::on_fontComboBox_activated(const QString &arg1)
{
textFamily(arg1);
}
void MainWindow::on_sizeComboBox_activated(const QString &arg1)
{
textSize(arg1);
}
void MainWindow::textFamily(const QString &fmly)
{
QTextCharFormat fmt;
fmt.setFontFamily(fmly);
if(activateChildWnd())
activateChildWnd()->setFormatOnSelectedWord(fmt);
}
void MainWindow::textSize(const QString &ps)
{
qreal pointSize = ps.toFloat();
if(ps.toFloat() > 0)
{
QTextCharFormat fmt;
fmt.setFontPointSize(pointSize);
if(activateChildWnd())
activateChildWnd()->setFormatOnSelectedWord(fmt);
}
}
void MainWindow::on_leftAlignAction_triggered()
{
textAlign(ui->leftAlignAction);
}
void MainWindow::on_centerAction_triggered()
{
textAlign(ui->centerAction);
}
void MainWindow::on_rightAlignAction_triggered()
{
textAlign(ui->rightAlignAction);
}
void MainWindow::on_justifyAction_triggered()
{
textAlign(ui->justifyAction);
}
void MainWindow::textAlign(QAction *act)
{
if(activateChildWnd())
{
if(act == ui->leftAlignAction)
activateChildWnd()->setAlignOfDocumentText(1);
else if(act == ui->centerAction)
activateChildWnd()->setAlignOfDocumentText(2);
else if(act == ui->rightAlignAction)
activateChildWnd()->setAlignOfDocumentText(3);
else if(act == ui->justifyAction)
activateChildWnd()->setAlignOfDocumentText(4);
}
}
void MainWindow::on_colorAction_triggered()
{
textColor();
}
void MainWindow::textColor()
{
if(activateChildWnd())
{
QColor color = QColorDialog::getColor(activateChildWnd()->textColor(),this);
if(!color.isValid())
return;
QTextCharFormat fmt;
fmt.setForeground(color);
activateChildWnd()->setFormatOnSelectedWord(fmt);
QPixmap pix(16,16);
pix.fill(color);
ui->colorAction->setIcon(pix);
}
}
void MainWindow::on_styleComboBox_activated(int index)
{
paraStyle(index);
}
void MainWindow::paraStyle(int sidx)
{
if(activateChildWnd())
activateChildWnd()->setParaStyle(sidx);
}
void MainWindow::on_printAction_triggered()
{
docPrint();
}
void MainWindow::on_printPreviewAction_triggered()
{
docPrintPreview();
}
void MainWindow::docPrint()
{
QPrinter pter(QPrinter::HighResolution);
QPrintDialog *pdlg = new QPrintDialog(&pter,this);
if(activateChildWnd()->textCursor().hasSelection())
pdlg->addEnabledOption(QAbstractPrintDialog::PrintSelection);
pdlg->setWindowTitle("打印文档");
if(pdlg->exec() == QDialog::Accepted)
{
activateChildWnd()->print(&pter);
}
delete pdlg;
}
void MainWindow::docPrintPreview()
{
QPrinter pter(QPrinter::HighResolution);
QPrintPreviewDialog pview(&pter,this);
connect(&pview,SIGNAL(paintRequested(QPrinter*)),SLOT(printPreview(QPrinter*)));
pview.exec();
}
void MainWindow::printPreview(QPrinter *pter)
{
activateChildWnd()->print(pter);
}
QMdiSubWindow *MainWindow::findChildWnd(const QString &docName)
{
QString canonicalFilePath = QFileInfo(docName).canonicalFilePath();
foreach (QMdiSubWindow* wnd, ui->mdiArea->subWindowList())
{
MyChildWnd* childwnd = qobject_cast<MyChildWnd *>(wnd->widget());
if(childwnd->myCurDocPath == canonicalFilePath)
return wnd;
}
return 0;
}
void MainWindow::formatEnabled()
{
ui->boldAction->setEnabled(true);
ui->italicAction->setEnabled(true);
ui->underlineAction->setEnabled(true);
ui->leftAlignAction->setEnabled(true);
ui->centerAction->setEnabled(true);
ui->rightAlignAction->setEnabled(true);
ui->justifyAction->setEnabled(true);
ui->colorAction->setEnabled(true);
}
void MainWindow::on_newAction_triggered()
{
docNew();
}
void MainWindow::refreshMenus()
{
//至少有一个文档子窗口打开的情况
bool hasChild = (activateChildWnd() != 0);
ui->saveAction->setEnabled(hasChild);
ui->saveAsAction->setEnabled(hasChild);
ui->printAction->setEnabled(hasChild);
ui->printPreviewAction->setEnabled(hasChild);
ui->pasteAction->setEnabled(hasChild);
ui->closeAction->setEnabled(hasChild);
ui->closeAllAction->setEnabled(hasChild);
ui->tileAction->setEnabled(hasChild);
ui->cascadeAction->setEnabled(hasChild);
ui->nextAction->setEnabled(hasChild);
ui->previousAction->setEnabled(hasChild);
//文档已打开并且其中由内容被选中时
bool hasSelect = (activateChildWnd() && activateChildWnd()->textCursor().hasSelection());
ui->cutAction->setEnabled(hasSelect);
ui->copyAction->setEnabled(hasSelect);
ui->boldAction->setEnabled(hasSelect);
ui->italicAction->setEnabled(hasSelect);
ui->underlineAction->setEnabled(hasSelect);
ui->leftAlignAction->setEnabled(hasSelect);
ui->centerAction->setEnabled(hasSelect);
ui->rightAlignAction->setEnabled(hasSelect);
ui->justifyAction->setEnabled(hasSelect);
ui->colorAction->setEnabled(hasSelect);
}
MyChildWnd* MainWindow::activateChildWnd()
{
//若有活动文档窗口则将其内的中心部件转换为MyChildWnd类型;若没有则直接返回0
if (QMdiSubWindow *actSubWnd = ui->mdiArea->activeSubWindow())
return qobject_cast<MyChildWnd *>(actSubWnd->widget());
else
return 0;
}
void MainWindow::addSubWndListMenu()
{
//首先清空原【窗口】菜单,然后再添加各菜单项
ui->menu_W->clear();
ui->menu_W->addAction(ui->closeAction);
ui->menu_W->addAction(ui->closeAllAction);
ui->menu_W->addSeparator();
ui->menu_W->addAction(ui->tileAction);
ui->menu_W->addAction(ui->cascadeAction);
ui->menu_W->addSeparator();
ui->menu_W->addAction(ui->nextAction);
ui->menu_W->addAction(ui->previousAction);
QList<QMdiSubWindow *> wnds = ui->mdiArea->subWindowList();
if (!wnds.isEmpty()) ui->menu_W->addSeparator();//如果有活动子窗口,显示分隔条
//遍历各个子窗口,显示所有当前已打开的文档子窗口项
for (int i = 0; i < wnds.size(); ++i)
{
MyChildWnd *childwnd = qobject_cast<MyChildWnd *>(wnds.at(i)->widget());
QString menuitem_text;
if (i < 9)
{
menuitem_text = tr("&%1 %2").arg(i + 1).arg(childwnd->getCurDocName());
} else {
menuitem_text = tr("%1 %2").arg(i + 1).arg(childwnd->getCurDocName());
}
//添加子窗口菜单项,设置其可选
QAction *menuitem_act = ui->menu_W->addAction(menuitem_text);
menuitem_act->setCheckable(true);
//将当前活动的子窗口设为勾选状态
menuitem_act->setChecked(childwnd == activateChildWnd());
//关联菜单项的触发信号到信号映射器的map()槽,该槽会发送mapped()信号
connect(menuitem_act, SIGNAL(triggered()), myWndMapper, SLOT(map()));
//将菜单项与相应的窗口部件进行映射,在发送mapped()信号时就会以这个窗口部件为参数
myWndMapper->setMapping(menuitem_act, wnds.at(i));
}
formatEnabled();//使【字体】菜单下的功能可用
}
void MainWindow::setActiveSubWindow(QWidget *wnd)
{
if (!wnd) return;
ui->mdiArea->setActiveSubWindow(qobject_cast<QMdiSubWindow *>(wnd));
}
void MainWindow::closeEvent(QCloseEvent *event)
{
ui->mdiArea->closeAllSubWindows();
if(ui->mdiArea->currentSubWindow())
{
event->ignore();
}
else {
event->accept();
}
}
mychildwnd.h
#ifndef MYCHILDWND_H
#define MYCHILDWND_H
#include <QWidget>
#include <QTextEdit>
#include <QFileInfo>
#include <QTextCodec>
#include <QFileDialog>
#include <QTextDocumentWriter>
#include <QMessageBox>
#include <QCloseEvent>
#include <QtWidgets>
#include <QPrinter>
class MyChildWnd : public QTextEdit
{
Q_OBJECT
public:
MyChildWnd();
QString myCurDocPath;//当前文档路径全名
void newDoc();//新建文档
QString getCurDocName();//从路径中提取文档名
bool loadDoc(const QString &docName);//加载文档内容
bool saveDoc();//保存文件
bool saveAsDoc();//另存为
bool saveDocOpt(QString docName);//具体执行保存操作
void setFormatOnSelectedWord(const QTextCharFormat &fmt);//设置字体与字号
void setAlignOfDocumentText(int aligntype);//设置对齐样式
void setParaStyle(int pstyle);//设置段落标号和编号
protected:
void closeEvent(QCloseEvent *event);
private slots:
void docBeModified();//文档被修改(尚未保存)时,在窗口标题栏显示*号
private:
bool beSaved;//文档是否已存盘
void setCurDoc(const QString &docName);//对当前加载文档的状态进行设置,并保存其路径全名
bool promptSave();//用户关闭文档的时候提示保存
};
#endif // MYCHILDWND_H
mychildwnd.cpp
#include "mychildwnd.h"
MyChildWnd::MyChildWnd()
{
setAttribute(Qt::WA_DeleteOnClose);//子窗口关闭时销毁该类对象实例
beSaved = false;//初始文档尚未保存
}
//创建一个新文档
void MyChildWnd::newDoc()
{
//设置窗口编号
static int wndSeqNum = 1;
//将当前打开的文档命名为"Word 文档 编号"的形式,编号在使用完一次后自增1
myCurDocPath = tr("Word 文档 %1").arg(wndSeqNum++);
//设置窗口标题,文档被改动后在其名称后面显示"*"号标识
setWindowTitle(myCurDocPath + "[*]" + tr(" - MyWord"));
//文档被改动时发送contensChanged()信号,执行自定义docBeModified()槽函数
connect(document(),SIGNAL(contentsChanged()),this,SLOT(docBeModified()));
}
//文档被修改(尚未保存)时,在窗口标题栏显示*号
void MyChildWnd::docBeModified()
{
setWindowModified(document()->isModified());//判断文档内容是否被更新
}
//从路径中提取文档名
QString MyChildWnd::getCurDocName()
{
return QFileInfo(myCurDocPath).fileName();
}
void MyChildWnd::closeEvent(QCloseEvent *event)
{
if(promptSave())
{
event->accept();
}
else
{
event->ignore();
}
}
//加载文档内容
bool MyChildWnd::loadDoc(const QString &docName)
{
if(!docName.isEmpty())
{
if(!QFile::exists(docName))
return false;
QFile doc(docName);
if(!doc.open(QFile::ReadOnly))
return false;
QByteArray text = doc.readAll();
QTextCodec *text_codec = Qt::codecForHtml(text);
QString str = text_codec->toUnicode(text);
if(Qt::mightBeRichText(str))
{
this->setHtml(str);
}
else
{
str = QString::fromLocal8Bit(text);
this->setPlainText(str);
}
setCurDoc(docName);
connect(document(),SIGNAL(contentsChanged()),this,SLOT(docBeModified()));
return true;
}
}
//对当前加载文档的状态进行设置,并保存其路径全名
void MyChildWnd::setCurDoc(const QString &docName)
{
myCurDocPath = QFileInfo(docName).canonicalFilePath();
beSaved = true;//文档已经被保存过
document()->setModified(false);//文档未被改动
setWindowModified(false);//窗口不显示被改动标识
setWindowTitle(getCurDocName() + "[*]");//设置文档名为子窗口标题
}
//保存文件
bool MyChildWnd::saveDoc()
{
if(!beSaved)
return saveAsDoc();
else {
saveDocOpt(myCurDocPath);
}
}
//另存为
bool MyChildWnd::saveAsDoc()
{
QString docName = QFileDialog::getSaveFileName(this,tr("另存为"),myCurDocPath,tr("HTML 文档 (*.htm *.html);;所有文件 (*.*)"));
if(docName.isEmpty())
return false;
else {
return saveDocOpt(docName);
}
}
//用户关闭文档的时候提示保存
bool MyChildWnd::promptSave()
{
if(!document()->isModified())
return true;
QMessageBox::StandardButton result;
result = QMessageBox::warning(this,tr("MyWord"),tr("文档'%1'已被更改,保存吗?").arg(getCurDocName()),QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
if(result == QMessageBox::Save)
return saveDoc();
else if(result == QMessageBox::Cancel)
return false;
return true;
}
//具体执行保存操作
bool MyChildWnd::saveDocOpt(QString docName)
{
if(!(docName.endsWith(".htm",Qt::CaseInsensitive) || docName.endsWith(".html",Qt::CaseInsensitive)))
{
docName += ".html";//默认保存为HTML文档
}
QTextDocumentWriter writer(docName);
bool success = writer.write(this->document());
if(success)
setCurDoc(docName);
return success;
}
//设置字体与字号
void MyChildWnd::setFormatOnSelectedWord(const QTextCharFormat &fmt)
{
QTextCursor tcursor = this->textCursor();
if(!tcursor.hasSelection())
tcursor.select(QTextCursor::WordUnderCursor);
tcursor.mergeCharFormat(fmt);
this->mergeCurrentCharFormat(fmt);
}
//设置对齐方式
void MyChildWnd::setAlignOfDocumentText(int aligntype)
{
if(aligntype == 1)
this->setAlignment(Qt::AlignLeft | Qt::AlignAbsolute);
else if(aligntype == 2)
this->setAlignment(Qt::AlignHCenter);
else if(aligntype == 3)
this->setAlignment(Qt::AlignRight | Qt::AlignAbsolute);
else if(aligntype == 4)
this->setAlignment(Qt::AlignJustify);
}
//设置段落标号和编号
void MyChildWnd::setParaStyle(int pstyle)
{
QTextCursor tcursor = this->textCursor();
if(pstyle != 0)
{
//文本列表格式
QTextListFormat::Style sname = QTextListFormat::ListDisc;
switch (pstyle) {
default:
case 1:
sname = QTextListFormat::ListDisc;
break;
case 2:
sname = QTextListFormat::ListCircle;
break;
case 3:
sname = QTextListFormat::ListSquare;
break;
case 4:
sname = QTextListFormat::ListDecimal;
break;
case 5:
sname = QTextListFormat::ListLowerAlpha;
break;
case 6:
sname = QTextListFormat::ListUpperAlpha;
break;
case 7:
sname = QTextListFormat::ListLowerRoman;
break;
case 8:
sname = QTextListFormat::ListUpperRoman;
break;
}
tcursor.beginEditBlock();
QTextBlockFormat tBlockFmt = tcursor.blockFormat();
QTextListFormat tListFmt;
if(tcursor.currentList())
{
tListFmt = tcursor.currentList()->format();
}
else
{
tListFmt.setIndent(tBlockFmt.indent()+1);
tBlockFmt.setIndent(0);
tcursor.setBlockFormat(tBlockFmt);
}
tListFmt.setStyle(sname);
tcursor.createList(tListFmt);
tcursor.endEditBlock();
}
else
{
QTextBlockFormat tbfmt;
tbfmt.setObjectIndex(-1);
tcursor.mergeBlockFormat(tbfmt);
}
}
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
MyWord.pro
#-------------------------------------------------
#
# Project created by QtCreator 2021-09-26T18:23:21
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
qtHaveModule(printsupport): QT += printsupport
TARGET = MyWord
TEMPLATE = app
# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
mainwindow.cpp \
mychildwnd.cpp
HEADERS += \
mainwindow.h \
mychildwnd.h
FORMS += \
mainwindow.ui
RESOURCES += \
res.qrc