.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中 ...
随机推荐
- 针对工程实践项目的用例建模Use Case Modeling
一.什么是用例建模(Use Case Modeling) 1.用例(Use Case) (1)概念:用例是软件工程或系统工程中对系统如何反应外界请求的描述,是一种通过用户的使用场景来获取需求的技术. ...
- Spring的几种初始化和销毁方法
一 指定初始化和销毁方法 通过@Bean指定init-method和destroy-method: @Bean(initMethod="init",destroyMethod=&q ...
- CentOS生产环境无网络安装percona-xtrabackup2.4【RPM安装教程】
Percona XtraBackup 8.0不支持对在MySQL 8.0之前的版本,Percona Server for MySQL或 Percona XtraDB Cluster中创建的数据库进行备 ...
- Asp.Net Core 单元测试正确姿势
背景 ASP.NET Core 支持依赖关系注入 (DI) 软件设计模式,并且默认注入了很多服务,具体可以参考 官方文档, 相信只要使用过依赖注入框架的同学,都会对此有不同深入的理解,在此无需赘言. ...
- windows 利用环境变量%PATH%中目录可写提权
使用PowerUp的时候有时候会有这种结果 [*] Checking %PATH% for potentially hijackable DLL locations... Permissions : ...
- 机器学习之Anaconda介绍
Anaconda Distribution 最受欢迎的Python / R数据科学发行版 轻松安装1,400多个Python / R数据科学包并管理您的包,依赖项和 环境 - 只需单击一下按钮即可.免 ...
- Abp vNext 自定义 Ef Core 仓储引发异常
问题 在使用自定义 Ef Core 仓储和 ABP vNext 注入的默认仓储时,通过两个 Repository 进行 Join 操作,提示 Cannot use multiple DbContext ...
- nginx目录安全设置
nginx目录安全设置<pre> location ~ /\. { deny all; }</pre>这样所有隐藏文件都不会以URL方式打开了
- 使用VSCode调试Egret项目中的ts代码
发布一次Android项目后,会在代码里,生成对应的.map文件.这样就可以在编辑器里或是Chrome里面对相应的TS文件进行断点调试了. 实际只要在tsconfig.json里面配置一下," ...
- C++中对C的扩展学习新增语法——引用
引用 引用的好处: 1.引用的好处 C++使用结构体,不需要再使用 typedef. 2.值传递是将实参进行拷贝,赋值给形参,如果对象比较大,每次拷贝效率比较低,并且函数内部无法修改外部变量的值,能力 ...