Browse DevX
Sign up for e-mail newsletters from DevX


Building Robust UIs in Mono with Gtk# : Page 2

Learn to use the native Gtk# GUI toolkit to build Mono-based desktop applications today.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

Building a Main Window
At absolute minimum, building a Gtk# user interface requires working with the Window and Application class types. Not too surprisingly, the Window class represents the main window of an application. The Window type has the ability to host menu systems, status bars, toolbars, drawing surfaces, and other internal widgets.

The Application type represents a running instance of a Gtk# application. This type encapsulates various low-level details such as dispatching messages to their intended targets, initializing and tearing down the Gtk# libraries, and so forth. To get the ball rolling, consider the following C# code file, which you can find in the downloadable code in the file BasicWindow.cs:

using System; using Gtk; namespace BasicWindow { static class Program { static void Main() { // Initialize the application. Application.Init(); // Create the main Window, handle DeleteEvent event // and show it! Window wnd = new Window("My Simple Window"); wnd.SetDefaultSize(300, 200); wnd.DeleteEvent += new DeleteEventHandler( MainWindow_Delete); wnd.ShowAll(); // Run the program. Application.Run(); } // When user clicks the close button, shut down // the application. static void MainWindow_Delete(object sender, DeleteEventArgs args) { Application.Quit(); args.RetVal = true; } } }

The first point of interest in the preceding code is that it uses the Gtk namespace, which not only defines the Window and Application type, but also the DeleteEventHandler delegate (used to handle the window's DeleteEvent event).

The Main() method begins by initializing the Gtk+ infrastructure via a call to the static Application.Init() method. After instantiating a Window object and establishing a default size, the code handles the DeleteEvent event using standard C# event syntax (again note that the DeleteEvent event works in conjunction with the DeleteEventHandler delegate).

This DeleteEvent event fires when the user clicks on the close button of the displayed window, at which point you destroy the application via a call to the Application.Quit() method, and inform the Gtk# system that this event is fully handled by assigning the RetVal property of the incoming DeleteEventArgs type to true (this step is technically optional, but is considered good form).

Finally, the code tells the Window object to display itself (and any contained widgets) and run the application.

At this point you can compile the application with the Mono C# compiler by entering the following command set at the command line (I'll provide more information on the -pkg option in the next section):

gmcs *.cs -pkg:gtk-sharp

Figure 2. Your First Gtk# Application: Although not exciting, this application is perhaps the simplest possible example of a Gtk#-based Mono application running under Microsoft Windows.
Assuming you don't have any compilation errors, you can now run your Gtk# application under the Mono runtime using the following command:

mono BasicWindow.exe

Figure 2 shows the Gtk# application hosted by the Microsoft Windows operating system.

Author's Note: You can compile and execute all the remaining examples in this article using the same command line instructions shown in this section; therefore, I won't repeat them again. Just be sure to change the name of the .exe file appropriately when running the mono utility.

The Role of the—pkg Option
Unlike the Microsoft C# compiler, the Mono C# compilers (mcs/gmcs) support the notion of importing "packages." Packages are similar to C# response files, in that they allow you to define a set of assemblies to include with the current compilation, but packages go one step further by also allowing you to define detailed compilation flags and version requirements for external dependencies.

Figure 3. Package Contents: If you investigate the gtk-sharp package by opening it with a text editor, you'll see that it references the Gtk# assemblies.
The details of the gtk-sharp package shown in the command line earlier are defined within a file named gtk-sharp-2.0.pc, located under the \lib\pkconfig subdirectory of your Mono installation (C:\Program Files\Mono-\lib\pkgconfig on a Win32 machine). If you were to open this file using a text editor, you would find that it specifies the Gtk# assemblies as input (see Figure 3).

Building a Better Window
With a basic example application running, it's time to improve the code. Currently, the logic used to define the Window type is embedded directly within the type defining Main(), which does not lend itself to code reuse. Consider the BasicWindowRefactored.cs code file below, which now subclasses the Window type to enforce encapsulation services.

using System; using Gtk; namespace BasicWindowRefactored { // The Program class initializes the Gtk# app. static class Program { static void Main() { Application.Init(); // Create the Window derived type. MainWindow wnd = new MainWindow("My Simple Window"); wnd.ShowAll(); Application.Run(); } } // The MainWindow class represents our custom Window. class MainWindow : Window { public MainWindow(string title) : base(title) { this.SetDefaultSize(300, 200); this.DeleteEvent += new DeleteEventHandler( MainWindow_Delete); } void MainWindow_Delete(object sender, DeleteEventArgs args) { Application.Quit(); args.RetVal = true; } } }

Despite the changed code, if you compile and run this version of the code, the output is identical. The benefit is that this version isolates the application logic and the main window logic into two independent classes.

Author's Note: I'll use the types defined in the BasicWindowRefactored.cs file as the basis for the remaining examples in this article. I won't modify the Program class further, and therefore won't show it beyond this point. However, the MainWindow type will undergo a number of modifications as the article examines new concepts.

Thanks for your registration, follow us on our social networks to keep up-to-date