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.

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

在交互应用程序中撤销和重做(Undo/Redo)能力是很重要的。像常见的软件Office,AutoCAD等,有了撤销功能,用户体验更舒服。一般都会使用Command模式来实现这一功能。

命令模式通过将请求本身变成一个对象来使工具箱对象可向未指定的应用对象提出请求,这个对象可被存储并像其他对象一样被传递。这一模式的关键是一个抽象的Command类,它定义了一个可执行操作的接口。其最简单的形式是一个抽象的Execute操作。具体的Command子类将接收者作为其一个实例变量,并实现Execute操作,指定接收者采取动作,而接收者执行该请求所需要的具体信息。在GoF的《Design Patterns》中,给出了Command模式的一般结构,如图1.1所示:

wps_clip_image-581

Figure 1.1 Command pattern structure

将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录成日志,以及支持可撤销的操作。

支持任意层次的撤销和重做命令的最后一步是定义一个命令历史记录(Command History),或称为已执行的命令列表。从概念上理解,命令的历史记录看起来有如下形状:

wps_clip_image-5187

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

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

目录
相关文章
|
14天前
|
存储 数据安全/隐私保护
Qt Installer Framework翻译(5-3)
Qt Installer Framework翻译(5-3)
|
10月前
|
Ubuntu 编译器 网络安全
RK3568开发笔记(七):在宿主机ubuntu上搭建Qt交叉编译开发环境,编译一个Demo,目标板运行Demo测试
在之前的博文中已经搭建好了一个比较完善的ubuntu宿主机,都很完善了但是发现没有Qt交叉编译开发环境,所以还需要搭建一套Qt交叉编译开发环境。
|
9月前
|
图形学
[学习][笔记] qt5 从入门到入坟:<12>Graphics View Framework
[学习][笔记] qt5 从入门到入坟:<12>Graphics View Framework
|
11月前
|
XML 数据管理 编译器
Qt+GDAL开发笔记(二):在windows系统msvc207x64编译GDAL库、搭建开发环境和基础Demo
上一篇使用mingw32版本的gdal,过程曲折,为更好的更方便搭建环境,在windows上msvc方式对于库比较友好。
|
12月前
|
XML 数据管理 Linux
Qt+GDAL开发笔记(一):在windows系统mingw32编译GDAL库、搭建开发环境和基础Demo
麒麟系统上做全球北斗定位终端开发,调试工具要做一个windows版本方便校对,北斗GPS发过来的是大地坐标,应用需要的是经纬度坐标,所以需要转换,可以使用公式转换,但是之前涉及到了另一个shang市公司项目使用WG,最终选择了GDAL库进行转换。
|
Ubuntu IDE Java
Qt+QtWebApp开发笔记(一):QtWebApp介绍、下载和搭建基础封装http轻量级服务器Demo
在arm上做了Qt的应用程序,为了在局域网实现web页的访问方式来配置arm上Qt的程序,局域网轻量级http服务器是很好的实现方式之一,有机会做国产麒麟上Qt的http服务器,正好接触到了QtWebApp可以实现。   本篇实战解说QtWebApp的轻量级Demo。   本篇篇幅较长,为了保持基础的完整性将必要的东西都放在本篇。
|
JavaScript 前端开发 C++
JavaScript 调用 C++/Qt 工程(附有代码 + demo)
JavaScript 调用 C++/Qt 工程(附有代码 + demo)
|
IDE 编译器 开发工具
统信UOS系统开发笔记(四):从Qt源码编译安装之编译安装QtCreator4.11.2,并配置编译测试Demo
上一篇已经从Qt源码编译了Qt,那么Qt开发的IDE为QtCreator,本篇从源码编译安装QtCreator,并配置好构建套件,运行Demo并测试。
|
数据可视化
Qt开发技术:Q3D图表开发笔记(二):Q3DBar三维柱状图介绍、Demo以及代码详解
qt提供了q3d进行三维开发,虽然这个框架没有得到大量运用也不是那么成功,性能上也有很大的欠缺,但是普通的点到为止的应用展示还是可以的。   其中就包括华丽绚烂的三维图表,数据量不大的时候是可以使用的。   上一篇介绍了基础的q3d散点图,本篇介绍基础的柱状图。
Qt开发技术:Q3D图表开发笔记(二):Q3DBar三维柱状图介绍、Demo以及代码详解
|
Java C++
Qt+QtWebApp开发笔记(二):http服务器日志系统介绍、添加日志系统至Demo测试
上一篇使用QtWebApp的基于Qt的轻量级http服务器实现了一个静态网页返回的Demo,网页服务器很重要的就是日志,因为在服务器类上并没有直接返回,所以,本篇先把日志加上。