首页 > 开源 > gtk-zlang v0.8.0.0发布,基于zlang编程语言的GTK封装的跨平台图形窗口应用开发库

gtk-zlang v0.8.0.0发布,基于zlang编程语言的GTK封装的跨平台图形窗口应用开发库

OSChina资讯 2026-09-28 10:27 5 阅读 查看原文

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;
}
test_hello

也可以用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;
}
...

 

guiwindow_dialog_window_type

多文档窗体(含菜单栏、工具栏、多标签布局、状态栏)

	...
	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;
	}
	...

 

guiwindow_multiple_document_window_type

七、官方提供的控件使用代码示例目录

  • ​ 源代码包路径: \gtk\test\*.z。

八、官方开发的桌面应用软件

  • msgdialog——用zlang语言开发的模拟Windows消息对话框,可在应用中引用使用;

  • zcrypto —— 用zlang语言+gtk-zlang开发的桌面安全算法工具(包含命令行模式和图形模式);

  • ZEUX —— 用zlang语言+gtk-zlang开发的桌面文本/源代码编辑器;

  • ZephPlayer —— 用zlang语言+gtk-zlang开发的桌面多媒体播放器;

九、快速开始

1. 源码仓库地址:https://gitee.com/calvinwilliams/gtk-zlang (仓库内含整套源代码、测试用例与详细介绍)