html服务器框架,一种类似http/html的分布式GUI程序设计框架

笔者构想了一种类似http/html的分布式GUI程序设计框架,适用于WIndows、桌面Linux、Mac OS以及C++,Java,Python等多种支持GUI编程的程序设计系统。但是对于手机小屏幕,可能不合适。

本系统包括窗口描述规则;gui.exe -- 一个命令行程序,用于解释执行该规则,你可以把gui.exe当成python.exe这种解释器,区别是gui.exe只解释执行图形程序;guid.exe --- 这是一个GUI服务器,用于编写实际的C++函数,相应客户端请求的页面或者函数调用,并将页面、函数调用结果传给客户端。

一、页面描述、请求服务器页面、函数调用

; 变量定义

@var

a=12 b="helo world" c=12.5

; 图形界面描述

@gui

1 WINDOW name="first" click="firstclick" title="测试" top=100 left=100 width=100 height=100 image="D:\test 1.bmp"

2 PANEL

3 TEXT name="t1" caption="My..."

2 WINDOW

3 TEXT caption=b

3 PANEL

4 TEXT captiion="Hello world"

; 初始化函数

@init

; 调用本地或者远程GUI服务器中的函数,返回值存进变量。

a=gui://localhost/cpp_fun1(12,"hello") $first.title=a $first.show

;为@gui添加一行节点 这里将在第一个参数指向的控件后,添加一个控件节点。该函数不做控件"层次"检查。

; 你可以再第一层控件后添加第三层控件。也就是说,即使你push_back成功了,不表示你的窗口描述就是正确的。

;系统在创建并绘制控件时,会做检查,如果检查到你的树形结构中,第一层控件节点有个第三层子节点,报错。

$first.push_back("t1",4,"TEXT","caption", "在函数里添加控件")

; 控件的键盘、鼠标处理函数

@firstclick

$first.title="Changed Titile"

鼠标、键盘处理函数,指定控件的以下属性即可:

click:单击

dblclick:双击

mousedown:鼠标按下

mouseup:鼠标抬起

mouseover:鼠标悬浮

mouseout:鼠标离开

mousemove:鼠标移动

mouseenter:鼠标进入

mouseleave:鼠标离开

keydown:按键按下

keyup:按键抬起

keypress:按键按下抬起

cpp_fun1是GUI服务器程序中的函数。其返回值将会被GUI客户端使用。

上述@gui部分,其实是对html的改进,目的是简化编程,让程序设计者和计算机都少做点事情。笔者实现上述@gui部分,用c++大概500行代码,如果使用html/xml,笔者在网上找了一些开源的xml解析库,通常十几个到几十个文件,统计上万行代码,甚至更多。也就说代码规模小了10倍甚至几十倍。而对应软件的解析效率,估计也能打到10倍甚至更多的增长。

为什么笔者随便一个设计,就会比html、xml好这么多呢?因为笔者为其限定了语法:

以数字开头,表示控件的层次。html/xml没有这个,系统检测但是,真正的GUI设计者,应该对自己的控件的层次了如指掌。

标签/控件无需重复两次, html是这种写法。

3.以行为单位。你不能把@gui中的一行拆开来写。

4.赋值语句不能有空格,也就是说"a=3",不能写成“a = 3”。同样,函数调用、参数之间也不能有空格。

5.区分大小写。

限定语法,计算机和程序设计者都能做更少的工作。

我们可以在上述GUI里写好几个窗口:

1 WINDOW name="first" click="firstclick" title="测试" top=100 left=100 width=100 height=100 image="D:\test 1.bmp"

2 DIV

3 A href="http://gnu.org/test.gui"

4 TEXT name="t1" caption="My..."

1 WINDOW name="s"

2 TEXT name="t1" caption="My..."

然后在@init中显示特定的窗口:

$first.show

如果你想,连续显示多个窗口:

$first.show

$s.show

多数情况下,用户可能会在@firstclick等键盘、鼠标处理函数中创建并显示窗口。

