界面设计习练后,下面写一些程序设计心得。
程序结构
先看一下程序总体结构,先在program.cs中找到main入口,在命名空间下是MainClass类,Main函数进入后首先建立应用程序环境 Application.Init,然后对MainWindow进行实例化,显示窗体并运行程序 Application.Run()。
//Program.csusing System;
using Gtk;namespace csharp3
{class MainClass{public static void Main(string[] args){Application.Init();MainWindow win = new MainWindow();win.Show();Application.Run();}}
}
main -> application init -> mainwindow{builder} ->application run/quit
上述过程中,mainwindow如下,它通过gtk库产生一个窗体及窗体包含的其它widgets,然后连通widgets的信号 - 属性和事件。这其中用到一个 Build() 函数,在C调用中常命名为 builder的指针,在gnome-builder构建器中称之为 template ,将界面设计器的设计文件变成程序来实现。public partial class MainWindow, 指明这只是 partial,一部分内容,还有一部分由 Build() 产生。在linux中,Gtk界面库与用户程序之间一般都是这种方式。
//mainwindow.csusing System;
using Gtk;public partial class MainWindow : Gtk.Window
{public MainWindow() : base(Gtk.WindowType.Toplevel){Build();}protected void OnDeleteEvent(object sender, DeleteEventArgs a){Application.Quit();a.RetVal = true;}protected void OnButton5Clicked(object sender, EventArgs e){entry2.Text = "Hello!";}protected void OnButton6Clicked(object sender, EventArgs e){Application.Quit();}
}
也可以不用设计器,自己写build的内容。Mono的设计器支持C#,但不支持VB.NET,而Mono本身是支持VB.NET的。因此,如果在Mono上用VB.NET开发的话,需要自己写build后的界面语句。大至是下面的样子。首先产生个Window,然后向window中加入控件并显示控件,如果需要产生事件则将事件与回调函数过程的地址连起来(Addressof),最后show的是window。除了主窗体给个初始尺寸,控件本身一般都是由sizer,比如vbox等去控制的。习惯于linux界面这种方式后,可以不用界面设计器,脑子想它是什么样就add上什么widget,个别属性调整一下,fill和expand用好,加控件时pack靠start或靠end,最后试运行调整一下就可以了。
Dim window As Gtk.Window = New Gtk.Window("Buttons")AddHandler window.DeleteEvent, AddressOf OnDeleteEventwindow.BorderWidth = 0window.Resize(800, 600)window.WindowPosition = WindowPosition.CenterDim box1 As VBox = New VBox(False, 10)window.Add(box1)box1.Show()box1.Homogeneous = FalseDim box2 As VBox = New VBox(False, 10)box2.BorderWidth = 10box1.PackStart(box2, True, True, 0)box2.Show()button1 = New Button("Button 1")box2.PackStart(button1, True, True, 0)button1.Show()AddHandler button1.Clicked, AddressOf OnButton1ClickedDim button2 As Button = New Button("Button 2")'button2.Active = truebox2.PackStart(button2, True, True, 0)button2.Show()Dim separator As HSeparator = New HSeparator()box1.PackStart(separator, False, True, 0)separator.Show()Dim box3 As VBox = New VBox(False, 10)box3.BorderWidth = 10box1.PackStart(box3, False, True, 0)Dim button3 As Button = New Button("Close")AddHandler button3.Clicked, AddressOf OnExitButtonEventDim entry1 As Entry = new Entry("Please")box3.PackStart(entry1, True, True, 0)entry1.Show()box3.PackStart(button3, True, True, 0)button3.CanDefault = Truebutton3.GrabDefault()button3.Show()
Mono C#编程中,可以不关注Build后的内容,它们在另外一个.cs中。如果抽象一些理解的话,builder是图中的样子,像个黑盒子接线箱,编程时连通相应的信号即可。
C#有设计器还是比VB.NET方便一些,不过在C#中也可以使用VB.NET功能,在引用中加上:
using VB = Microsoft.VisualBasic
引用后即产生新的命名空间VB,比如在C#中使用VB.NET的文件读写,可以写成:
VB.FileSystem.FileOpen(1, "VBNETTEST.TXT", VB.OpenMode.Output, VB.OpenAccess.Write, VB.OpenShare.Shared);VB.FileSystem.WriteLine(1, "Hello World! - 1");VB.FileSystem.WriteLine(1, "Hello World! - 2");VB.FileSystem.WriteLine(1, "Hello World! - 3");VB.FileSystem.WriteLine(1, "Hello World! - 4");VB.FileSystem.WriteLine(1, "Hello World! - 5");VB.FileSystem.FileClose(1);
微软的Microsoft.VisualBasic命名空间中VB.NET功能繁多,喜欢VB.NET编程的话可以把它引用到进程序中,Mono的C#设计器也就间接地支持VB.NET语言开发了。
用户程序
默认的MainWindow.cs产生MainWindow:Gtk.Window类,里面有个MainWindow()方法,方法中首先是Build(),自己的程序一般使用这个类,加入一些类内变量,在类内加入一些方法等。需要的话也可另僻空间,用另类,用另类方法等。
//MainWindow.csusing System;
using Gtk;
using System.Threading.Tasks;
using VB = Microsoft.VisualBasic;
using Cairo;public partial class MainWindow : Gtk.Window
{//Store previous background color of drawingarea1private Gdk.Color StoreColor = new Gdk.Color(255, 255, 255);private int iArea1ObjX = 10;private int iArea1ObjY = 50;private uint timerID1, timerID2;private ImageSurface surfacepub;private Context ctxpub;private Context ctxArea1;private int drawingarea1Width;private int drawingarea1Height;public MainWindow() : base(Gtk.WindowType.Toplevel){Build();drawingarea1.AppPaintable = true;CreateContext();timerID1 = GLib.Timeout.Add(100, OnTimedEvent1);timerID2 = GLib.Timeout.Add(100, OnTimedEvent2);/*aTimer = new System.Timers.Timer(300);aTimer.Elapsed += OnTimedEvent;aTimer.AutoReset = true;aTimer.Enabled = true;*/}protected void OnDeleteEvent(object sender, DeleteEventArgs a){DestroyContext();Gtk.Application.Quit();a.RetVal = true;}protected void OnButton16Clicked(object sender, EventArgs e){DestroyContext();Gtk.Application.Quit();}protected void OnColorbutton1ColorSet(object sender, EventArgs e){var redcolor = colorbutton1.Color.Red;var greencolor = colorbutton1.Color.Green;var bluecolor = colorbutton1.Color.Blue;}
先写这么多,一些常用widgets使用方法在下篇心得中写。