.NET Core 跨平台 GUI 开发之 GTtkSharp 初级篇
.NET Core 跨平台 GUI 开发之 GTtkSharp 初级篇
- 本文作为初级篇,适合已经安装好.NET Core 环境以及 Gtk 环境,并具备了 C#开发基础知识,能跑一些简单的例子,希望更深入了解开发 GTK 程序的同学。本文主要内容包括 GTK 的深入介绍、界面布局、响应式编程等
- 参考 1:x11 gtk qt gnome kde 之间的区别和联系(最后有图) https://blog.csdn.net/lanmayi003/article/details/6584521
- 参考 2:x11 gtk qt gnome kde 之间的区别和联系(讲得很明白) https://blog.csdn.net/zhanglianpin/article/details/6441879
- 参考 3:GtkSharp 教程 https://www.mono-project.com/docs/gui/gtksharp/tutorials/
GTK 来龙去脉
- Linux 上的图形界面可有可无,有需要的话是可以安装的,作为一个软件安装到系统。比如常见的桌面环境有 KDE 和 GNOME,它们不仅是个窗口管理器,还提供了桌面、菜单等功能,。桌面管理器顾名思义了,没有它的话就不能打开多个窗口不能最大最小化没有边框等,所以希望整个系统只跑一个桌面程序的情况就可以不用安装窗口管理器。windows 用户按 https://zhidao.baidu.com/question/1372025356510156779.html 这个操作可以体验一下,请先好保存当前工作再操作
- KDE 和 GNOME 分别基于 Qt 和 Gtk 实现。它们通过一种叫 X11 的协议来通信,不仅控制窗口最大最小化缩放和边框,还提供桌面、工具状态栏等
- X11 可用于几乎所有已有的现代操作系统,基于客户端——服务器模型。跟常规理解不一样,此处从应用程序视角看:本地主机 X 显示程序提供显示服务,远端应用使用了该显示服务,所谓它是客户端。就像远程控制桌面一样,本地提供显示,远程服务器作为客户端。当它们都在同一主机,看起来就是一个整体。比如苹果电脑,X 协议集成在系统内核,所以性能好很多
- 层次关系:linux 本身-->X 服务器<--通过 X 协议交谈-->窗口管理器-->X 应用程序。X 服务实现有 Xfree86、Xorg、Xnest 等,KDE 和 GNOME 属于 X 客户端。我们开发的桌面程序属于 X 客户端
- 为了方便开发人员,将 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 初级篇的更多相关文章
- 新浪微博客户端开发之OAuth认证篇
新浪微博客户端开发之OAuth认证篇 2013年7月29日新浪微博客户端开发 OAuth2.0授权机制我在这里就不浪费口舌了,有很多大牛都发表过相关的文章解释OAuth2.0认证的流程,我就随便找了一 ...
- 前端开发之javascript BOM篇
主要内容: 1.BOM输出 2.BOM的对象 3.client的相关属性 4.offset的相关属性 5.scroll的相关属性 前情提要: 何谓BOM? 所谓 BOM 指的就是浏览器对象模型 Bro ...
- 前端开发之JavaScript基础篇三
主要内容: 1.创建对象的几种方式 2.JavaScript内置对象 3.JavaScript错误--Throw.Try 和 Catch 4.JavaScript 表单验证 一.创建对象的几种方式 1 ...
- [转载]敏捷开发之Scrum扫盲篇
现在敏捷开发是越来越火了,人人都在谈敏捷,人人都在学习Scrum和XP... 为了不落后他人,于是我也开始学习Scrum,今天主要是对我最近阅读的相关资料,根据自己的理解,用自己的话来讲述S ...
- 敏捷开发之Scrum扫盲篇
现在敏捷开发是越来越火了,人人都在谈敏捷,人人都在学习Scrum和XP... 为了不落后他人,于是我也开始学习Scrum,今天主要是对我最近阅读的相关资料,根据自己的理解,用自己的话来讲述Scrum中 ...
- 敏捷开发之Scrum扫盲篇(转)
转:http://www.cnblogs.com/taven/archive/2010/10/17/1853386.html 现在敏捷开发是越来越火了,人人都在谈敏捷,人人都在学习Scrum和XP.. ...
- koa+mysql+vue+socket.io全栈开发之web api篇
目标是建立一个 web QQ的项目,使用的技术栈如下: 后端是基于koa2 的 web api 服务层,提供curd操作的http接口,登录验证使用的是 json web token,跨域方案使用的是 ...
- 转:敏捷开发之Scrum扫盲篇
现在敏捷开发是越来越火了,人人都在谈敏捷,人人都在学习Scrum和XP... 为了不落后他人,于是我也开始学习Scrum,今天主要是对我最近阅读的相关资料,根据自己的理解,用自己的话来讲述Scrum中 ...
- 敏捷开发之Scrum扫盲篇(转)
现在敏捷开发是越来越火了,人人都在谈敏捷,人人都在学习Scrum和XP... 为了不落后于他人,我也开始学习Scrum.今天主要是对我最近阅读的相关资料,根据自己的理解,用自己的语言来描述Scrum中 ...
随机推荐
- Linux的目录介绍
Linux的目录介绍 Linux系统以目录来组织和管理系统中的所有文件.Linux系统通过目录将系统中所有的文件分级.分层组织在一起,形成了Linux文件系统的树型层次结构.以根目录 “/” 为起点, ...
- 第三十二章 System V信号量(三)
n哲学家进餐问题描述有五个哲学家,他们的生活方式是交替地进行思考和进餐,n哲学家们共用一张圆桌,分别坐在周围的五张椅子上,在圆桌上有五个碗和五支筷子,n平时哲学家进行思考,饥饿时便试图取其左.右最靠近 ...
- shell 队列实现线程并发控制
需求:并发检测1000台web服务器状态(或者并发为1000台web服务器分发文件等)如何用shell实现? 方案一:(这应该是大多数人都第一时间想到的方法吧) 思路:一个for循环1000次,顺序执 ...
- 《Effective Java》 读书笔记(一) 使用静态构造方法代替传统构造函数
对象的创建与销毁 ITEM1 使用静态工厂方法代替构造函数 传统的新建一个对象的方法是通过构造函数: Foo foo =new Foo(); 一个类也可以提供一个静态方法产生一个对象: Boolean ...
- 关于mimikatz lazagne免杀方法
其实现在的杀软还是玩的老一套,改改特征字符就能过了,最新的defender能用这个方法过 文章直接从笔记复制出来的,有需要的自己看情况用 git clone https://github.com/ge ...
- shell 字符串比较与脚本 too many arguments 报错
一.问题 最近在写 shell 脚本的时候,遇到了一些小问题,就是我在判断一个字符串是否为空的时候经常报下面的错,程序是正常执行了,但是有这个提示很蛋疼,下面就是看看是什么问题导致的? [: too ...
- CSPS模拟 42
T3数位$dp$还没改完啊 哭了 T1 对$DAG$里所有点求他能到达的点的数量 考试时算了$bitset$内存扛不住,yy了个线段树合并上去 没有A不是因为被卡了,而是数组又开小了.. 我以为不能卡 ...
- Vue+element UI实现表格数据导出Excel组件
介绍 这是一个可以将页面中的表格数据导出为Excel文件的功能组件,该组件一般与表格一起使用,将表格数据传给组件,然后通过点击组件按钮可将表格中的数据导出成Excel文件. 使用方法 由于封装该组件内 ...
- wordpress插件:multiple post thumbnails(可为文章添加多个特色图片)
我们经常会给wordpress的文章加上特色图片来实现日志缩略图的需求,但是很多时候一张图片并不能够完美而又全面的表达我们wordpress文章的内容,这时候您可能就会需要这样一个能让wordpres ...
- 浅谈OI中的底层优化!
众所周知,OI中其实就是算法竞赛,所以时间复杂度非常重要,一个是否优秀的算法或许就决定了人生,而在大多数情况下,我们想出的算法或许并不那么尽如人意,所以这时候就需要一中神奇的的东西,就是底层优化: 其 ...