二、百分比指定控件大小和位置

多数GUI库的作者没有认识到 -- 特别是那些跨平台的库 -- GUI库的各种控件应该按百分比指定长度、宽度、和在父级控件中的位置 --而不是用像素。你创建window或者button时,应该通过百分比指定大小和位置。GUI库应该有自动将百分比转化为像素的功能,所有宣称跨平台的GUI库都应该加上这个功能,而且是所有控件都能通过百分比定位。这是html教给我们的常识。很可惜,在网页设计者这里很普通的常识,在GUI库那里却变成了奢侈品。

我们鼓励使用百分比来指定窗口大小和位置。如下代码,创建一个窗口,该窗口离屏幕左上角分别占屏幕长和宽的10% 20%,而该窗口的大小也是屏幕长和宽的80%、90%。

1 WINDOW name="first" click="firstclick" title="测试" top=10% left=20% width=80% height=90% image="D:\test 1.bmp"

三、C++实现。

gui.ex中,我们用一个简单的函数读取并解析上述文本:

read_gui("test.gui");

该函数的目的则是读取test文本,然后得到一颗树形结构 -- 这个过程和浏览器解析html是类似的。然后,遍历该结构,先父后子、先兄后弟,创建并显示窗口。笔者,使用Windows API快速做了个原型。如果希望,能跨平台,可那使用GTK更好 --- 注意,不要用QT。

除了该函数,我们还要实现test.gui中使用的宿主语言函数,也就是上文中的cpp_fun1.我们的解析程序解析test.gui要调用cpp_fun1,会把该函数的调用结果赋值给变量a -- 注意,变量a是test.gui的一个变量、并非c++程序中的变量。在实现中,我们可以使用map来存放变量名和值。

有了以上三点,一个单击的GUI设计方法就完成了。剩下的工作,则是实现各种控件。

四、基本控件的实现。

最简单、基础,必备的可能是WINDOW和TEXT,这很容易。WINDOW用于创建一个标准的Windows窗口,TEXT用于写文本。

比较重要的是容器控件,在OO库里,通常是叫PANEL,用于放置各种控件,在html则是

的好处在于可以嵌套放置,你可以在一个div里放一个div,多次嵌套。PANEL也应该如此。

一些OO GUI库的PANEL控件,用一种丑陋、莫名其妙的”布局对象“来控制其中的控件的布局,不提了。良好的设计大概是这样的:

1 WINDOW name="s"

2 PANEL layout="vertical"/"horizon“/”none" w=3 h=4

3 TEXT name="t1" caption="My..."

layout可以取值vertical或者horizon,其意义是,本PANEL的子控件,按照垂直、或者水平方式布局。如果你指定布局方式为None,则子控件按照top width摆放控件。

w和h的意义是,把PANEL平均分成3*4的矩形格子,控件依次放入其中。可以按行放置子控件,也可以按列放置子控件。

最后也是“叶子”控件 --- 他们必须放置于容器空间之中 Window或者PANEL。你不能在叶子控件里添加控件。通常,一个按钮、单行文本框、单选、多选、图像控件.... 是一个叶子控件。

不同OO库添加叶子控件的方法不一样,有的顶层窗口上不能直接放置叶子控件,必须添加一个PANEL,而另一些可以直接放置。我想,各自都有理由,笔者不想做约束,实现者考虑自己的需求,灵活掌握。

DELPHI VCL有自己的菜单控件TMENU,而在我们的GUI系统中,无需MENU控件,我们简单使用PANEL和TEXT就能拼出一个菜单:

1 WINDOW name="s"

2 PANEL layout="horizon“ w=1 h=2

3 PANEL name="menu" layout="horizon“ w=5 h=1

4 TEXT name="file" caption="文件" click="subshow"

4 TEXT name="edit" caption="编辑"

4 TEXT name="view" caption="查看"

4 TEXT name="tools" caption="工具"

4 TEXT name="help" caption="帮助"

