Qt版Word字处理软件
演示界面

mychild.h
mychild.cpp
myword.h
myword.cpp
mychild.h
#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);
void setAlign(int align); //设置段落对齐格式
void setStyle(int style); //设置段落标号、编号
QString userFriendlyCurrentFile(); //提取文件名
QString currentFile() {return curFile;} //返回当前文件路径
void mergeFormatOnWordOrSelection(const QTextCharFormat &format); //字体格式设置
protected:
void closeEvent(QCloseEvent *event);
private slots:
void documentWasModified(); //文档被修改时,窗口显示更改状态标识
private:
bool maybeSave(); //提醒保存文件操作
QString strippedName(const QString &fullFileName); //获取较短的绝对路径
void setCurrentFile(const QString &fileName); //设置当前文件的属性
QString curFile; //保存当前文件路径
bool isUntitled; //作为当前文件是否被保存到硬盘上的标识
};
#endif // MYCHILD_H
mychild.cpp
#include "mychild.h"
#include <QtWidgets>
MyChild::MyChild()
{
setAttribute (Qt::WA_DeleteOnClose); //设置在子窗口关闭时销毁这个类的对象
isUntitled = true; //初始化isUntitled为true
}
/*
* 新建文件操作
* 1、设置窗口编号
* 2、设置文件未被保存过“isUntitled = true”
* 3、保存文件路径,为curFile赋初值
* 4、设置子窗口标题
* 5、文联文档内容改变信号contentsChanged()至显示文档更改状态标识槽documentWasModified()
*
* static 局部变量只被初始化一次,下一次依据上一次的结果值
*/
void MyChild::newFile ()
{
//设置窗口编号,因为编号会一直被保存,所以需要使用静态变量
static int sequenceNumber = 1;
//新建的文档默认未命名
isUntitled = true;
//将当前文件命名为“文档+编号”的形式,编号先使用在加1
curFile = tr("文档 %1").arg (sequenceNumber++);
//设置窗口标题,使用[*]可以在文档被更改在文件名称后显示“*”号
setWindowTitle (curFile + "[*]" + tr("- Myself Word"));
//文档更改时发送contentSChanged()信号,执行documentWasModified()槽函数
connect (document (), SIGNAL(contentsChanged()), this, SLOT(documentWasModified()));
}
/*
* 加载文件操作步骤
* 1、打开指定的文件,并读取文件内容到编辑器
* 2、设置当前文件的setCurrentFile(),该函数可以获取文件路径,完成文件和窗口状态的设置
* 3、关联文档内容改变信号到显示文档更改状态标志槽documentWasModified()。加载文件操作采用loadFile()函数实现
*/
bool MyChild::loadFile (const QString &fileName)
{
if(!fileName.isEmpty ())
{
if(!QFile::exists (fileName))
{
return false;
}
//新建QFile对象
QFile file(fileName);
//以只读方式打开文件,出错则提示,并返回false
if(!file.open (QFile::ReadOnly))
{
return false;
}
QByteArray data = file.readAll ();
/*通过检查BOM(字节顺序标记)和内容类型的元头,并能够解码成Unicode的html返回QTextCodec实例。Qt使用Unicode
存储,操作字符,提供了一套QTextCodec类。去帮助转换非Unicode格式到Unicode*/
QTextCodec *codec = Qt::codecForHtml (data);
QString str = codec->toUnicode (data);
//如果是纯文本
if(Qt::mightBeRichText (str))
{
/*如果你有现成的HTML文件,则可以直接调用setHtml()方法来加载*/
this->setHtml (str);
}
else
{
str = QString::fromLocal8Bit (data);
/*setPlainText()顾名思义,是设置纯文本。而setText参数除了可以设置为纯文本之外,还可以设置为一些简单
的html格式的字符串,当然这些字符串是修饰一个字符串。*/
this->setPlainText (str);
}
setCurrentFile (fileName);
connect(document (), SIGNAL(contentsChanged()), this, SLOT(documentWasModified()));
return true;
}
}
/*
* 保存文件
* 1、如果文件没有被保存过(用isUntitled判断),则执行“另存为”操作saveAs()。
* 2、否则直接“保存”文件saveFile(),该函数首先打开指定文件,然后将编辑器的内容写入该文件,最后设置当前文件setCurrentFIle()
*/
bool MyChild::save ()
{
if(isUntitled)
{
return saveAs();
}
else
{
return saveFile (curFile);
}
}
/*
* 另存为
* 1、从文件对话框获取文件路径。
* 2、如果路径不为空,则保存文件saveFile()
*/
bool MyChild::saveAs ()
{
QString fileName = QFileDialog::getSaveFileName (this, tr("另存为"), curFile, tr("HTML 文档(*.htm *.html); 所有文件(*.*)"));
//获取文件路径,如果为空则返回false,否则保存文件
if(fileName.isEmpty ())
{
return false;
}
return saveFile (fileName);
}
/*
* 保存文件
*/
bool MyChild::saveFile (QString fileName)
{
//如果字符串的结尾引用.htm或者.html则返回true,否则返回false。忽略大小写
if(!(fileName.endsWith (".htm", Qt::CaseInsensitive) || fileName.endsWith (".html", Qt::CaseInsensitive)))
{
fileName += ".html"; //默认保存为HTML文档
}
//保存文件对话框(对于某些格式QTextDocumentWriter可直接保存,其他不支持的格式就用QTextStream以流的形式保存 )
QTextDocumentWriter writer(fileName);
bool success = writer.write (this->document ());
if(success)
setCurrentFile (fileName);
return success;
}
/*
* 另存为文件操作(Remind the save file)
*/
bool MyChild::maybeSave ()
{
//首先判断文档是否被修改过,如果文档被修改过执行if(){}下面的内容
if(!document()->isModified ())
{
return true;
}
QMessageBox::StandardButton ret;
ret = QMessageBox::warning (this, tr("Myself Qt Word"), tr("文档"%1"已被修改,保存吗?").arg (userFriendlyCurrentFile ()), QMessageBox::Save | QMessageBox::Cancel | QMessageBox::Discard);
if(ret == QMessageBox::Save)
{
return save();
}
else if(ret == QMessageBox::Cancel)
{
return false;
}
return true;
}
/*
* 关闭文件事件
*/
void MyChild::closeEvent (QCloseEvent *event)
{
if(maybeSave())
{
event->accept ();
}
else
{
event->ignore ();
}
}
/*
* 文件更改标签
* 编辑器内容是否被更改,可以使用QTextDocument类的isModified()函数获知,这里使用了QTextEdit类,document()函数来获取
* 它的QTextDocument类对象。然后使用setWindowModified()函数设置窗口的更改状态标志“*”,如果参数为true,则将在标题中设置
* 了“[*]”号的地方显示“*”号,表示该文件已经被修改。
*/
void MyChild::documentWasModified ()
{
//根据文档的isModified()函数的返回值,判断编译器内容是否被更改
setWindowModified (document ()->isModified ());
}
QString MyChild::userFriendlyCurrentFile ()
{
return strippedName (curFile);
}
QString MyChild::strippedName (const QString &fullFileName)
{
return QFileInfo(fullFileName).fileName ();
}
/*
* 设置当前文件属性
*/
void MyChild::setCurrentFile (const QString &fileName)
{
/*canonicalFilePath ()可以除去路径中符号链接,如“.”和“..”等符号。这个
*函数只是将加载文件的路径首先保存到curFile中,然后再进行一些状态的设置*/
curFile = QFileInfo(fileName).canonicalFilePath ();
//文件已经被保存过
isUntitled = false;
//文档没有被更改过
document ()->setModified (false);
//窗口不显示被更改标志
setWindowModified (false);
//设置窗口标题,userFriendlyCurrentFile ()返回文件名
setWindowTitle (userFriendlyCurrentFile () + "[*]");
}
/*
* 设置字体格式
* 调用QTextCursor的mergeCharFormat()函数,将参数format所表示的格式应用到光标所在处的字符上
*/
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);
}
}
void MyChild::setStyle (int style)
{
//设置文本光标,执行文本首部
QTextCursor cursor = this->textCursor ();
if(style != 0)
{
//QTextListFormat 主要用于描述文本符号,编号的格式
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::ListUpperAlpha; //大写字母编号
break;
case 7:
stylename = QTextListFormat::ListLowerRoman; //小写罗马编号
break;
case 8:
stylename = QTextListFormat::ListUpperRoman; //大写罗马编号
break;
}
//为支持撤销操作(设置开始编辑文本格式)
cursor.beginEditBlock ();
QTextBlockFormat bfmt = cursor.blockFormat ();
QTextListFormat listfmt;
if(cursor.currentList ())
{
listfmt = cursor.currentList ()->format ();
}
else
{
listfmt.setIndent (bfmt.indent () + 1);
bfmt.setIndent (0);
cursor.setBlockFormat (bfmt);
}
listfmt.setStyle (stylename);
cursor.createList (listfmt);
cursor.endEditBlock ();
}
else
{
//QTextBlockFormatTextBlockFormat类则用于表示这一块文本的格式,如缩进值、与四边的边距等
QTextBlockFormat bfmt;
bfmt.setObjectIndex (-1);
cursor.mergeBlockFormat (bfmt); //合并格式
}
}
myword.h
#ifndef MYWORD_H
#define MYWORD_H
#include <QMainWindow>
#include <QPrintDialog>
#include <QPrinter>
#include <QPrintPreviewDialog>
class QMdiArea; //TextEdit
class QMenu; //主菜单
class QAction; //动作
class QComboBox; //
class QFontComboBox;//
class MyChild;
class QMdiSubWindow;
class QSignalMapper;//信号映射器,它可以实现对多个子窗口部件的相同信号进行映射,首先为其添加字符串或者数值参数,然后在发送出去。
class Myword : public QMainWindow
{
Q_OBJECT
public:
Myword(QWidget *parent = 0);
~Myword();
private:
QMdiArea *mdiArea;
void createMenus(); //创建主菜单
void createActions(); //创建动作
void createToolBars(); //创建工具栏
void createStatusBar(); //创建状态栏
void colorChanged(const QColor &c); //设置动作栏颜色
QMdiSubWindow *findMyChild(const QString &fileName); //查找子窗口
void enabledText(); //设置格式菜单及其对应的工具按钮变为可用状态
MyChild *activeMyChild(); //活动窗口
QSignalMapper *windowMapper;
//菜单
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 *quitAct; //退出
//【编辑】主菜单
QAction *undoAct; //撤销
QAction *redoAct; //重做
QAction *cutAct; //剪切
QAction *copyAct; //复制
QAction *pasteAct; //粘贴
//【格式】主菜单
QAction *boldAct; //加粗
QAction *italicAct; //倾斜
QAction *underlineAct; //下划线
QAction *leftAlignAct; //左对齐
QAction *centerAlignAct;//居中
QAction *rightAlignAct; //右对齐
QAction *justifyAct; //两端对齐
QAction *colorAct; //颜色
//【窗口】主菜单
QAction *closeAct; //关闭
QAction *closeAllAct; //关闭所有
QAction *tileAct; //平铺
QAction *cascadeAct; //层叠
QAction *nextAct; //下一个
QAction *previousAct; //前一个
QAction *separatorAct; //
//【帮助】主菜单
QAction *aboutAct; //关于本软件
QAction *aboutQtAct; //关于Qt
QToolBar *fileToolBar; //"文件"工具条
QToolBar *editToolBar; //"编辑"工具条
QToolBar *formatToolBar;//"格式"工具条
QToolBar *comboToolBar; //组合框选择栏
QComboBox *comboStyle; //标号与编号类型选择框
QFontComboBox *comboFont;//字体选择框
QComboBox *comboSize; //字号选择框
private slots:
void about();
void fileNew(); //新建文件操作
void fileOpen(); //打开文件操作
void fileSave(); //保存文件操作
void fileSaveAs(); //另存为文件操作
void undo(); //撤销
void redo(); //重做
void cut(); //剪切
void copy(); //复制
void paste(); //粘贴
void textBold(); //加粗
void textItalic(); //倾斜
void textUnderline(); //下划线
void textFamily(const QString &f); //字体选择框
void textSize(const QString &p); //字号
void textAlign (QAction *a); //设置段落对齐格式
void textColor(); //设置字体颜色
void textStyle(int styleIndex); //设置段落的风格
void filePrint(); //打印文档
void filePrintPreview(); //打印预览文档
void printPreview(QPrinter *); //
void updateMenus(); //更新菜单
void updateWindowMenu(); //更新窗口菜单
MyChild *createMyChild(); //创建子窗口
void setActiveSubWindow(QWidget *window);
protected:
void closeEvent (QCloseEvent *event);
};
#endif // MYWORD_H
myword.cpp
#include "myword.h"
#include <QtWidgets>
#include "mychild.h"
#include <QIcon>
#include <QFont>
#include <QPixmap>
/*
* setHorizontalScrollBarPolicy和setVerticalScrollBarPolicy函数,只要设置
* Qt::ScrollBarAlwaysOff就可以隐藏滚动条,此处设置为Qt::ScrollBarAsNeeded表示
* 滚动条在需要(子窗口较多,主区域显示不下)时才出现
*/
class QString rsrcPath = ":/images";
Myword::Myword(QWidget *parent)
: QMainWindow(parent)
{
move(200, 150);
resize (800, 500);
setWindowIcon (QIcon(rsrcPath + "/qt.png"));
setWindowTitle (tr("Myself Word"));
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();
updateMenus ();
}
Myword::~Myword()
{
}
/*
* 更新菜单的槽函数
*/
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 ());
//关联动作的触发信号到信号映射器的map()槽,这个槽会发送mapped()信号
connect (action, SIGNAL(triggered(bool)), windowMapper, SLOT(map()));
//动作作与相应的窗口部件进行映射,在发送mapped()信号时就会以这个窗口部件为参数
windowMapper->setMapping (action, windows.at (i));
}
enabledText (); //使得字体设置菜单可用
}
/*
* 主菜单
*/
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(quitAct);
//“编辑”主菜单
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(centerAlignAct);
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::createActions ()
{
//文件菜单动作集
newAct = new QAction(QIcon(rsrcPath + "/filenew.png"), tr("新建(&N)"), this);
newAct->setShortcut (QKeySequence::New);
newAct->setToolTip ("新建"); //设置工具栏按钮的提示文本
newAct->setStatusTip ("新建一个新文档"); //设置按钮状态栏提示文本
connect(newAct, SIGNAL(triggered(bool)), this, SLOT(fileNew()));
openAct = new QAction(QIcon(rsrcPath + "/fileopen.png"), tr("打开(&O)"), this);
openAct->setShortcut (QKeySequence::Open);
openAct->setToolTip ("打开");
openAct->setStatusTip ("打开已存在的文档");
connect (openAct, SIGNAL(triggered(bool)), this, SLOT(fileOpen()));
saveAct = new QAction(QIcon(rsrcPath + "/filesave.png"), tr("保存(&S)"), this);
saveAct->setShortcut (QKeySequence::Save);
saveAct->setToolTip ("保存");
saveAct->setStatusTip ("将当前文档存盘");
connect (saveAct, SIGNAL(triggered(bool)), this, SLOT(fileSave()));
saveAsAct = new QAction(tr("另存为(&A)..."), this);
saveAsAct->setShortcut (QKeySequence::SaveAs);
saveAsAct->setStatusTip (tr("以一个新名字保存文档"));
connect (saveAsAct, SIGNAL(triggered(bool)), this, SLOT(fileSaveAs()));
printAct = new QAction(QIcon(rsrcPath + "/fileprint.png"), tr("打印&P"), this);
printAct->setShortcut (QKeySequence::Print);
printAct->setToolTip ("打印");
printAct->setStatusTip (tr("打印文档"));
connect (printAct, SIGNAL(triggered(bool)), this, SLOT(filePrint()));
printPreviewAct = new QAction(tr("打印预览..."), this);
printPreviewAct->setStatusTip (tr("打印预览效果"));
connect (printPreviewAct, SIGNAL(triggered(bool)), this, SLOT(filePrintPreview()));
quitAct = new QAction(tr("退出"), this);
quitAct->setShortcut (tr("Ctrl+Q"));
quitAct->setStatusTip (tr("退出应用程序"));
connect (quitAct, SIGNAL(triggered(bool)), qApp, SLOT(closeAllWindows()));
//编辑菜单动作集
undoAct = new QAction(QIcon(rsrcPath + "/editundo.png"), tr("撤销(&U)"), this);
undoAct->setShortcut (QKeySequence::Undo);
undoAct->setToolTip (tr("撤销"));
undoAct->setStatusTip ("撤销当前操作");
connect (undoAct, SIGNAL(triggered(bool)), this, SLOT(undo()));
redoAct = new QAction(QIcon(rsrcPath + "/editredo.png"), tr("重做(&R)"), this);
redoAct->setShortcut (QKeySequence::Redo);
redoAct->setToolTip (tr("重做"));
redoAct->setStatusTip (tr("恢复之前操作"));
connect (redoAct, SIGNAL(triggered(bool)), this, SLOT(redo()));
cutAct = new QAction(QIcon(rsrcPath + "/editcut.png"), tr("剪切(&T)"), this);
cutAct->setShortcut (QKeySequence::Cut);
cutAct->setToolTip (tr("剪切"));
cutAct->setStatusTip (tr("从文档中裁剪所选内容,并将其放入剪贴板"));
connect (cutAct, SIGNAL(triggered(bool)), this, SLOT(cut()));
copyAct = new QAction(QIcon(rsrcPath + "/editcopy.png"), tr("复制(&C)"), this);
copyAct->setShortcut (QKeySequence::Copy);
copyAct->setToolTip (tr("复制"));
copyAct->setStatusTip (tr("拷贝所选内容,并将其放入剪切板"));
connect (copyAct, SIGNAL(triggered(bool)), this, SLOT(copy()));
pasteAct = new QAction(QIcon(rsrcPath + "/editpaste.png"), tr("粘贴(P)"), this);
pasteAct->setShortcut (QKeySequence::Paste);
pasteAct->setToolTip (tr("粘贴"));
pasteAct->setStatusTip (tr("将剪粘板的内容粘贴到文档"));
connect (pasteAct, SIGNAL(triggered(bool)), 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 (tr("加粗"));
boldAct->setStatusTip (tr("将所选文字加粗"));
QFont bold;
bold.setBold (true);
boldAct->setFont (bold);
connect (boldAct, SIGNAL(triggered(bool)), this, SLOT(textBold()));
italicAct = new QAction(QIcon(rsrcPath + "/textitalic.png"), tr("倾斜(&I)"), this);
italicAct->setCheckable (true);
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。
- 上一篇: QT5.7操作word
- 下一篇: QT操作Word,插入表格