【.NET Core 跨平台 GUI 开发】第一篇:编写你的第一个 Gtk# 应用
本文是【.NET Core 跨平臺(tái) GUI 開(kāi)發(fā)】系列博文的第一篇。該系列博文是一個(gè)關(guān)于 Gtk# 跨平臺(tái)應(yīng)用開(kāi)發(fā)的初級(jí)隨筆集合。該隨筆集合介紹了 GTK 和 Gtk# 的基本信息以及開(kāi)發(fā)方法,并展示了如何使用 .NET Core 技術(shù)棧開(kāi)發(fā)基于 Gtk# 的跨平臺(tái) GUI 程序。
博文假設(shè)你已經(jīng)對(duì) C# 有一定的了解且熟悉事件驅(qū)動(dòng),所使用的電腦中已經(jīng)安裝好了 Visual Studio 以及 .NET Core 開(kāi)發(fā)環(huán)境。如果你熟悉 WinForm 應(yīng)用程序的開(kāi)發(fā),那么你將輕松不少。
1、GTK 和 Gtk#
什么是 GTK ?
GTK(原名GTK+)最初是GIMP的專(zhuān)用開(kāi)發(fā)庫(kù)(GIMP Toolkit),后來(lái)發(fā)展為Unix-like系統(tǒng)下開(kāi)發(fā)圖形界面的應(yīng)用程序的主流開(kāi)發(fā)工具之一。GTK是自由軟件,并且是GNU計(jì)劃的一部分。自2019年2月6日起,GTK+改名為GTK。
維基百科:https://zh.wikipedia.org/wiki/GTK什么是 Gtk# ?
Gtk#是個(gè).NET的庫(kù),用來(lái)綁定GTK+ GUI庫(kù)。它讓你可以使用Mono或其他兼容CLR的語(yǔ)言來(lái)開(kāi)發(fā)GNOME應(yīng)用程序。
Gtk#像其他現(xiàn)在的視窗庫(kù)一樣,采用事件驅(qū)動(dòng),讓開(kāi)發(fā)者可以在視窗組件的事件被觸發(fā)時(shí),處理要做的事情。
以Gtk#創(chuàng)建的應(yīng)用程序可以運(yùn)行在許多平臺(tái)上,如Linux、Microsoft Windows與Mac OS X等。
維基百科:https://zh.wikipedia.org/wiki/Gtk%E2%99%AF簡(jiǎn)單來(lái)說(shuō) GTK 是一款在類(lèi) Unix 系統(tǒng)下進(jìn)行圖形界面開(kāi)發(fā)的工具。Gtk# 是一個(gè) .NET 的庫(kù),他對(duì) GTK 進(jìn)行了包裝,這樣我們就可以使用 C# 來(lái)調(diào)用 GTK 進(jìn)行圖形界面開(kāi)發(fā)。因?yàn)?GTK 非常流行且是自由軟件,所以 Gtk# 可以在許多平臺(tái)上運(yùn)行。
我們要使用的 Gtk# 來(lái)自 https://github.com/GtkSharp/GtkSharp ,是 Mono Gtk Sharp 的一個(gè)分支。該版本的 Gtk# 組件提供了對(duì) .NET Core 和 GTK3 的支持、發(fā)布了 NuGet 包并提供了在 Windows 下無(wú)需安裝的運(yùn)行環(huán)境。
2、在 Mac OS 系統(tǒng)中安裝 GTK
如果你使用 Mac OS 進(jìn)行開(kāi)發(fā),那么在開(kāi)始之前,你需要在本機(jī)安裝好 GTK 環(huán)境。安裝過(guò)程并不復(fù)雜,如果你在中國(guó)大陸,你可能需要一個(gè)強(qiáng)壯有力的網(wǎng)絡(luò),這將為你帶來(lái)流暢的安裝體驗(yàn)。具體的安裝過(guò)程參見(jiàn): Installing Gtk on Mac 。
3、第一個(gè) Gtk# 應(yīng)用
打開(kāi) Visual Studio 新建一個(gè) .NET Core 控制臺(tái)應(yīng)用并命名為 Gtk.HelloWorld 。在項(xiàng)目創(chuàng)建好后,通過(guò) NuGet 將 GtkSharp 引用到項(xiàng)目中。如果你對(duì) NuGet 并不熟悉,可以參考這篇文章:在 Visual Studio 中安裝和管理 NuGet 包?。
為 Hello World 應(yīng)用安裝 GtkSharp 包將以下代碼粘貼到 Programe.cs 文件中:
using System;using Gtk;namespace Gtk.HelloWorld{class Program
{
static void Main(string[] args)
{
Application.Init();
var win = new Window("Hello World!");
win.SetDefaultSize(300, 600);
//窗體關(guān)閉后退出應(yīng)用
win.DeleteEvent += (s, e) =>
{
Application.Quit();
};
win.WindowPosition = WindowPosition.Center;
win.Resizable = false;
var label = new Label("This is a label!");
win.Add(label);
win.ShowAll();
Application.Run();
Console.WriteLine("Hello World!");
}
}}
點(diǎn)擊菜單欄中的 ” 調(diào)試 ” -> ” 開(kāi)始調(diào)試 ” 或者直接按 “ F5 ”鍵運(yùn)行程序調(diào)試。在編譯完成并啟動(dòng)后,就可以看到一個(gè)控制臺(tái)的黑框緊接著在屏幕的中央出現(xiàn)了一個(gè) 300*600 的窗體,我們的 Hello World 就完成了。
運(yùn)行 Hello World如果你是第一次運(yùn)行 Gtk# 程序且本機(jī)并沒(méi)有安裝 Gtk 環(huán)境,那么編譯的時(shí)間會(huì)稍微長(zhǎng)一些。如果你恰巧網(wǎng)絡(luò)環(huán)境不是很好,訪問(wèn) GitHub 速度很慢,那么你可能會(huì)遇到 Visual Studio 提示下面這個(gè)錯(cuò)誤:
Gtk has not been detected, downloading and installing it, set SkipGtkInstall to True to skip theese steps.這是因?yàn)?Gtk# 的程序包在編譯時(shí)會(huì)嘗試檢測(cè)本地是否安裝有 GTK 環(huán)境,如果沒(méi)有安裝,那么他會(huì)自己去 GitHub 上下載一份回來(lái)并解壓,如果下載解壓失敗,就會(huì)提示上面的錯(cuò)誤。(詳情可參看:GtkSharp.targets)。
目前來(lái)說(shuō)(2019年11月19日),Gtk# 的默認(rèn)檢測(cè)地址是:
$(LOCALAPPDATA)\Gtk\3.24這個(gè)地址在我的電腦上的絕對(duì)路徑是:?C:\Users\Killer\AppData\Local\Gtk\3.24?。其中?Killer?是我電腦的登錄用戶(hù)名,你可能需要將其替換掉才能找到正確的位置。如果這個(gè)位置中不包含 Gtk 的運(yùn)行時(shí)文件,那么程序會(huì)嘗試去?https://github.com/GtkSharp/Dependencies/raw/master/gtk-3.24.zip?下載,并解壓到該位置。
除了改善網(wǎng)絡(luò)環(huán)境,我們還可以手動(dòng)將運(yùn)行時(shí)安裝到本地電腦。手動(dòng)安裝的步驟如下:
確保你找到了正確的 Gtk 運(yùn)行時(shí)路徑并建立好了文件夾(比如:C:\Users\Killer\AppData\Local\Gtk\3.24 )。
使用下載工具(比如:IDM、迅雷、QQ旋風(fēng)等)下載文件 https://github.com/GtkSharp/Dependencies/raw/master/gtk-3.24.zip 到本地。
將下載到的文件解壓縮,并將所有文件復(fù)制到 Gtk 運(yùn)行時(shí)文件夾。
操作完成后的 Gtk 運(yùn)行時(shí)文件夾類(lèi)似下圖:
現(xiàn)在,你的應(yīng)用程序應(yīng)該可以正常運(yùn)行起來(lái)了。
4、程序分析
Hello World 程序的代碼可以在 gtk-sharp-demo/Gtk.HelloWorld 中找到。
如果你開(kāi)發(fā)過(guò) WinForm 程序,你可能會(huì)注意到的第一件事是我們沒(méi)有為?Label?添加布局代碼。比如,我們沒(méi)有規(guī)定?label.Left = 100?或?label.Width = 200?,我們只是將 label 添加到窗體中:win.Add(label);。這是因?yàn)?Gtk.Window 是從 Bin 繼承的窗口小部件,或者是承載“Container”的單個(gè)窗口小部件。這可能有些難以理解,但是目前你可以?xún)H僅記住,Gtk.Window 只能直接包含一個(gè)部件。
另一個(gè)值得關(guān)注的部分是?Application.Init()?和?Application.Run()?。通常,當(dāng)應(yīng)用程序處理完其主線程上的所有代碼后,應(yīng)用程序?qū)⑼V?。因?yàn)?Gtk.Window 的?ShowAll()?方法不會(huì)阻止主線程,因此代碼將繼續(xù)運(yùn)行并關(guān)閉。?Application.Init()?命令告訴運(yùn)行時(shí)監(jiān)聽(tīng)所有啟動(dòng)的 Gtk.Window ,當(dāng)運(yùn)行?Application.Run()?命令時(shí),它將在這些窗口上啟動(dòng)主循環(huán)。這將使應(yīng)用程序保持運(yùn)行狀態(tài),直到我們調(diào)用?Application.Quit()?方法退出程序。
Gtk.Window 類(lèi)型的?SetDefaultSize?方法用來(lái)設(shè)置窗體的默認(rèn)大小。WindowPosition?屬性可以獲取或設(shè)置窗體出現(xiàn)的位置。Resizable?屬性可以決定是否允許用戶(hù)手動(dòng)調(diào)整窗體的大小,當(dāng)這個(gè)屬性設(shè)置為 flase 時(shí),窗體就不能通過(guò)鼠標(biāo)拖動(dòng)改變大小了,同時(shí)最大化按鈕也被禁用掉了。
在 WinForm 中,我們通過(guò)注冊(cè)?Closed?事件來(lái)在窗體關(guān)閉后做一些事情,在 Gtk# 中需要改為?DeleteEvent?事件。在主窗體被刪除時(shí)退出程序是一步很關(guān)鍵的操作,否則會(huì)出現(xiàn)所有窗體都關(guān)閉了但是應(yīng)用程序沒(méi)有退出的情況。
總結(jié)
以上是生活随笔為你收集整理的【.NET Core 跨平台 GUI 开发】第一篇:编写你的第一个 Gtk# 应用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【.NET Core 跨平台 GUI 开
- 下一篇: ASP.NET Core快速入门(第4章