logo资料库

Wt官方入门向导(中文翻译).doc

第1页 / 共18页
第2页 / 共18页
第3页 / 共18页
第4页 / 共18页
第5页 / 共18页
第6页 / 共18页
第7页 / 共18页
第8页 / 共18页
资料共18页,剩余部分请下载后查看
Wt C++工具包的简介
1.简介
未来Web应用程序技术
Wt来了!
2.库概要
主要的控件
会话管理
信号/槽 事件响应
国际化
无干扰的升级
会话生命周期
Wt库是如何工作的?
3.向导
无所不在的Hello World
我的第一个widget
第二个widget:释放Wt的能量
4.总结
备注:
Wt C++工具包的简介 Koen Deforche 和 Wim Dumon 2006 年 1 月 -------------------------------------------------------------------------------------------------- -- 本文由 陶桃猪 翻译 如需转载及引用 请注明出处 谢谢 -------------------------------------------------------------------------------------------------- - 限于本人翻译水平 定有错漏不妥之处 欢迎指正 -------------------------------------------------------------------------------------------------- -- 邮箱:taotaozhulz@163.com -------------------------------------------------------------------------------------------------- -- 博客:http://www.lonemover.com -------------------------------------------------------------------------------------------------- -- 2011 年 4 月 10 日 -------------------------------------------------------------------------------------------------- --
1.简介 未来Web应用程序技术 C++已经确立为开发许多应用的语言,像桌面应用,电子邮件客户端,数据库引擎等 等。但是 C++开发 Web 应用是非常少的。在 Web 应用开发中占统治地位的语言是 JAVA, PHP,Python 和 Perl。并且十分特别的是,PHP 是一个专门为 Web 开发设计的语言。其他的 一些语言都有各自的 Web 开发框架。例如,JAVA 的 J2EE 和 Structs,Perl 的 Perl::CGI 或者 Python 的 Zope。这些框架提供了会话管理,支持来自浏览器的 HTML 表单和 Cookies 传输 数据的解析,并且能够帮助在回应中生成新的页面。 以上框架所遵循的模型如图 1 所示。
图 1 每一 步,浏 览器向 服务器 请求一 个页 面,并 且可能 提交包 含一系列的表单值的请求。在服务器端,应用程序处理这个请求,标识这个会话,并且执行 业务逻辑。最后,这个应用程序生成了一个响应页面。这个响应页面可能不仅包含 HTML,还 包括 JavaScript 来加强应用程序的交互性。但是 JavaScript 在不同的浏览器里表现是不同 的,所以需要努力将其写的很好的兼容不同的浏览器。 然而,最新的获得很大成功的 Web 应用,像 Google 的 Gmail 或者 Google 地图,并 不遵循这个页面接着页面的模式。Google 使用的是一种将 JavaScript 和服务器端技术结合 起来的,通常被称为 Ajax 的技术,使用这个技术可以在不刷新页面的情况下从服务器上获 得数据并更新页面。Ajax 的原理主要是利用 JavaScript 在后台向服务器发送 HTTP 请求(例 如:有没有新的邮件?)。服务器端以 XML 的形式来生成合适的响应(例如: “Yes,2:(1)..,(2)...”)。最后,客户端的 JavaScript 解析这个响应并且通过操作 DOM 来完成页 面的更新(例如在收件箱里加两条电子邮件的消息)。 在 2005 年,Ajax 被大肆的宣传,导致了 Web 应用程序开发的根本改变。每一个事 件都需要向客户端传送一个完整的页面已经不需要了。Ajax 为 Web 加入了新的可能,因此 Ajax 有点时候是和新的更加交互性的 Web,也就是 Web2.0 相关联的。同时,使用这个技 术面临着很多挑战。为了使用 Ajax,应用开发者需要学习并理解许多的技术,除了服务端的框 架和 HTML/CSS 开发者需要学习使用 JavaScript 操作 DOM 的 DHTML,为了能使用 JavaScript 生成有效的 GET 或者 POST 请求开发者需要学习一些 HTTP 协议的细节,最后需 要学习 XMLHttpRequest API。同时,需要考虑不同浏览器的兼容性,以及对旧版本浏览器 的支持。
Wt来了! 和传统 Web 应用程序框架的页面模型相比,Wt 或者一个传统的 GUI 库所遵循的模型 是基于 widgets 的,看一下图 2。 图 2 这 些 widgets 在概念上 是以树的形式组织的,并且回调函数和特定的事件相关。为了响应一个事件,回调函数会被 调用,一些任务就会被完成,并且或者 widget 树会被修改。 Wt 是一个针对 Web 应用开发的 C++ widget 库。Wt 应用模型和现存的 GUI 库(例 如微软的 MFC 或者 TrolTech 的 Qt)是很相似的。同时,Wt 为开发者隐藏了很多潜在的技 术细节(HTML,Forms/CGI, JavaScript, Ajax 等等),就像 Qt 库如何隐藏潜在的 X 库或者微 软的 Windows GUI 的细节一样。 因为 Wt 的 API 对底层的技术(Forms,JavaScript 或者 Ajax)做了抽象,Wt 根据浏览 器支持的技术来和浏览器通信。使应用能够在一大堆浏览器种运行的责任从应用开发者身上 转移到了 Wt 库开发者身上。 在接下来介绍 Wt 的文章中,我们将会首先对主要的类和特性做一个梗概的介绍,同 时也包括 Wt 在屏幕的背后做了一些什么。接下来,我们将会展示一下如何使用 Wt 来实现 一个经典的名为“hangman”的猜词游戏。 2.库概要 主要的控件 整个用户接口被组织为一个具有继承性的 WWidget 对象的树。一个 WWidget 对应 于一个可视化的实体,例如一个文本块(WText),一个表(WTable),一条可被编辑的行
(WLineEdit),或者一个更加复杂的组合 widget(实现 WCompositeWidget 的类)。用户接口, 这里指的是 Web 的页面,是通过创建和维护一个 widget 树来实现的。每一个 WWidget 对 应于一块矩形的区域,并且维护了这块区域里的内容和事件。 Wt 这个库提供了许多直接对应于 HTML 提供的 widgets 的基本的 widgets,这些 widgets 都是 WWebWidget 的子孙(WText, Wtable, Wimage,...).这些 widgets 间接的维护 服务器端的 HTML DOM。相对比而言,WCompositeWidget 对象是通过组合其他的 widget 而实现的 widget.虽然 Wt 库提供了一些组合 widget(例如一个树列表和一个自动完成的编 辑行),这些 widgets 并不属于 Wt 库,因为他们是在 Wt 之上实现的。 每一个 Wt 应用程序必须以一个 WApplication 对象的实例化作为开始。这个对象管理 着 widget 树的根,浏览器容量信息并且使用地区设定以及消息资源束来管理国际化支持 (后面会谈到)。 会话管理 和多个应用实例如何同时运行相似,Wt 内核系统会为每一个独立的 Web 会话生成一 个 Wt 应用。 每一个新的“会话”意味着一个起始于 wmain()执行的路径已经产生,wmain()是 Wt 应用的入 口。所以,程序员只需要实现单用户的应用程序,除非用户会和一个公共的组件或者和每一 个人交互(例如数据库),在这种情况下必须使用标准的数据共享机制。 当前版本的 Wt 实现了使用不同的进程来运行不同的执行路径。所以,对于每一个新 的会话来说,Wt 会生成一个新的进程。这样的一个主要的好处在于可以享受到用户会话中 的内核级别的内存保护。所以,简单的程序错误不会自动的危及会话保密性。这个方法的不 好的一面在于它的的成本:当前的内核实现对于每一个进程来说,可能需要一定量的非可交 换的内存。在未来,Wt 会提供不同的线程实现的选择,包括用户级别的线程。 信号/槽 事件响应 Wt 使用一个信号/槽的机制来实现事件的响应。用户界面的事件,例如鼠标点击,或 者文本修改,会被 Wt 暴露为和特定 widget 相关的信号。为了响应事件,程序员将信号和 一个槽连接。任何的拥有一个和信号相兼容的签名的对象方法,都可以用来作为槽。当信号 被触发的时候,所有和这个信号连接的槽都会被调用。这个信号/槽的机制是一个建立良好 的,类型安全的并且自我管理的回调机制。
国际化 考虑到互联网固有的广域特征,国际化和本地化是一个网站非常重要的属性。Wt 通 过提供消息资源束来帮助实现网站的国际化。一个 WMessage 对象提供了一个依赖当前本 地的一份文本。为用户显示文本的控件(例如 WText)会得到一个 WMessage 而不是一个 自然的文本。翻译的不同区域的消息会以 XML 的形式存储在消息资源文件中,每一个区域 一个文件。当需要改变应用的区域的时候,使用 WApplication::setLocale(),这样的话应用 程序会自动更新对应 widgets 的本地文本。 无干扰的升级 Web 应用的一个主要的优势在于发布者可以很方便的升级应用程序的所有拷贝,仅 仅是通过在他的网站上部署一个新的版本。通常情况下,发布者不希望在部署新的版本的时 候终止现存会话的运行,并且为新的会话提供新的版本。这种无打扰的升级是 Wt 默认的升 级方式。 会话生命周期 Wt 在客户端和服务器之间使用了一个 keep-alive 的协议来决定会话生命周期。只要 Web 页面在用户的浏览器中显示着,会话保持激活状态,否则会话将会被终止。另外,应 用程序可以通过调用 WApplication::quit()终止会话(例如为了响应用户的登出请求)。以上 的方式,当一个会话终止的时候,主要的 widget 会被销毁。这样应用程序就可以释放资源 了。 Wt库是如何工作的? Wt 实现了两个主要的工作:渲染并维护浏览器中的 HTML DOM 树和响应用户输入 和事件,例如鼠标点击。 所有可以被捕获的事件都映射到信号,这个信号和特定的 widget 相关联。当一个事 件被用户触发了之后,(例如点击 OK 按钮),浏览器和目标对象和对应的信号通信(例如 OkButton->clicked),和所有表单数据传送到服务器(使用 Ajax 或者纯 HTML 表单提交)。 在服务器端,对应的 Wt 应用实例处理所有的表单数据来更新 widget 树的状态。然后,通 过触发目标对象的信号,这个事件就被触发了, 信号触发之后,所有连接的槽都会被触发。这些槽会执行业务逻辑并且修改 widget 树。对 widget 树的修改会被 Wt 库跟踪,并且会被转化为 HTML DOM 树的服务器端模型。最后,
依赖于通信的方式,要么是 DOM 树改变了,要么是完整修改过的 DOM 树被传输到浏览 器,完成整个事件循环。 因为在使用 widget 树的用户接口和渲染树的机制上的分离,当 Ajax 有效的时候,Wt 会优化对增长响应的渲染。Wt 在和浏览器第一次通信的过程中仅仅传送可视化的 widget 改 变,通过这个方法实现上一句的目标。页面一被加载,剩下的隐藏的 widgets 改变会在后台 被传送。所以,最初的响应被优化同时接下来的一系列 widget 的显示很活泼。 3.向导 向导这一章节讨论了两个小程序来验证不同的 Wt 库概念。第一个程序是 Hello World 程序,这个小程序主要介绍了两个关键的概念:widget 树和信号/槽。第二个相对来 说大一点的程序是一个在线版本的经典 hangman 游戏,这个程序包含了一个通过一个小的 数据库支持的用户排名系统。这个游戏的在线版本是有效的(根据本人翻译时的测试结果, 链接失效,提供了备选的[1])。这个 hangman 游戏验证了一个针对更加复杂的 Web 应用 程序是如何被构建和管理的,如何实现自己的 widgets,信号和槽,如何处理布局并且提供 了一个数据是如何从数据库解析出来显示在网站上的。这个游戏包括注释的完整代码大概有 900 行。我们为本向导选取了最有趣的部分。 Wt 文档页面包含了暴露在 Wt API 下的类,方法,信号和槽的完整版本。即使是这个 hangman 游戏仅仅使用了有效的类和方法的一小部分。完整的样例程序的源码和构建它们 的 Makefiles,都包含在了 Wt 源码的发行版本中了。 无所不在的HelloWorld 任何一个程序的入口都是 wmain( )函数。最简单的 Wt 程序必须实例化 WApplication 对象,并且调用应用程序的死循环。对于 hello world 应用来说,一个 WText 对象和一个 WPushButton 加入到了 widget 树当中。这样它们就可以显示在浏览器中了。点击 Quit 按钮 会终止会话。这是通过连接 Quit 按钮的点击信号和应用程序的 quit()槽来实现的。 这里需要强调的是,没有其他的更加聪明的方法来显式的调用 Quit 这个函数。当用 户浏览离开了当前的应用,Wt 将会检测到 keep-alive 消息不在接收了,并且 Wt 将会终止 会话就好像 quit()被调用了一样。 列表 1. 有 quit 按钮的 Hello World #include #include
#include int wmain(int argc, char **argv) { } WApplication appl(argc, argv); //Widgets can be added to a parent //by calling addWidget() … appl.root()->addWidget(new WText(“

Hello, World!

”)); // … or by specifying a parent at // construction time WPushButton *Button = new WPushButton(“Quit”, appl.root()); Button->clicked.connect(SLOT (&appl, WApplication::quit)); return appl.exec(); 我的第一个widget 我们用登陆这个过程来开始我们对 hangman 这个游戏的讨论。登陆过程是由 LoginWidget 来处理。我们已经将业务逻辑减小到最少了,而且事实上是有一点简单了。 LoginWidget 请求使用他的名字和密码来向登陆返回用户,并且选择被用作游戏的词典里选 择一个有效的字典。如果用户不在当前的数据库中,我们假设他是一个新用户并且自动把他 加入数据库中。如果登陆成功,一个确认的信息将会被显示出来,否则就会提示出错并重 试。 Hangman 的 LoginWidget 验证了使用一个比较好的面向对象的风格来写一个自我维 护的拥有清新的接口并且可以插入任何需要的地方的 widget 的可能性。拥有非标准的行为 的 LoginWidget 可能不会立即成为一个可以重用的组件,但是至少证明了接口的规则。 LoginWidget 只有两个公共的成员函数。第一个是构造函数,构造函数的参数为它们的父
分享到:
收藏