qooxdoo入门教程一:应用程序界面简单设计

第1部分:从一个Tweets应用开始

简介

本教程将通过一系列比“Hello World”更深入的教程,从多个的实用角度来展示桌面qooxdoo应用的开发过程。你可以在qooxdoo下载包的framework中的DEMO目录中找到更多的示例程序,比如Feedreader等。

从教程的标题来看,我们创建一个简单的Tweets应用程序(Tweets是Identi.ca网站用来是阅读和发布的象twitter服务一样的公共短信息的应用程序)。

下面的图片展示了应用程序完成后的样子。

你会看到这个应用程序有一个窗口,包含一个工具栏,一个列表,一个文本区域和一个发布消息按钮。这是一个非常典型的qooxdoo应用程序界面。

在教程的第一部分,我们将学习如何创建一个新的应用程序,以及如何建立这个程序界面。

开始

第一步是设置一个qooxdoo应用程序开发环境来开始我们的开发工作。首先你要下载一个ActivePython脚本语言程序交并安装,我们将使用它来建立应用程序的初始框架以及后期开发过程中的程序编译发布等工作。下面我们需要下载一份qooxdoo SDK(假设我们的WEB服务器的文档根目录为D:\WebRoot目录)。并将其解压到D:\WebRoot\qooxdoo目录下。使用D:\WebRoot\qooxdoo目录下的create-application.py脚本命令创建一个qooxdoo应用程序开发框架。使用cmd窗口输入命令如下:

create-application.py -n tweets -t desktop -o d:\webroot\ -s tweets

参数说明:-n 应用名称  -t 应用类型 -o 程序输出目录 -s 应用的命名空间名称

命令执行后应该会自动在d:\webroot下生成一个tweets目录。将当前目录更改到d:\webroot\tweets目录并运行 generate.py source命令来解决应用系统的类的依赖关系。现在你可以打开一个浏览器,输入地址:http://127.0.0.1/tweets/source查看一下初始框架的效果。

用你喜欢的编辑器打开位于source/class/tweets/目录下Application.js文件,这个文件中的main函数就是整个应用系统的入口函数。我们会在这个文件中看到创建了一个按钮的代码,以及当这个按钮按下时触发一个显示hello world的事件,我们不需要这个,所以删除这些代码及所有关于它的监听代码。

接下来,我们首先创建一个窗口。这个窗口包含所有的UI控件,我们将从qooxdoo Window继承一个新的类并在这个类的内部添加控制命令。建立一个新的类就是建立一个新文件。在Application.js文件同目录下建立一个新文件,并命名 MainWindow.js,添加一些代码到新文件中。使用qooxdoo中的qx.Class.define函数创建一个类。将下面的代码添加到新创建的文件中。

qx.Class.define("tweets.MainWindow",

{

extend : qx.ui.window.Window,

construct : function()

{

this.base(arguments, "tweets");

}

});

这样通过对qooxdoo Window的继承我们就建立了一个我们自己的类。在这个类的构造函数中,我们通过qooxdoo Window构造函数的第一个参数设置窗口的标题,通过this.base(arguments)调用覆盖基类的方法,在这里它是在构造函数里调用,所以他所调用的就是基类的构造函数。为了测试这个窗口,我们需要在主应用程序创建它的一个实例。在主应用程序 Application.js文件中添加如下两行代码来创建并打开窗口。请确保将代码添加到application class中的main函数中。

Var main = new tweets.MainWindow();

main.open();

下面所有的测试都可以在浏览器中完成。但在测试之前我们还需要做一件事情,就是运行generate.py生成器命令。因为我们在系统中增加了窗口类。它需要一个新的依赖关系。所以运行需要运行generate.py source命令,然后在浏览器中打开页面。这时您应该看到一个窗口,并且在它的左上角有“tweets”应用名称。

窗口运行配置

教程的最后一个任务就是配置窗口。在打开窗口时窗口的显示位置在浏览器的左上角,很不好看,为了将窗口的显示位置离开浏览器的边缘。需要在您的应用程序添加以下代码:

