.NET Core 跨平台 GUI 开发之 GTtkSharp 初级篇

GTK 来龙去脉

  1. Linux 上的图形界面可有可无,有需要的话是可以安装的,作为一个软件安装到系统。比如常见的桌面环境有 KDE 和 GNOME,它们不仅是个窗口管理器,还提供了桌面、菜单等功能,。桌面管理器顾名思义了,没有它的话就不能打开多个窗口不能最大最小化没有边框等,所以希望整个系统只跑一个桌面程序的情况就可以不用安装窗口管理器。windows 用户按 https://zhidao.baidu.com/question/1372025356510156779.html 这个操作可以体验一下,请先好保存当前工作再操作
  2. KDE 和 GNOME 分别基于 Qt 和 Gtk 实现。它们通过一种叫 X11 的协议来通信,不仅控制窗口最大最小化缩放和边框,还提供桌面、工具状态栏等
  3. X11 可用于几乎所有已有的现代操作系统,基于客户端——服务器模型。跟常规理解不一样,此处从应用程序视角看:本地主机 X 显示程序提供显示服务,远端应用使用了该显示服务,所谓它是客户端。就像远程控制桌面一样,本地提供显示,远程服务器作为客户端。当它们都在同一主机,看起来就是一个整体。比如苹果电脑,X 协议集成在系统内核,所以性能好很多
  4. 层次关系:linux 本身-->X 服务器<--通过 X 协议交谈-->窗口管理器-->X 应用程序。X 服务实现有 Xfree86、Xorg、Xnest 等,KDE 和 GNOME 属于 X 客户端。我们开发的桌面程序属于 X 客户端
  5. 为了方便开发人员,将 X 协议封装,于是有了 XLib。类似于 windows 上的 关于通信功能的 ws2_32.dll,提供了访问系统功能的 api,比如监听端口和从系统缓冲区读取端口接收的数据。很多常用功能为了方便使用,于是有了 C 函数库 GLib,类似于 C#里面的 System 空间的很多函数,包括字符串处理、list 数据结构等。接着是 Gdk,结合 GLib,将 XLib 函数库封装得更友好,比如 C#中将 ws2_32.dll 一些功能封装成 UdpClient。再往上就是 Gtk 了,依赖于 Gdk,提供基础的工具包和 widget,是上层 GUI 派生的基础。类似于 NewLife 的 X 组件里面的 ApiClient 这种网络库,基于 UdpClient 等封装。Gtk 获得了面向对象特性和可扩展性之后,就是 Gtk+,翻译成 CSharp 就是 GtkSharp。类似于 X 组件,提供了很多功能和工具,提供给各个应用系统做业务。层次关系:x 协议-->XLib,GLib-->Gdk-->Gtk+

界面布局

  • Gtk#有被称为容器对象的东西,用于指导窗口或其他容器内的布局和放置。此技术不同于使用 System.Windows.Forms 工具箱定位的常用方法。GTK#和 System.Windows.Forms 之间的主要区别在于:使用 GTK#的应用程序不使用绝对坐标或固定坐标来定位窗口小部件。使用 GTK 工具包的应用程序通过布局和包装容器对象为其接口创建正确的布局
  • 目前,最常用的就是水平和垂直包装盒,即 HBox 和 VBox

Box

  • 对齐控件的首选方法。优点:与屏幕尺寸无关、更容易国际化
  • 水平盒子(HBox)和垂直(VBox)盒子,对于 VBox,PackStart 将从顶部开始包装盒子,PackEnd 将从底部开始包装盒子。对于 HBox,PackStart 将从左到右打包盒子,PackEnd 将从右到左打包盒子。
  • 使用如下,child 参数是要打包到框中的对象。expand 参数控制框是否填充分配给它的区域(true),否则缩小框使其恰好合适框中对象大小。fill 参数控制对象是否填满框,仅当 expand 为 true 时生效。比如日志文本框,缩放的时候,文本框跟随窗口大小变化
box1.PackStart(Widget child, bool expand, bool fill, int padding);
  • 创建函数如下,homogeneous 表示框中的每个对象是否具有相同的大小(即,HBox 中的宽度相同或 vBox 中的高度相同),等效于 Pack 方法中 expand 为 true。spacing 表示框中对象间距,而 padding 会在对象两侧都添加
HBox hbox1 = new HBox(bool homogeneous, int  spacing);

Table

  • 除了使用 HBox 和 VBox 进行打包外,还可以使用 Table 对象进行打包。这个有点像 html 的 table,适合方方正正大小差不多的空间集合,比如计算器。
  • Table 的声明如下,rows、columns 分别指要创建的行和列。homogeneous 为 true 表示所有的表框大小设置为大小最大那个控件,为 false 则各行和列的大小根据各行列中大小最大那个控件决定
