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的遠程協助,你可以讓朋友控制你的電腦。
總結
以上是生活随笔為你收集整理的html服务器框架,一种类似http/html的分布式GUI程序设计框架的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: centos 7 防火墙和端口配置
- 下一篇: 注册