3 PANEL name="submenu" layout=“vertical” w=1 h=3 show=no

4 TEXT name="new" caption="新建"

4 TEXT name="save" caption="保存"

4 TEXT name="open" caption=“打开"

3 PANEL name="content" layout="horizon“ w=1 h=1

@subshow

submenu.show

以上,名为menu的PANEL就是一个菜单,我们的菜单可以以各种文本的颜色显示,因为你已经实现了TEXT的彩色显示。

submenu是文件菜单的子菜单,show=no意为默认不现实,当你调用@submennu.show时,系统才绘制该子菜单。我们在名为file的text单击函数中,调用了该函数。

对于数据库记录的显示,我们实用上面的PANEL和TEXT控件即可:

1 WINDOW name="s"

2 PANEL name="db" layout="vertical"/"horizon“/”none" w=3 h=4

3 TEXT name="t1" caption="My..."

3 TEXT name="t2" caption="My..."

3 TEXT name="t3" caption="My..."

3 TEXT name="t4" caption="My..."

以上的PANEL中,存放3行4列文本,每行文本显示数据库的一条记录。

如果你有超过3条记录,你只需改变PANEL的w和h值,然后添加节点:

;变量后的"|"表示该变量是一个数组变量。

a|=“0000”,1,2,3

@gui

1 WINDOW name="s"

2 PANEL name="db" layout="vertical"/"horizon“/”none" w=3 h=4

; a|0引用数组的某一元素,等价于多数程序中的a[0],使用单符号操作符,解析更加容易。

3 TEXT name="t1" caption=a|0

3 TEXT name="t2" caption="My..."

3 TEXT name="t3" caption="My..."

@init

;调用C++/Python等实现语言函数,获得数据库记录,存在数组变量中.

a|=cpp_fun() $db.w=10 $db.w=10 $t1.caption=a|0 $t2.caption=a|1 $t3.caption=a|0

也许,我们该为这种GUI描述语言,添加for语句。

控件。这里的难点在于,vedio控件里的数据不是字符串,而是二进制数据。

我们的GUI描述文件怎么获得C++程序的二进制数据呢?

五、分布式GUI

我们可以基于以上框架,实现一个类似html中的控件/标签。

1 WINDOW name="first" click="firstclick" title="测试" top=100 left=100 width=100 height=100 image="D:\test 1.bmp"

2 DIV

3 A href="GUI://gnu.org/test.gui" caption="GNU官网"

4 TEXT name="t1" caption="My..."

当用户点击:

3 A href="GUI://gnu.org/test.gui" caption="GNU官网"

其实要创建并显示远程机器上的GUI程序,其文本描述和其中将要调用的C++函数都在远程机器上。

这就过程就好比你在网页中点击一个链接,会跳到一个新的页面。同样,你可以照搬html的设计打开一个新的窗口,旧窗口不用关闭。

在gnu.org上会运行一个GUI服务器、并存在一个test.gui文件。GUI服务器类似于http服务器,用于接受客户端请求,返回test.gui文本以及该文本中书写的各种宿主语言的函数调用结果。

假设GUI://gnu.org/test.gui的内容如下:

@gui

1 WINDOW name="test"

@init

$test.show

$.title=My_CPP_fun()

运行在gnu.org上的GUI服务器应该实现了My_CPP_fun函数,并且能够将其调用结果返回给客户端。

一个简单的GUI协议如下:

GET GUI://gnu.org/test.gui

这个类似http的GET请求,用于返回文本文件内容。

以下用于调用远程函数:

GET GUI://gnu.org/ My_CPP_fun 12 "test.abc" 223.4

以上调用远程服务器的My_CPP_fun函数,参数为12 "test.abc" 223.4

这样,一来,我们的GUI框架,就有了网络分布式能力。我们编写的GUI不但可以本地执行,而且可以把URL地址告诉别人,别人就能简单使用A标签使用你的GUI程序。 这个似乎很像Windows的远程协助,你可以让朋友控制你的电脑。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值