0.8.0.0 2026-09-24 calvin 依赖v0.12.8.0<=zlang<=0.12.*.0
* 随着zlang v0.12.8.0重新构建,所有控件的设置类函数的返回值从控件对象改为bool,配合zlang的连续调用函数操作符".."表达代码,创建临时对象减半,提升性能
一、gtk-zlang介绍
gtk-zlang是基于zlang编程语言的GTK封装包装库,打造跨平台的开源GUI技术栈,让开发者快速开发跨平台的桌面应用软件。
二、底层优势
-
zlang编程语言是一门原创自研、支持中文编程、融合和创新语法设计并保持简洁高效、开箱即用、跨平台+高性能的编程语言; -
GTK是一个免费、开源、跨平台的图形用户界面(GUI)开发工具包,它提供了一套丰富的控件(如按钮、对话框、菜单、滑块等)用于创建GUI图形界面应用程序,它支持Linux、Windows和MacOS;
三、核心亮点
1. 完整GTK控件绑定
-
深度封装
GTK标准控件,用zlang代码可直接调用窗口、对话框、文本框、表格、树视图、弹窗、等全套控件,支持CSS样式、事件回调函数等;
2. 原生跨平台桌面支持
-
依托
GTK跨平台特性,zlang源代码编写一次即可在Linux、Windows和MacOS上运行; -
平台画风适配性,
gtk-zlang在Linux、Windows和MacOS按平台本地风格显示标题栏等风格;
3. 轻量化GUI快速开发
-
使用简洁的类
C/C++/Java风格zlang代码快速构建GUI窗体和控件、以及事件回调处理逻辑,易上手,学习曲线平缓,一站式完成“静态界面、动态交互”桌面应用软件开发; -
还能使用XML描述性配置来声明式构建窗体和控件,工作量再缩减一半以上,也更方便理解和修改;
-
gtk-zlang包装了GTK,同时还做了一定的封装,使得开发更加方便、集成、高效;
4. 无缝联动zlang生态
-
可直接复用
zlang标准库文件读写、网络、数据库等处理能力,以及第三方封装好的zlang对象库;
5. 低资源占用
-
不同于
Electron的臃肿和占内存,zlang和gtk-zlang技术栈走的是另一条技术路线,解释语言zlang可以让开发者快速开发应用软件,应用逻辑细节处理都用C封装成zlang对象在zlang代码中直接调用,既可以快速开发原型和调试,又保证了运行性能、商业机密/算法专利和防篡改,同时还极大的缩小了安装包大小和内存占用;
6. 开源驱动、持续迭代
-
gtk-zlang是开源的,这意味着它是社区驱动而不是商业公司控制,学习者可以访问完整源代码,开源开发者可以提交补丁和贡献特性;使用gtk-zlang完全免费,不像QT需要支付高昂的授权费用;
四、功能和能力
gtk-zlang包装了丰富的窗体对象、布局对象、控件对象和工具对象,也封装了一些原生繁琐的常用操作,供zlang开发者调用,快速构建桌面应用软件。
以下是目前已经包装封装好的对象清单:
|
对象类型 |
对象清单 |
|---|---|
|
窗体对象 |
窗口、消息对话框、文件对话框、颜色对话框、字体对话框 |
|
布局对象 |
固定位置布局、盒子布局、对齐盒子布局、流式盒子布局、网格布局、滚动条布局、外框布局、标签页布局、分隔栏布局、弹出浮动窗体布局、折叠布局 |
-
| 控件对象 | 菜单栏类: 菜单栏、菜单、菜单项
工具栏类:工具栏、工具栏分隔条
普通控件类:标签控件、行编辑控件、块编辑控件、高级块编辑控件
按钮和选择框类:按钮控件、切换按钮控件、数值调整按钮控件、链接按钮控件、单选框控件、多选框控件
列表和表格类:列表框控件、下拉列表框控件、表格控件、树型表格控件
杂类:容量控件、进度条控件、切换开关控件、滑块控件、日历控件、图像控件、图片控件、视频播放器控件、分割线控件 |
| 工具对象 | 鼠标、键、方向、控件对齐、文本对齐、监视器、剪贴板、许可协议 |
五、安装说明
安装说明
六、代码示例
hello world
国际惯例,学习一门新语言或新技术首先写一个简单完整的示例案例感受一下,表示我上手了。
import stdtypes stdio gtk ;
function int main( array args )
{
guiwindow win ;
try
{
win.SetTitle( "hello gtk-zlang" );
win.SetSize( 400 , 300 );
win.SetChild( <object> guilabel.Create(win,"Hello world").SetExpand(true).SetAlign(guialign.CENTER) );
win.OpenWindow();
catch
{
guimessagedialog.ModalOpenDialog( win , guimessagedialog.ERROR_TYPE , zexception.GetExceptionName() , zexception.GetExceptionDesc() , guibutton.BUTTONS_OK ) ;
}
}
return 0;
}
也可以用XML来构造窗口,效果同上:
import stdtypes stdio gtk ;
function int main( array args )
{
guiwindow win ;
try
{
win.BuildFromXml( "
<window title='hello gtk-zlang' size='400*300'>
<label expand='true' align='CENTER'>Hello world</label>
</window>
" );
win.OpenWindow();
catch
{
guimessagedialog.ModalOpenDialog( win , guimessagedialog.ERROR_TYPE , zexception.GetExceptionName() , zexception.GetExceptionDesc() , guibutton.BUTTONS_OK ) ;
}
}
return 0;
}
复杂对话框
...
function int main( array args )
{
guiwindow win ;
try
{
win.BuildFromXml( "
<window window-type='DIALOG_WINDOW_TYPE' title='win-zcrypto' control-default-margin='5'>
<notebooklayout>
<vboxlayout notebooklayout-title='Digest'>
<hboxlayout>
<label>Artimetic :</label>
<combobox name='digest_artimetic_COMBOBOX'>
<comboboxitem>MD4</comboboxitem>
<comboboxitem>MD5</comboboxitem>
<comboboxitem selected>SHA1</comboboxitem>
<comboboxitem>SHA224</comboboxitem>
<comboboxitem>SHA256</comboboxitem>
<comboboxitem>SHA384</comboboxitem>
<comboboxitem>SHA512</comboboxitem>
</combobox>
</hboxlayout>
<hseparator />
<gridlayout>
<r>
<c r-span='4' align='START'><label vertical-align='START'>Input :</label></c>
<c><radiobutton group='digest_input_FORMAT' label='TEXT' checked='true' /></c>
<c r-span='3'><scrollwindowlayout><editarea name='digest_input_EDITAREA' size='700*100' horizontal-expand='true' /></scrollwindowlayout></c>
</r>
<r>
<c />
<c><radiobutton group='digest_input_FORMAT' label='HEXSTR' /></c>
<c />
</r>
<r>
<c />
<c><radiobutton group='digest_input_FORMAT' label='BASE64' /></c>
<c />
</r>
<r>
<c />
<c><radiobutton group='digest_input_FORMAT' label='FILE' toggle-event-callback='radiobtn_digest_input_FORMAT_FILE_OnToggled' /></c>
<c><edit name='digest_input_filename_EDIT' horizontal-expand='true' /></c>
</r>
</gridlayout>
<hseparator />
<gridlayout>
<r>
<c r-span='3' align='START'><label vertical-align='START'>Salt :</label></c>
<c><radiobutton group='digest_salt_FORMAT' label='TEXT' checked='true' /></c>
<c r-span='3'><scrollwindowlayout><editarea name='digest_salt_EDIT' size='700*100' horizontal-expand='true' /></scrollwindowlayout></c>
</r>
<r>
<c />
<c><radiobutton group='digest_salt_FORMAT' label='HEXSTR' /></c>
<c />
</r>
<r>
<c />
<c><radiobutton group='digest_salt_FORMAT' label='BASE64' /></c>
<c />
</r>
</gridlayout>
<hseparator />
<button label='>>> Hash <<<' click-event-callback='btn_digest_calc_OnClick' name='digest_hash_BUTTON' horizontal-expand='true' horizontal-align='FILL' />
<hseparator />
<gridlayout>
<r>
<c r-span='2' align='START'><label vertical-align='START'>Output :</label></c>
<c><radiobutton group='digest_output_FORMAT' label='HEXSTR' checked='true' /></c>
<c r-span='2'><editarea name='digest_output_EDITAREA' size='600*100' horizontal-expand='true' /></c>
</r>
<r>
<c />
<c><radiobutton group='digest_output_FORMAT' label='BASE64' /></c>
<c />
</r>
</gridlayout>
</vboxlayout>
...
</notebooklayout>
</window>
" );
win.OpenWindow();
catch
{
stdout.Println( zexception.GetExceptionDesc() );
}
}
return 0;
}
...
多文档窗体(含菜单栏、工具栏、多标签布局、状态栏)
...
function int CreateWindow()
{
try
{
main_win.BuildFromXml( "
<window window-type='MULTIPLE_DOCUMENT_WINDOW_TYPE' title='ZEUX' maximize close-window-event-callback='CloseWindow'>
<menubar>
<menubaritem label='File'>
<menu>
<menusection>
<menuitem label='New' activate-event-callback='File_New_menuitem_OnClicked' accelerator-key='<ctrl>n' />
<menuitem label='Open' activate-event-callback='File_Open_menuitem_OnClicked' accelerator-key='<ctrl>o' />
<menuitem label='Save' activate-event-callback='File_Save_menuitem_OnClicked' accelerator-key='<ctrl>s' />
<menuitem label='Close' activate-event-callback='File_Close_menuitem_OnClicked' />
</menusection>
</menu>
</menubaritem>
<menubaritem label='Edit'>
<menu>
<menusection>
<menuitem label='Undo' activate-event-callback='Edit_Undo_menuitem_OnClicked' accelerator-key='<ctrl>z' />
<menuitem label='Redo' activate-event-callback='Edit_Redo_menuitem_OnClicked' accelerator-key='<ctrl>y' />
</menusection>
<menusection>
<menuitem label='Cut' activate-event-callback='Edit_Cut_menuitem_OnClicked' accelerator-key='<ctrl>x' />
<menuitem label='Copy' activate-event-callback='Edit_Copy_menuitem_OnClicked' accelerator-key='<ctrl>c' />
<menuitem label='Paste' activate-event-callback='Edit_Paste_menuitem_OnClicked' accelerator-key='<ctrl>v' />
<menuitem label='Delete' activate-event-callback='Edit_Delete_menuitem_OnClicked' accelerator-key='<ctrl>DEL' />
</menusection>
</menu>
</menubaritem>
<menubaritem label='Search'>
<menu>
<menusection>
<menuitem label='Find ...' activate-event-callback='Search_Find_menuitem_OnClicked' accelerator-key='<ctrl>f' />
<menuitem label='Find prev' activate-event-callback='Search_FindPrev_menuitem_OnClicked' accelerator-key='<ctrl>F3' />
<menuitem label='Find next' activate-event-callback='Search_FindNext_menuitem_OnClicked' accelerator-key='F3' />
<menuitem label='Replace ...' activate-event-callback='Search_Replace_menuitem_OnClicked' accelerator-key='<ctrl>r' />
</menusection>
</menu>
<menu>
<menusection>
<menuitem label='Advance move cursor'>
<menu>
<menusection>
<menuitem label='Move left word' activate-event-callback='Search_Advance_MoveLeftWord_menuitem_OnClicked' accelerator-key='<ctrl>LEFT' />
<menuitem label='Move right word' activate-event-callback='Search_Advance_MoveRightWord_menuitem_OnClicked' accelerator-key='<ctrl>RIGHT' />
</menusection>
</menu>
</menuitem>
<menuitem label='Basic select text'>
<menu>
<menusection>
<menuitem label='Select all' activate-event-callback='Search_BasicSelectText_SelectAll_menuitem_OnClicked' accelerator-key='<ctrl>a' />
<menuitem label='Select word' activate-event-callback='Search_BasicSelectText_SelectWord_menuitem_OnClicked' accelerator-key='<ctrl>w' />
<menuitem label='Select line' activate-event-callback='Search_BasicSelectText_SelectLine_menuitem_OnClicked' accelerator-key='<ctrl>l' />
</menusection>
</menu>
</menuitem>
<menuitem label='Advance select text'>
<menu>
<menusection>
<menuitem label='Append select left word' activate-event-callback='Search_AdvanceSelectText_AppendSelectLeftWord_menuitem_OnClicked' accelerator-key='<ctrl><shift>LEFT' />
<menuitem label='Append select right word' activate-event-callback='Search_AdvanceSelectText_AppendSelectRightWord_menuitem_OnClicked' accelerator-key='<ctrl><shift>RIGHT' />
</menusection>
</menu>
</menuitem>
<menuitem label='Goto'>
<menu>
<menusection>
<menuitem label='Goto line' activate-event-callback='Search_Goto_GotoLine_menuitem_OnClicked' accelerator-key='<ctrl>g' />
<menuitem label='Goto file offset' activate-event-callback='Search_Goto_GotoFileOffset_menuitem_OnClicked' />
<menuitem label='Goto line offset' activate-event-callback='Search_Goto_GotoLineOffset_menuitem_OnClicked' />
</menusection>
</menu>
</menuitem>
</menusection>
</menu>
</menubaritem>
<menubaritem label='View'>
<menu>
<menusection>
<menuitem label='Font ...' activate-event-callback='View_Font_menuitem_OnClicked' />
</menusection>
</menu>
</menubaritem>
<menubaritem label='Environment'>
<menu>
<menusection>
<menuitem label='Window popup menu' checked='false' activate-event-callback='Environment_WindowPopupMenu_menuitem_OnClicked' name='menubar_Environment_Window-popup-menu_menuitem' />
</menusection>
</menu>
</menubaritem>
<menubaritem label='Help'>
<menu>
<menusection>
<menuitem label='About' activate-event-callback='Help_About_menuitem_OnClicked' />
</menusection>
</menu>
</menubaritem>
</menubar>
<toolbar>
<button icon='document-new' click-event-callback='File_New_toolbuttonitem_OnClicked' tooltip='New File' />
<button icon='document-open' click-event-callback='File_Open_toolbuttonitem_OnClicked' tooltip='Open File' />
<button icon='document-save' click-event-callback='File_Save_toolbuttonitem_OnClicked' tooltip='Save File' />
<toolseparatoritem />
<button icon='edit-undo' click-event-callback='Edit_Undo_toolbuttonitem_OnClicked' tooltip='Undo' />
<button icon='edit-redo' click-event-callback='Edit_Redo_toolbuttonitem_OnClicked' tooltip='Redo' />
<toolseparatoritem />
<button icon='edit-cut' click-event-callback='Edit_Cut_toolbuttonitem_OnClicked' tooltip='Cut' />
<button icon='edit-copy' click-event-callback='Edit_Copy_toolbuttonitem_OnClicked' tooltip='Copy' />
<button icon='edit-paste' click-event-callback='Edit_Paste_toolbuttonitem_OnClicked' tooltip='Paste' />
<button icon='edit-delete' click-event-callback='Edit_Delete_toolbuttonitem_OnClicked' tooltip='Delete' />
<toolseparatoritem />
<button icon='application-exit' click-event-callback='File_Exit_toolbuttonitem_OnClicked' tooltip='Exit' />
</toolbar>
<statusbar>
<label name='Processing_Info' horizontal-expand='true' horizontal-align='CENTER' />
<label name='RowNo_ColNo_FileOffset' horizontal-expand='true' horizontal-align='CENTER' />
<label name='Newline_Mode' horizontal-expand='true' horizontal-align='CENTER' />
<label name='File_Encoding' horizontal-expand='true' horizontal-align='CENTER' />
</statusbar>
</window>
" );
main_win.ShowWindow();
keys_val = regedit.QueryKeys( regedit.HKEY_CLASSES_ROOT , '''*\shell\ZEUX''' ) ;
if( keys_val )
main_win.GetControlByName("menubar_Environment_Window-popup-menu_menuitem").SetChecked( true );
else
main_win.GetControlByName("menubar_Environment_Window-popup-menu_menuitem").SetChecked( false );
catch
{
message = string.FormatString( "exception name : %s\nexception desc : %s\nsource filename : %s:%d\nobject name : %s\nfunction name : %s\n"
, zexception.GetExceptionName() , zexception.GetExceptionDesc()
, zexception.GetExceptionSourceFilename() , zexception.GetExceptionSourceRow()
, zexception.GetExceptionObjectName() , zexception.GetExceptionFunctionName() ) ;
guimessagedialog.ModalOpenDialog( main_win , guimessagedialog.ERROR_TYPE , "Main_Window" , message , guibutton.BUTTONS_OK ) ;
return zexception.SetException();
}
}
return 0;
}
...
七、官方提供的控件使用代码示例目录
-
源代码包路径:
\gtk\test\*.z。
八、官方开发的桌面应用软件
-
msgdialog——用
zlang语言开发的模拟Windows消息对话框,可在应用中引用使用; -
zcrypto —— 用
zlang语言+gtk-zlang开发的桌面安全算法工具(包含命令行模式和图形模式); -
ZEUX —— 用
zlang语言+gtk-zlang开发的桌面文本/源代码编辑器; -
ZephPlayer —— 用
zlang语言+gtk-zlang开发的桌面多媒体播放器;