在上一篇里,我們完成了動作的創建,那么這一次,我們把它加載到界面上,把需要是實現的動作都加上。
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類型,若沒有直接返回0if(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;
}
還有其他一些動作的函數沒有實現,下一期就寫出來!!!
感謝閱讀!!!!!!