main.moveTo(50,30);

//main.center();  //窗口居中显示

另外我们应该配置窗口的控制按钮。让用户不能关闭、最小化和最大化窗口。在窗口的构造函数中添加以下代码:

this.setShowClose(false);

this.setShowMaximize(false);

this.setShowMinimize(false);

最后一件事就是改变启动时窗口的大小。当然,运行时用户也可以改变窗口的大小,但是为了启动应用程序就有一个好看的窗口,应该在程序启动时设置窗口的初始大小。改变窗口大小和隐藏控制按钮一样容易,只是在窗口的构造函数加入如下代码:

this.setWidth(250);

this.setHeight(300);

这时运行程序,您的应用程序应该像下图这样。

由于以上代码没有增加新的类的调用,所以应用不需要调用generate.py命令。

我们需要做的第下一件事情就是为我们的窗口设置一个组件布局。 在上面的界面中你可以看到文本区域和按钮并排在一行而其它所有元素垂直排列。但是,所有的元素都可以看做在网格中对齐排列的,因此我们选择为当前窗口选择一个网格布局。在我们的窗口类中添加网格布局,就是在MainWindow.js文件中添加下面这些代码:

var layout = new qx.ui.layout.Grid(0,0);

this.setLayout(layout);

没有任何内容的布局是没有意义的,所以下面给布局添加一些内容,看看它是否正常运行。让我们添加系统的前两个元素Toolbar和List View到窗口布局中。

Layout和Toolbar

我们需要在添加工具栏前创建它。创建工具栏并将其直接添加到布局中。

var toolbar = new qx.ui.toolbar.ToolBar();

this.add(toolbar, {row: 0, column: 0});

上面的代码就将工具栏添加到主窗口的网格布局中。 你唯一需要注意的事情就是add()函数的第二个参数。它包含了布局属性的位置信息。你可以在Layout API中查找在这种网格布局情况下可用的布局属性,在这里,我们只使用row和column两个属性来告诉布局toolbar位于网格布局的第一行、第一列(row和column以0开始)。

Layout和List

添加List到布局的代码看起来很熟悉。

// list

var list = new qx.ui.form.List();

this.add(list, {row: 1, column: 0});

现在在浏览器中看看我们的工作效果。同样的,在代码中我们增加了新的类,它需要新的依赖关系,因此我们需要调用generate.py生成器来重新生成代码。之后,我们就可以在浏览器中看到结果了。但这我们看到的结果却不是我们想要的样子,看不到Toolbar,List与窗口边框有太多的填充而且也没有充满整个窗口。这些事项都我们需要考虑的。

首先,我们不需要List与窗口边框之间的填充。解决这个问题我们中需要修改window对象的一个默认的内容填充属性即可。

this.setContentPadding(0);

将这一行代码加入到主窗口的构造函数中,填充就去除了。

接下来,我们需要考虑List的大小。Layout并不知道哪一列(几列)或哪一行(几行)应该扩展。为此我们需要告诉Layout:

layout.setRowFlex(1, 1);

layout.setColumnFlex(0, 1);

代码第一行告诉Layout第二行(也就是List所在行)大小需要扩展。第二行代码对Layout的第一列执行相同的设置。

我们需要做的最后一件事就是解决Toolbar不可见的问题。如果你知道Toolbar不可见的原因,你肯定也知道怎么解决。原因就是Toolbar没有包含任何一个组件所以它看不到,下面我们给它加入一个组件。在我们教程的这个例子中,我们需要添加一个刷新按钮。我们已经知道如何创建和添加组件,所以只需要在文件中添加以下代码。

var reloadButton = new qx.ui.toolbar.Button("Reload");

toolbar.add(reloadButton);

现在看看所有的修改就否都完成了,记住一定要在重新加载浏览器页面之前在运行代码生成器,因为我们以增加了一个新的类(button)。我们看到的结果正是我们想要的样子。

TextArea 和Button