Table table1 = new Table(int rows, int columns, bool homogeneous);

// 假如创建2*2的表格
0 1 2
0+----------+----------+
| | |
1+----------+----------+
| | |
2+----------+----------+
  • 添加控件方式如下,leftAttach,rightAttach,topAttach,bottomAttachach 分别代表表中控件的左右上下边所在位置。例如,希望某个控件占据第一行两个格子,那么 leftAttach=0,rightAttach=2,topAttach=0,bottomAttachach=1。
  • xOptions 和 yOptions 指定打包选项
    • Gtk.AttachOptions.Fill:如果表框大于窗口小部件,并且指定了 Fill,则窗口小部件将展开以使用所有可用空间
    • Gtk.AttachOptions.Shrink:如果为 Table 中控件分配了较少的空间,然后又请求了空间(通常是由用户调整窗口大小),则通常将窗口小部件推离窗口底部并消失。如果指定了 Shrink ,则小部件将随表格收缩
    • Gtk.AttachOptions.Expand:这将导致 Table 扩展以占用窗口中的所有剩余空间
  • xPadding 和 yPadding 分别控制 Table 内控件在原位置基础上表框到控件的左右或者上下距离
table1.Attach (        Widget            child,
int leftAttach,
int rightAttach,
int topAttach,
int bottomAttach,
Gtk.AttachOptions xOptions,
Gtk.AttachOptions yOptions,
int xPadding,
int yPadding );

其它布局

  • 固定容器 fixed,容器内控件相对于窗口左上角位置,并且位置可动态修改
Fixed fixed1 = new Fixed();
fixed1.Put(widget, x, y);
fixed1.Move(widget, x, y);
  • 布局容器 layout,实现了无限的滚动区域,适合动态加载很多空间的情况,比如相册
Layout layout1 = new Layout(hadjustment, vadjustment);
layout1.Put(widget, x, y);
layout1.Move(widget, x, y);
  • 框架 frame,类似于 winform 的 groupbox,框上有个标签。LabelXalign 和 LabelYalign 属性分别表示 Label 在框上的水平和垂直位置,范围是 0-1。LabelXalign 默认 0,标签位于左边,LabelYalign 未使用。ShadowType 属性决定外框样式 Gtk.Shadow.EtchedIn 为默认值
Frame frame1 = new Frame("Label");
frame1.LabelXalign = 0.3;
frame1.ShadowType = ShadowType.Out;

响应式编程

  • 本节介绍多线程 GTK#编程以及如何保持 GTK#应用程序的响应速度
  • 和 winform 一样,更新 UI 应该由创建 UI 的线程来执行,否则可能会崩溃。可用 Gtk.Application.Invoke 来请求 GUI 线程完成更新
using Gtk;

class Demo {
static Label label; static void Main ()
{
Application.Init ();
Window w = new Window ("Cray on a Window");
label = new Label ("Busy computing"); Thread thr = new Thread (new ThreadStart (ThreadRoutine));
thr.Start ();
Application.Run ();
} static void ThreadRoutine ()
{
LargeComputation ();
Gtk.Application.Invoke (delegate {
label.Text = "Done";
});
} static void LargeComputation ()
{
// lots of processing here
}
}
  • 定时器 GLib.Timeout,类似 System.Windows.Forms.Timer。不同之处在于,GLib.Timeout 总是在拥有 Gtk 主循环的线程上被调用
 void StartClock ()
{
// 每秒调用一次update_status GLib.Timeout.Add (1000, new GLib.TimeoutHandler (update_status));
} bool update_status ()
{
time_label.Text = DateTime.Now.ToString (); // 返回true则在下一次超时时间到达后再次调用update_status
// 返回false则终止定时器 return true;
}

最后

  • 本文介绍了 Gtk 在整个 Linux 桌面开发所处位置、列举了几个布局容器、以及响应式编程。掌握以上知识,可大大提高编程效率,全部操作一遍即可理解并掌握

