Qt Undo Framework Demo

來源:互聯網
上載者:User

標籤:

Qt Undo Framework Demo

[email protected]

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/View

1. Introduction

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

命 令模式通過將請求本身變成一個對象來使工具箱對象可向未指定的應用對象提出請求,這個對象可被儲存並像其他對象一樣被傳遞。這一模式的關鍵是一個抽象的 Command類,它定義了一個可執行操作的介面。其最簡單的形式是一個抽象的Execute操作。具體的Command子類將接收者作為其一個執行個體變 量,並實現Execute操作,指定接收者採取動作,而接收者執行該請求所需要的具體資訊。在GoF的《Design Patterns》中,給出了Command模式的一般結構,1.1所示:

Figure 1.1 Command pattern structure

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

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

Figure 1.2 Command History

每 個圓代表一個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所示:

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所示:

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

Qt Undo Framework Demo

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.