在以上面容成功后,我们可以继续进行下一个任务了,添加Text Area和“Post”按钮,象前在的场景一样直接添加它们。

// textarea

var textarea = new qx.ui.form.TextArea();

this.add(textarea, {row: 2, column: 0});

// post button

var postButton = new qx.ui.form.Button("Post");

this.add(postButton, {row: 2, column: 1});

这一次,我们在布局的第二列添加一个POST的按钮,并使其与TextArea水平对齐。再次生成并重新加载进行测试。

像上次一样,显示结果并不是我们希望的样子。Toolbar和List没有填满整个窗口。不要仅,这是一个我们自己的问题,因为我们添加按钮的动作将Layout扩大到了两列。 List和Toolbar需要跨越两列才能得到我们想要的结果。这很容易,在向布局中添加List和Toolbar控件时使用一个合并单元格的布局属性colSpan:2。代码应该是下面这样:

this.add(toolbar, {row: 0, column: 0, colSpan: 2});

this.add(list, {row: 1, column: 0, colSpan: 2});

为UI添加动作

现在的用户界面看起来就是我们想要的。 但如何将UI与应用程序的后台逻辑代码进行沟通呢? 使用事件通知的方式将UI与程序逻辑处理分离就是一个好方法。如果你仔细看就会发现我们的应用只需要UI向后台逻辑发送两个事件通知:重载Tweets和发一个Tweet。

我们添加这两个事件到窗口中。 添加事件分为两步。 首先,我们需要声明想要触发什么样的事件。 因此,我们窗口类定义的构造函数中加事件定义部分:

events :

{

"reload" : "qx.event.type.Event",

"post"   : "qx.event.type.Data"

},

正如你看到的代码,它逗号结束。是否需要以逗号结尾取决于你将代码复制在什么位置,你只需确定这个类的定义是一个有效的JavaScript对象就可以了。现在再回到事件中,reload事件是一个普通的事件,只是通知接收器重新载入。post事件需要将包含的数据发布到identica中,是一个数据事件,这就是为什么需要使用两种不同类型的事件。

声明该事件是使用事件的第一步骤。 第二个步骤就是触发事件!让我们来看看在重载事件,在载入按钮被触发(qooxdoo的说法是执行)时执行这个重载事件。按钮本身有触发执行事件,所以我们可以使用按钮本身的触发执行事件来触发我们自定义的重载事件。

reloadButton.addListener("execute", function() {

this.fireEvent("reload");

}, this);

这里,我们做了两件事情:第一添加一个事件监听器,第二触发一个事件就象调用一个方法一样简单。 fireEvent()唯一的参数是我们在类定义中声明的事件的名称。另一个有趣的事情是addListener函数的第三个参数this。它设置在我们的窗口实例中回调函数要使用的上下文对象,因此this.fireEvent()中的this才能被正确解析。

接下来的代码虽有一些不同,但也很容易。

postButton.addListener("execute", function() {

this.fireDataEvent("post", textarea.getValue());

}, this);

这一次,我们使用fireDataEvent方法对数据事件进行触发。这个方法的第二个参数就是这个数据事件中需要嵌入的数据。在这里我们只是简单地使用文字区域的值。为了测试这两个事件,我们需为每个事件在我们的应用程序代码中添加一个调试监听器,在application.js的main()方法加入下面代码:

main.addListener("reload", function() {

this.debug("reload");

}, this);

main.addListener("post", function(e) {

this.debug("post: " + e.getData());

}, this);

在这两个事件中我们使用了qooxdoo调试功能中的debug函数。现在我们可以对整个用户界面进行测试了。使用一个你喜欢的浏览器打开索引文件,就会看到UI的效果。如果想看到的调试信息,你必须打开你所选择浏览器中的调试工具或者使用qooxdoo的调试控制台。 按F7可以使qooxdoo控制台可见。

结束工作

在这个任务的最后,我们可以对用户界面进行一些完善。如果文本区域有一些文本告诉你应该在这里输入你的信息,工具栏显示一些提示信息告诉用户一些更详细信息?这样用户界面就显的更加友好了。达到上面的目的非常容易!