.NET Core 跨平台 GUI 开发之 GTtkSharp 初级篇的更多相关文章

  1. 新浪微博客户端开发之OAuth认证篇

    新浪微博客户端开发之OAuth认证篇 2013年7月29日新浪微博客户端开发 OAuth2.0授权机制我在这里就不浪费口舌了,有很多大牛都发表过相关的文章解释OAuth2.0认证的流程,我就随便找了一 ...

  2. 前端开发之javascript BOM篇

    主要内容: 1.BOM输出 2.BOM的对象 3.client的相关属性 4.offset的相关属性 5.scroll的相关属性 前情提要: 何谓BOM? 所谓 BOM 指的就是浏览器对象模型 Bro ...

  3. 前端开发之JavaScript基础篇三

    主要内容: 1.创建对象的几种方式 2.JavaScript内置对象 3.JavaScript错误--Throw.Try 和 Catch 4.JavaScript 表单验证 一.创建对象的几种方式 1 ...

  4. [转载]敏捷开发之Scrum扫盲篇

    现在敏捷开发是越来越火了,人人都在谈敏捷,人人都在学习Scrum和XP...      为了不落后他人,于是我也开始学习Scrum,今天主要是对我最近阅读的相关资料,根据自己的理解,用自己的话来讲述S ...

  5. 敏捷开发之Scrum扫盲篇

    现在敏捷开发是越来越火了,人人都在谈敏捷,人人都在学习Scrum和XP... 为了不落后他人,于是我也开始学习Scrum,今天主要是对我最近阅读的相关资料,根据自己的理解,用自己的话来讲述Scrum中 ...

  6. 敏捷开发之Scrum扫盲篇(转)

    转:http://www.cnblogs.com/taven/archive/2010/10/17/1853386.html 现在敏捷开发是越来越火了,人人都在谈敏捷,人人都在学习Scrum和XP.. ...

  7. koa+mysql+vue+socket.io全栈开发之web api篇

    目标是建立一个 web QQ的项目,使用的技术栈如下: 后端是基于koa2 的 web api 服务层,提供curd操作的http接口,登录验证使用的是 json web token,跨域方案使用的是 ...

  8. 转:敏捷开发之Scrum扫盲篇

    现在敏捷开发是越来越火了,人人都在谈敏捷,人人都在学习Scrum和XP... 为了不落后他人,于是我也开始学习Scrum,今天主要是对我最近阅读的相关资料,根据自己的理解,用自己的话来讲述Scrum中 ...

  9. 敏捷开发之Scrum扫盲篇(转)

    现在敏捷开发是越来越火了,人人都在谈敏捷,人人都在学习Scrum和XP... 为了不落后于他人,我也开始学习Scrum.今天主要是对我最近阅读的相关资料,根据自己的理解,用自己的语言来描述Scrum中 ...

随机推荐

  1. MySQL的基础与安装

    一.数据库概述 1.什么是数据库? 数据库(Database)是按照数据结构来组织.存储和管理数据的建立在计算机存储设备上的仓库. 2.数据库的主要特点: ⑴ 实现数据共享        数据共享包含 ...

  2. Python 用科学的方法判断函数/方法

    from types import MethodType,FunctionType def check(arg): """ 检查arg是方法还是函数? :param ar ...

  3. MyBatis的几个重要概念和工作流程

    MyBatis 几个重要的概念 Mapper 配置: Mapper 配置可以使用基于 XML 的 Mapper 配置文件来实现,也可以使用基于 Java 注解的 MyBatis 注解来实现,甚至可以直 ...

  4. linux sudo root 权限绕过漏洞(CVE-2019-14287)

    0x01 逛圈子社区论坛 看到了 linux sudo root 权限绕过漏洞(CVE-2019-14287) 跟着复现下 综合来说 这个漏洞作用不大  需要以下几个前提条件 1.知道当前普通用户的密 ...

  5. C Primer Plus (一)

    摘要:重读C Primer Plus ,查漏补缺 重读C Primer Plus,记录遗漏的.未掌握的.不清楚的知识点. 一.概览 1.链接器的作用是将这3个目标元素(目标代码.系统的标准启动代码和库 ...

  6. go语言版本测试, 一段错误代码引发的血案

    起因: 最近在学习手写docker,看到了一段会编译错误的代码. 过程: 最近在学习docker,看到一段示例代码,每次编译时会报错. 因此, 无法继续下去, 只好在网上搜索解决方案, 用了很多时间, ...

  7. 使用Typescript重构axios(二十六)——添加HTTP授权auth属性

    0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...

  8. 《JS高程》-教你如何写出可维护的代码

    1.前言   在平时工作开发中,大部分开发人员都花费大量的时间在维护其他人员的代码.很难从头开始开发新代码,很多情况下都是以他人成果为基础的,或者新增修改需求,自己写的代码也会被其他开发人员调用,所以 ...

  9. jQuery源码分析--为什么在参数列表中传入undefined

    (function(window, undefined){ //jQuery code; })(window); 为什么要传入undefined? 1.没有传入undefined: <!DOCT ...

  10. 瞎折腾实录:构建 Armel 版本的 .NET Core 教程和资料资源

    目录 首先我要说明,我失败了~ 我把我的进度和经验放出来,希望能够帮助别人完成编译工作~ 背景:最近接手一个华为某型号的嵌入式设备,需要在上面搭建 .NET Core 环境. 设备是 Armel 架构 ...