Qt Undo Framework Demo

Qt Undo Framework Demo

eryar@163.com編程

Abstract. Qt’s Undo Framework is an implementation of the Command Pattern, for implementing undo/redo functionality in applications. The Command pattern is based on the idea that all editing in an application is done by creating instances of command objects. Command objects apply changes to the document and are stored on a command stack. Furthermore, each command knows how to undo its changes to bring the document back to its previous state. As long as the application only uses command objects to change the state of the document, it is possible to undo a sequence of commands by traversing the stack downwards and calling undo on each command in turn. It is also possible to redo a sequence of commands by traversing the stack upwards and calling redo on each command. 設計模式

Key Words. Qt, Undo/Redo, Command Pattern, Model/Viewapp

1. Introduction 框架

在交互應用程序中撤銷和重作(Undo/Redo)能力是很重要的。像常見的軟件Office,AutoCAD等,有了撤銷功能,用戶體驗更舒服。通常都會使用Command模式來實現這一功能。ide

命 令模式經過將請求自己變成一個對象來使工具箱對象可向未指定的應用對象提出請求,這個對象可被存儲並像其餘對象同樣被傳遞。這一模式的關鍵是一個抽象的 Command類,它定義了一個可執行操做的接口。其最簡單的形式是一個抽象的Execute操做。具體的Command子類將接收者做爲其一個實例變 量,並實現Execute操做,指定接收者採起動做,而接收者執行該請求所須要的具體信息。在GoF的《Design Patterns》中,給出了Command模式的通常結構,如圖1.1所示:函數

wps_clip_image-581

Figure 1.1 Command pattern structure工具

將一個請求封裝爲一個對象,從而使你可用不一樣的請求對客戶進行參數化;對請求排隊或記錄成日誌,以及支持可撤銷的操做。post

支持任意層次的撤銷和重作命令的最後一步是定義一個命令歷史記錄(Command History),或稱爲已執行的命令列表。從概念上理解,命令的歷史記錄看起來有以下形狀:學習

wps_clip_image-5187

Figure 1.2 Command Historyidea

每 個圓表明一個Command對象,標有present的對象即爲當前命令對象。當咱們調用Unexecute()後,標有present的對象將會向左 移;當調用Execute(),標有present的對象將會向右移。重複這個過程,咱們能夠進行多層次的撤銷,層次數只受命令歷史記錄長度的限制。

在Qt的Undo框架中主要包括如下幾個類:

v QUndoCommand:這個類至關於Command模式中的那個抽象基類Command,全部這些命令都被保存到undo棧中,在其派生類中實現undo和redo函數。

v QUndoStack:這個至關於命令歷史記錄,其中保存了Command對象的列表。

v QUndoGroup:是一個undo stack的組合。

v QUndoView:是顯示undo堆棧中內容的一個列表組件,在這個視圖中點擊命令的名稱也能夠實現與Undo/Redo按鈕相同的做用。

本文經過一個簡單的例子來示例Qt中Undo框架,先在簡單的List模型中實現,進而在Tree上實現。掌握Qt的這個框架,就能夠不用OpenCASCADE的OCAF了,而且Qt的代碼用起來仍是相對簡單清晰的。

2.Example

Qt提供了一個Undo框架的示例,程序還涉及到圖形繪製相關的內容,程序效果以下圖2.1所示:

wps_clip_image-17325

Figure 2.1 Qt Undo Framework Example

結合這個示例程序,學習一下Qt的Undo框架,從而寫出一個更簡單的程序,代碼以下所示:

class InsertCommand : public QUndoCommand
{
public:
    InsertCommand(const QModelIndex& theIndex, QStringListModel* theModel);
    ~InsertCommand();

public:
    virtual void undo();
    virtual void redo();

private:
    QModelIndex mIndex;
    QStringListModel* mModel;
};

首先,從QUndoCommand派生出一個插件字符串的類InsertCommand,並要實現undo()和redo()這兩個虛函數,實現代碼以下所示:

void InsertCommand::undo()
{
    mModel->removeRows(mIndex.row(), 1);
}

void InsertCommand::redo()
{
    mModel->insertRows(mIndex.row(), 1);
    mModel->setData(mIndex, QString("Insert string " + QString::number(mIndex.row())));
}

這樣在響應工具欄按鈕的函數中,只須要生成這個命令,並將命令加入到命令棧中便可,代碼以下:

void undoTest::insertString()
{
    QModelIndex aIndex = mListView->currentIndex();

    mUndoStack->push(new InsertCommand(aIndex, mListModel));
}

程序運行效果以下圖2.2所示:

wps_clip_image-9457

Figure 2.3 Test Qt Undo Framework

經過工具欄上的undo/redo及命令列表中選擇,均可以實現命令的回退及重作。完整的程序代碼可經過文後連接下載。

3.Conclusion

在 學習C++基本語法後,能夠看看GoF的《設計模式》。剛剛接觸可能感受有些抽象,這時能夠使用Qt來編寫一些程序來練練手。用Qt來編程感受比MFC要 舒服不少,有些類封裝得很直接,易於使用。儘管MFC中也有個Document/View的設計模式,可是Qt中的MVC用起來更直接。經過使用現有的框 架,來理解那些抽象的設計模式,從而加深面向對象的觀念,讓本身的程序更簡單,有趣。

OpenCASCADE的OCAF框架也提供了一個 數據框架,基於這個樹形的框架,能夠存儲層次表示的數據,且也提供了Undo/Redo的支持。基於OCAF框架,能夠快速開發出必定功能的專業軟件了。 可是要使用OCAF框架,涉及的OpenCASCADE庫不少。若是打算開發一個輕量級的三維程序,而又正好選擇了Qt來開發GUI,這時就能夠考慮使用 Qt的MVC框架及在這個框架上的Undo/Redo功能,這樣開發效率能夠相對高一些,且程序發佈時依賴的動態庫也要少不少。

流行的工 廠設計軟件中的數據框架多用樹形結構,樹中每一個結點上的屬性可讓用戶自由擴展,像OCAF中經過TDataStd_Integer添加一些整數屬性一 樣,及用TDataStd_Name添加名稱屬性。可是OCAF中添加屬性有些侷限性,由於每種屬性是用GUID來區別的,因此每一個結點上同一種屬性只能 有一個。

因此用Qt的MVC框架來根據須要實現一個自定義的樹形Model,再基於V3d_Viewer實現一個顯示三維的View,便可以實現一個簡單,但看上去相對專業的CAD建模程序了。

4. References

1. GoF. Design Patterns-Elements of Reusable Object-Oriented Software.機械工業出版社. 2010

2. Qt5.4. Overview of Qt’s Undo Framework. 2014

3. Qt5.4. Undo Framework Example. 2014

4. OpenCASCADE6.8.0. OCAF. 2014

5. OpenCASCADE6.8.0. OCAF White Paper. 2014

6. OpenCASCADE6.8.0. Distribution of Data Through OCAF Tree. 2014

 

PDF Version and Source code: Qt Undo Framework Demo

相關文章
相關標籤/搜索