reloadButton.setToolTipText("Reload the tweets.");

textarea.setPlaceholder("Enter your message here...");

postButton.setToolTipText("Post this message on identi.ca");

另外一个很好的设置就是在窗口标题栏中加入一个Identica的Logo。只要从identica网上下载一个Logo的PNG图标,将其保存在的应用程序的source/resource/tweets目录中。为窗口添加图标是容易的因为窗口有一个添加图标的属性,你可以在窗口的构造函数中设置这个属性。

this.base(arguments, "tweets", "tweets/logo.png");

这一次,我们以增加了一个新的图像。图像类的也需要依赖关系,因此我们需要再次运行代码生成器。然后,就可以在windows的标题栏中看到图像了。

下面还有两个小的改动需要来完成。 首先,按钮看起来不怎么好。因此我们应该给它一个固定的宽度,并让它的高度自适应。

postButton.setWidth(60);

最后一个任务相对与前面的调整有些复杂。你可能知道,identica信息最大只能有140个字符。所有输入的信息超过140个字符时候应该禁用POST按钮,这样可以帮助后台通信层更好的运行。 完全没有文字的identica消息也是不可用的,那么在在这种情况下也应该禁用POST按钮。为了得到我们想要的效果,当文本区域中的文本被改变的时候应该通知我们进行一些设置,幸运的是,文本区域有一个文字变化的数据事件,下面我们来监听这个事件:

textarea.addListener("input", function(e) {

var value = e.getData();

postButton.setEnabled(value.length < 140 && value.length > 0);

}, this);

这个事件处理程序只有两行,首先取得文本区域中更改的文本内容。第二行根据文本内容长度是否超过140或长度为0来设置POST按钮的enabled属性。有些人可能感觉这些代码不好,因为用户每添加一个字符监听器就会被调用一次, 但这不是一个问题,因为qooxdoo属性系统已经考虑到了,如果传入的setter的值与现有的值一样,它会被忽略也不会触发事件。

我们考试的最后一件事是应用程序启动时。文本区是空的,但POST按钮中有效的。因此我们要禁止按钮。

postButton.setEnabled(false);

现在回到浏览器中测试一下我们的新的调整,构建用户界面工作就全部完成了。

时间: 2024-10-12 14:09:55

qooxdoo入门教程一:应用程序界面简单设计的相关文章

ibatis入门教程一

这几天研究ibatis玩,参考一篇贴子进行安装配置:蓝雪森林 选择这个帖子来跟随配置是因为这个帖子看着比较干净,但是我仍旧在配置得过程中出现了好几个问题,所以我决定在这个帖子的基础上将更多细节加上,做一个傻瓜教程. 一.前期准备 虽然ibatis能处理多种数据库,不过初学者还是比较适应mysql,因此我选择mysql作为我的数据载体.另外我准备建的是一个普通的java 工程,并采用maven命令行来建立这个工程.所以在这之前,电脑上需要安装maven和mysql. 二.工程建立 ①使用maven

漫谈vfp程序界面及设计观

软件业发展到今天,我们的用户早已不满足简单的界面.于是,一部分软件设计师便以UI设计师的身份从开发人员的队伍里分化出来,他们借鉴消费心理学的经验,就像走在夜都市的绚烂街道上,就像陶醉在超市里花花绿绿的货架前,通过精心设计,使软件产品在展示屏幕前,带给人们瞳孔放大的强烈视觉冲击力. 对于VFP无法支持基于子窗体设计原理来实现的流行Skin的情形,使得不少程序员伤透了脑筋,伴随过无数个失眠的夜晚.原因是VFP的控件是"自绘"的,而不是象其它的开发工具那样从MicroSoft Common

[转]无废话SharePoint入门教程一[SharePoint概述]

