• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            eryar

            PipeCAD - Plant Piping Design Software.
            RvmTranslator - Translate AVEVA RVM to OBJ, glTF, etc.
            posts - 603, comments - 590, trackbacks - 0, articles - 0

            Qt Undo Framework Demo

            Posted on 2015-01-13 18:59 eryar 閱讀(6729) 評論(0)  編輯 收藏 引用 所屬分類: 2.OpenCASCADE

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

            1. Introduction

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

            命令模式通過將請求本身變成一個對象來使工具箱對象可向未指定的應(yīng)用對象提出請求,這個對象可被存儲并像其他對象一樣被傳遞。這一模式的關(guān)鍵是一個抽象的Command類,它定義了一個可執(zhí)行操作的接口。其最簡單的形式是一個抽象的Execute操作。具體的Command子類將接收者作為其一個實例變量,并實現(xiàn)Execute操作,指定接收者采取動作,而接收者執(zhí)行該請求所需要的具體信息。在GoF的《Design Patterns》中,給出了Command模式的一般結(jié)構(gòu),如圖1.1所示:

            wps_clip_image-581

            Figure 1.1 Command pattern structure

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

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

            wps_clip_image-5187

            Figure 1.2 Command History

            每個圓代表一個Command對象,標有present的對象即為當前命令對象。當我們調(diào)用Unexecute()后,標有present的對象將會向左移;當調(diào)用Execute(),標有present的對象將會向右移。重復(fù)這個過程,我們可以進行多層次的撤銷,層次數(shù)只受命令歷史記錄長度的限制。

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

            v QUndoCommand:這個類相當于Command模式中的那個抽象基類Command,所有這些命令都被保存到undo棧中,在其派生類中實現(xiàn)undo和redo函數(shù)。

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

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

            v QUndoView:是顯示undo堆棧中內(nèi)容的一個列表組件,在這個視圖中點擊命令的名稱也可以實現(xiàn)與Undo/Redo按鈕相同的作用。

            本文通過一個簡單的例子來示例Qt中Undo框架,先在簡單的List模型中實現(xiàn),進而在Tree上實現(xiàn)。掌握Qt的這個框架,就可以不用OpenCASCADE的OCAF了,并且Qt的代碼用起來還是相對簡單清晰的。

            2.Example

            Qt提供了一個Undo框架的示例,程序還涉及到圖形繪制相關(guān)的內(nèi)容,程序效果如下圖2.1所示:

            wps_clip_image-17325

            Figure 2.1 Qt Undo Framework Example

            結(jié)合這個示例程序,學(xué)習一下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,并要實現(xiàn)undo()和redo()這兩個虛函數(shù),實現(xiàn)代碼如下所示:

            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())));
            }

            這樣在響應(yīng)工具欄按鈕的函數(shù)中,只需要生成這個命令,并將命令加入到命令棧中即可,代碼如下:

            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及命令列表中選擇,都可以實現(xiàn)命令的回退及重做。完整的程序代碼可通過文后鏈接下載。

            3.Conclusion

            在學(xué)習C++基本語法后,可以看看GoF的《設(shè)計模式》。剛剛接觸可能感覺有些抽象,這時可以使用Qt來編寫一些程序來練練手。用Qt來編程感覺比MFC要舒服很多,有些類封裝得很直接,易于使用。盡管MFC中也有個Document/View的設(shè)計模式,但是Qt中的MVC用起來更直接。通過使用現(xiàn)有的框架,來理解那些抽象的設(shè)計模式,從而加深面向?qū)ο蟮挠^念,讓自己的程序更簡單,有趣。

            OpenCASCADE的OCAF框架也提供了一個數(shù)據(jù)框架,基于這個樹形的框架,可以存儲層次表示的數(shù)據(jù),且也提供了Undo/Redo的支持。基于OCAF框架,可以快速開發(fā)出一定功能的專業(yè)軟件了。但是要使用OCAF框架,涉及的OpenCASCADE庫很多。如果打算開發(fā)一個輕量級的三維程序,而又正好選擇了Qt來開發(fā)GUI,這時就可以考慮使用Qt的MVC框架及在這個框架上的Undo/Redo功能,這樣開發(fā)效率可以相對高一些,且程序發(fā)布時依賴的動態(tài)庫也要少很多。

            流行的工廠設(shè)計軟件中的數(shù)據(jù)框架多用樹形結(jié)構(gòu),樹中每個結(jié)點上的屬性可以讓用戶自由擴展,像OCAF中通過TDataStd_Integer添加一些整數(shù)屬性一樣,及用TDataStd_Name添加名稱屬性。但是OCAF中添加屬性有些局限性,因為每種屬性是用GUID來區(qū)別的,所以每個結(jié)點上同一種屬性只能有一個。

            所以用Qt的MVC框架來根據(jù)需要實現(xiàn)一個自定義的樹形Model,再基于V3d_Viewer實現(xiàn)一個顯示三維的View,即可以實現(xiàn)一個簡單,但看上去相對專業(yè)的CAD建模程序了。

            4. References

            1. GoF. Design Patterns-Elements of Reusable Object-Oriented Software.機械工業(yè)出版社. 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

            国产精品久久久久9999| 免费国产99久久久香蕉| 久久99热这里只有精品66| 超级碰碰碰碰97久久久久| 中文字幕乱码人妻无码久久| 久久99精品久久久久子伦| 久久国产成人精品国产成人亚洲| 伊人色综合久久天天人守人婷| 亚洲国产精品无码久久一线| 国产91色综合久久免费分享| 91久久成人免费| 性欧美大战久久久久久久久| 伊人久久大香线焦综合四虎| 久久乐国产综合亚洲精品| 国产精品禁18久久久夂久| 区亚洲欧美一级久久精品亚洲精品成人网久久久久 | 91久久福利国产成人精品| 香蕉久久夜色精品国产尤物| 久久午夜羞羞影院免费观看| 日日狠狠久久偷偷色综合免费 | 国产午夜精品理论片久久 | 香港aa三级久久三级| 少妇久久久久久被弄高潮| 日本精品一区二区久久久| 狠狠色丁香久久婷婷综| 无遮挡粉嫩小泬久久久久久久| 热综合一本伊人久久精品| 国产精品免费久久| 日本免费久久久久久久网站| 久久午夜伦鲁片免费无码| 久久久久精品国产亚洲AV无码| 久久久久亚洲AV无码专区桃色| 色综合色天天久久婷婷基地| 国产成年无码久久久久毛片| 性高湖久久久久久久久| 久久AV高潮AV无码AV| 久久精品成人免费观看97| 青青草国产精品久久久久| 婷婷综合久久狠狠色99h| 99久久国语露脸精品国产| 国内精品人妻无码久久久影院|