在上一篇里,我们完成了动作的创建,那么这一次,我们把它加载到界面上,把需要是实现的动作都加上。
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();//调用创建工具条
updateMenus();//更新菜单条目
resize(800,600);
setWindowTitle(tr("Office办公自动化文字编辑 软件 V2.1"));
setUnifiedTitleAndToolBarOnMac(true);
}
上一次我们玩还曾了create Actions(),接下来,我们要完成createMenus(),createToolBars()等功能。
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);
}
创建菜单,通过menuBar()的addMenu函数添加,再往里面添加动作,顺便还添加了分隔符addSeparator()。
其他也一样添加进去就好了
//编辑菜单
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);
在窗口这个动作里,我们链接函数就好了
Qmenu类下有一个信号为 aboutToShow,该信号在Qmenu展开时触发。
所以:
在连接的槽函数里我们去添加:
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->addSeparator();
//如果有活动窗口,则显示分隔条
QList<QMdiSubWindow*> windows=mdiArea->subWindowList();
separatorAct->setVisible(!windows.isEmpty());
//遍历各个子窗口,显示当前已打开的文档子窗口项
for(int i=1;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()),windowMapper,SLOT(map()));
//动作作与相应的窗口部件进行映射,在发送mapped()信号时就会以这个窗口部件为参数
windowMapper->setMapping(action,windows.at(i));
}
enabledText();//使得字体设置菜单可用
}
接下来就是要创建工具条了:
跟创建菜单行为其实差不多,就是函数名字稍微变了一下:
void MyWord::createToolBars()
{
//文件
fileToolBar=addToolBar(tr("文件"));
fileToolBar->addAction(newAct);
fileToolBar->addAction(openAct);
fileToolBar->addSeparator();
fileToolBar->addAction(saveAct);
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(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));
}
}
把他们连接到对应槽函数,我们一步一步去实现就好了,
Qt foreach是一种用于遍历容器类型的语法结构。与传统的for循环相比,foreach更加易读、易写、易错,由此减少代码出错的概率。Qt foreach在Qt 4.0中被引入,可以用于遍历数组、QList、QVector、QSet、QMap和QHash等容器类型。
foreach (声明变量, 容器) { …… }
接着我们把细节一点一点去完善:
//判断是否有活动子窗口用activeMyChild()函数
MyChild *MyWord::activeMyChild()
{
//若有活动窗口,则将其内的中心部件转换为MyChild类型,若没有直接返回0
if(QMdiSubWindow *activeSubWindows=mdiArea->activeSubWindow()){
return qobject_cast<MyChild*>(activeSubWindows->widget());
}
return 0;
}
//发现子窗口操作
QMdiSubWindow *MyWord::findMyChild(const QString &filename)
{
/*canonicalFilePath ()可以除去路径中符号链接,如“.”和“..”等符号。这个
*函数只是将加载文件的路径首先保存到canonicalFilePath中,然后再进行一些状态的设置*/
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::setActiveSubWindow(QWidget *window)
{
if(!window){
return;
}
mdiArea->setActiveSubWindow(qobject_cast<QMdiSubWindow*>(window));
}
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;
}
还有其他一些动作的函数没有实现,下一期就写出来!!!
感谢阅读!!!!!!