本文转自:http://www.cnblogs.com/iamlilinfeng/p/3026332.html 一.前言 听说SharePoint也有一段时间了,可一直处在门外.最近被调到SharePoint实施项目小组,就随着工作一起学习了一下实施与开发.但苦于网上SharePoint入门的东西实在太少,导致自学入门很难,不知道SharePoint这东西到底能做什么.因此有了此篇文章.该文章只是基于本人对SharePoint的理解,希望能够帮助那些还在门外的同学.由于能力有限,有说的不明白的地

python教程---爬虫入门教程一

此次教程使用的python版本为2.7!!! 在刚上大学之时,总是在网上看到什么爬虫,因为当时还在学习c++,没有时机学习python,更没有去学习爬虫了,而趁着这次工程实训学习了基本的python的使用,于是有提起了学习爬虫的兴致,也写下了这个系列的博客,以记录自己的积累 下面进入正题: 爬虫是什么? 网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动的抓取万维网信息的程序或者脚本. 在学习爬虫时需要用到那些知识呢? Python基

Gemini.Workflow 双子工作流入门教程一:定义流程:流程图属性

简介: Gemini.Workflow 双子工作流,是一套功能强大,使用简单的工作流,简称双子流,目前配套集成在Aries框架中. 下面介绍本篇教程:流程定义:流程图属性. 步骤一:在流程管理的流程定义中,新增流程 步骤二:设置流程图属性,控制总开关: 流程图右侧,有些属性可以设置,这里设置的是总开头,流程节点有有相应的设置,只有满足总开关和流程节点同时打开,开关才有效. 下面介绍属性控制的地方: 1.是否显示流程图: 在流程办理界面中,右上角有个“查看流程图”按钮. 点击的话可以看到: 2.其

【Cocos2d入门教程一】Cocos2d-x环境搭建

在进行Cocos2d游戏开发前 我们先来配置一下环境,我们先来准备一下工具,我们所需要的工具分别为: 1.Cocos2d引擎 2.JDK 3.SDK 4.NDK 5.ANT 6.ADT 1.下载Cocos2d-x引擎,目前最新版本为3.6,本教程的所有例子以3.4版本为例,下载完直接解压即可.点击下载Cocos2d引擎 2.JDK 检查自己电脑上是否已装好JDK环境 方法:打开终端,输入 java–version 如果没有安装过,点击下载JDK 效果如下: 3.ADT下载,ADT被称为安卓的集成

【Cocos2d入门教程一】Cocos2d下安卓环境的搭建

在进行Cocos2d游戏开发前 我们先来配置一下环境,我们先来准备一下工具,我们所需要的工具分别为: 1.Cocos2d引擎 2.JDK 3.SDK 4.NDK 5.ANT 6.ADT 1.下载Cocos2d-x引擎,目前最新版本为3.6,本教程的所有例子以3.4版本为例,下载完直接解压即可.点击下载Cocos2d引擎 2.JDK 检查自己电脑上是否已装好JDK环境 方法:打开终端,输入 java–version 如果没有安装过,点击下载JDK 效果如下: 3.ADT下载,ADT被称为安卓的集成

一起学Google Daydream VR开发,快速入门开发基础教程一:Android端开发环境配置一

原文因涉及翻墙信息,被强制删除,此文为补发! 准备工作 进入Google Daydream开发者官网,开启准备工作,官网地址:https://vr.google.com/daydream/developers/ -------------------------------------------------------------------------------------------------------------------- Google Daydream开发者网址: https

C#系列教程一:C#的前世今生,VS了解

我的学习历程 回头想想,其实没碰windows的时间真的很长了.我大概是两年前的时候开始做iOS开发的,2012年3月份吧.从那以后就很少用到windows系统.现在工作都用mac机器,对windows的好感也越来越淡,再加上坑爹的windows8,我本来以为我再也不可能碰windows了,没想到最近的项目又让我不得不重新拾起以前的windows编程,继续C#开发. 我大二的时候开始接触windows编程,那时候VC++很流行,感觉C++也不错,自己可以手动画一个窗体有点狂拽炫酷叼.以前有画过类