Programming C, C++, Java, PHP, Ruby, Turing, VB
Computer Science Canada 
Programming C, C++, Java, PHP, Ruby, Turing, VB  

Username:   Password: 
 RegisterRegister   
 An Intro to Mono, GTK#, Glade and Such with Pictures
Index -> General Programming
View previous topic Printable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic
Author Message
wtd




PostPosted: Sat Aug 06, 2005 12:46 am   Post subject: An Intro to Mono, GTK#, Glade and Such with Pictures

Let's look at developing a very simple app with Mono and GTK#. We'll use the MonoDevelop IDE and the Glade GUI designer.

Here's the MonoDevelop IDE at first startup.

Posted Image, might have been reduced in size. Click Image to view fullscreen.

We want to choose "New Project/Solution" from the File menu.

Posted Image, might have been reduced in size. Click Image to view fullscreen.

We'll be using Glade, so we'll choose to create a Glade# project. Of course, all of this is using C#.

Call the project HelloWorld and let it define where it saves the project.

You'll automatically get a window.

Posted Image, might have been reduced in size. Click Image to view fullscreen.

You'll notice that my interface changes from screenshot to screenshot a bit. The various information panes can be turned on and off with the View menu. You can then grab the top edge of the panes and drag them around to rearrange your working environment.

We can now easily compile and run this very simple application. Either select "Compile" or "Compile All" from the Run menu, or click one of the "Build" buttons at the right-hand side of the toolbar. The Output pane should inform us that the program compiled successfully.

We then need only click the "Run" button next to the Build buttons on the toolbar.

Posted Image, might have been reduced in size. Click Image to view fullscreen.

We get a window where standard output can show up, and a window titled "Glade Window". When we close that window, the standard output window prompts us to press any key. Press any key and that window closes and we're back to the IDE.

So, we're going to write some code now, right?

Nope. First we're going to take a look at glade and modifying our GUI.

In the Solution pane, we'll navigate to the Resource Files category. Within this we'll see the "gui.glade" file. Double-click it to open it in Glade. With MonoDevelop minimized, here's what we see.

Posted Image, might have been reduced in size. Click Image to view fullscreen.

The "window1" widget is highlighted, so we see its properties in the Properties window.

Let's change its title to "Hello World!", then save the GUI, quit Glade, and go back to MonoDevelop.

Having done that, we can build and run the project again and there's our window again, but with the new title. We didn't write a single additional line of code. We haven't written any code yet, in fact.

Now, let's open "gui.glade" back up and check something out. Switch to the "Signals" tab in the Properties window.

Posted Image, might have been reduced in size. Click Image to view fullscreen.

Here you can see that there is one signal listed here. In this case it's the "delete_event". This is the event that occurs when the window is deleted, or closed. For instance, if you click the close button.

Now,we also have here a handler for that signal. The handler is called "OnWindowDeleteEvent".

We can then go into MonoDevelop and see that handler implemented as:

code:
public void OnWindowDeleteEvent (object o, DeleteEventArgs args)
{
        Application.Quit ();
        args.RetVal = true;
}


Of course, this doesn't give us much. Let's add some text. Back to Glade with us.

Double-click "window1" to open the window.

Then select the Label widget from the Palette window.

With that selected simply click in the window to place a label there. The properties window can then be used to change the contents of the label. When you're done, save the GUI and go back to MonoDevelop.

Rebuild the project and run it. You should have a window containing some centered piece of text.

Of course, you should notice that the window is much bigger than is necessary to accomodate the string. This is because a default size was specified for the window in Glade. We can change this easily. The downside is that the window is now very very small.

But the real question is how do we build something a bit more complex? Well, a window in GTK+ is a container which contains a single widget. In our first case, this was a Label widget.

However, we can also have container widgets which contain multiple widgets. The most common of these are vertical and horizontal boxes, as well as tables.

So, let's use a vertical box and a horizontal box to create a more complex application. We'll end up with a label, a text entry field, and a button. Back to Glade with us.

Delete the label we currently have in the window. Then add a vertical box with two rows. To the top row add a horizontal box with two columns.

In the top row, we'll add a label with the text "Name:" and a text entry field. The bottom row gets a button with the label "Say Hello". To make everything look pretty we'll add some spacing. First we can give our window a border by setting "Border Width" to 5 pixels. Next we'll select the vertical box and give it spacing of 5 pixels. Do the same to your horizontal box and you end up with a nice looking layout.

One last thing. To make sure that when the program is run the cursor starts out in the text entry field, select the text entry field and under the "Common" tab, toggle "Has Focus" to Yes.

Now save and go back to MonoDevelop.

Posted Image, might have been reduced in size. Click Image to view fullscreen.

And it doesn't do a darn thing.

But what do we want it to do?

Well, let's have it write a greeting to the console when we click the button.

So, for that to happen we need an event handler for the "clicked" signal the button sends. We also need access to the contents of the text entry field. For this, we're going to have to write some code.

But first, back to Glade. Open window1, select the button widget, and go to its "Signals" tab.

Choose the "clicked" signal in the form at the bottom of the window. You'll get a sensible name for the signal handler. Click "Add" to add this handler. Save your GUI and head back to MonoDevelop.

We'll want to add that event handler to our code in Main.cs.

code:
void on_button1_clicked (object o, EventArgs args)
{
               
}


No code in the body of the method, so nothing happens.

We don't have a way of accessing the contents of our text entry field, so we must first add the widget to our code.

code:
[Widget] Entry entry1;


The name of the variable matches the name given to the widget in Glade.

Now we can get at the contents of the entry field by accessing its Text property.

code:
void on_button1_clicked (object o, EventArgs args)
{
         Console.WriteLine("Hello, {0}!", entry1.Text);       
}


Of course, it would look stupid to print "Hello, !", so we'll add a bit of extra code.

code:
void on_button1_clicked (object o, EventArgs args)
{
         if (entry1.Text != "")
         {
                 Console.WriteLine("Hello, {0}!", entry1.Text);
         }     
}


So, now we have a source code file that looks like follows.

code:
// project created on 05/08/2005 at 7:54 P
using System;
using Gtk;
using Glade;

public class GladeApp
{
        public static void Main (string[] args)
        {
                new GladeApp (args);
        }

        public GladeApp (string[] args)
        {
                Application.Init();

                Glade.XML gxml = new Glade.XML (null, "gui.glade", "window1", null);
                gxml.Autoconnect (this);
                Application.Run();
        }

        /* Connect the Signals defined in Glade */
        public void OnWindowDeleteEvent (object o, DeleteEventArgs args)
        {
                Application.Quit ();
                args.RetVal = true;
        }
       
        [Widget] Entry entry1;
       
        void on_button1_clicked (object o, EventArgs args)
        {
               if (entry1.Text != "")
               {
                       Console.WriteLine("Hello, {0}!", entry1.Text);
               }
        }
}


That's it. That and our Glade file does it all.

Posted Image, might have been reduced in size. Click Image to view fullscreen.

I'll go further with this if there's demand for it. Smile

Questions are, as always, welcome.
Sponsor
Sponsor
Sponsor
sponsor
MysticVegeta




PostPosted: Sat Aug 06, 2005 12:34 pm   Post subject: (No subject)

I am speechless. Good job man!
wtd




PostPosted: Sat Aug 06, 2005 6:21 pm   Post subject: (No subject)

So, for a new challenge, we'll create a simple web browser.

We start out in MonoDevelop. Create a new solution. Again, this is a Glade# project, and we'll call it SimpleWebBrowser.

In the solutions pane, go to References. Right-click on it and choose "Edit References". This will bring up a dialog box. Check the box next to "gecko-sharp".

Gecko is the mozilla rendering engine, which we'll embed in our application via Gecko#.

Now we're ready to really start. First we lay out our interface. This means opening up "gui.glade" in Glade.

First, change the title of the window.

Next we want to add a one row vertical box. Into it we'll place buttons and toolbars. A display area will be added, but that'll come later.

Add a horizontal box with space for three widgets. Here we want back and forward buttons, and a text entry field. Be sure that the packing for the horizontal box has Expand set to No.

For the buttons, we'll use something rather new. Rather than simply giving them a label, we'll choose a stock button. Among the stock buttons available are Back and Forward.

Style tips include setting the relief style for the buttons to None and add border width and spacing.

Unfortunately, the Gecko# rendering widget is not available in Glade, so we'll have to add that later. Instead add a frame to the lower row of the vertical box. For now, we're done with Glade, so save your changes and quit.

Back in MonoDevelop, we need to start editing Main.cs.

The first thing we'll do is add a "using" statement for Geck.

code:
using Gecko;


Next we want access to the entry field widget and the vertical box, so we need to add those widgets inside our class.

code:
[Widget] Entry entry1;
[Widget] VBox vbox1;


And of course we need a widget for the HTML display. There's no Glade widget to bind this to, so we'll simply create a variable for it.

code:
WebControl webdsplay;


We then need to actually instantiate that web control and place it into our GUI.

Our constructor therefore has to be modified.

code:
public GladeApp (string[] args)
{
        Application.Init();

        Glade.XML gxml = new Glade.XML (null, "gui.glade", "window1", null);
        gxml.Autoconnect (this);
               
        webdisplay = new WebControl();
        webdisplay.Show();
               
        vbox1.PackStart(webdisplay);
               
        Application.Run();
}


And we can run this, but it doesn't do a darn thing, because we haven't given it a URL. For that to happen, we need to handle the "activate" event for the entry field. So back to Glade, where we'll edit the Signals tab for the text entry field. Let's call our "activate" handler "load_url". So we need to define a matching method.

code:
void load_url (object o, EventArgs args)
{
        webdisplay.LoadUrl(entry1.Text);
}


Now we can build our project and run it, and with this we can enter a URL and load it by clicking return. However, we still can't go back or forward, so we need some event handlers for those buttons.

code:
void go_back (object o, EventArgs args)
{
        webdisplay.GoBack();
}
       
void go_forward (object o, EventArgs args)
{
        webdisplay.GoForward();
}


Now you have a very basic web browser. Congratulations.
MysticVegeta




PostPosted: Sat Aug 06, 2005 10:36 pm   Post subject: (No subject)

oh i learned how to do that in VC++ its quite easy all we gotta do is modify the code provided by the IDE lol Laughing
wtd




PostPosted: Sat Aug 06, 2005 11:48 pm   Post subject: (No subject)

MysticVegeta wrote:
oh i learned how to do that in VC++ its quite easy all we gotta do is modify the code provided by the IDE lol Laughing


Did I mention that this is all portable?
MysticVegeta




PostPosted: Sun Aug 07, 2005 12:13 pm   Post subject: (No subject)

what do you mean by "portable"?
wtd




PostPosted: Sun Aug 07, 2005 2:29 pm   Post subject: (No subject)

If I have Mono and the necessary assemblies (libraries) installed on the client computer, I can take the generated executable and run it seamlessly on any combination of operating system and hardware.
MysticVegeta




PostPosted: Mon Aug 08, 2005 8:26 am   Post subject: (No subject)

dont all executables run on every computer without the neccessity of having the libraries installed on it?
Sponsor
Sponsor
Sponsor
sponsor
wtd




PostPosted: Mon Aug 08, 2005 12:15 pm   Post subject: (No subject)

MysticVegeta wrote:
dont all executables run on every computer without the neccessity of having the libraries installed on it?


No.

If you use static linking, which includes the required library code directly in the executable, then to some extent you can get away with this.

However, this only covers one CPU architecture, and for the most part, one operating system. Different CPUs speak entirely different languages at the machine level, and even on the same CPU architcture, there can be multiple formats for the compiled binary.

This also doesn't cover dynamic linking, which avoids including the library code in the executable and links it in at runtime. This can greatlu reduce the size of an executable, though it requires that the library be available already on the client computer.
MysticVegeta




PostPosted: Tue Aug 09, 2005 1:17 pm   Post subject: (No subject)

I bow to the prince.
Display posts from previous:   
   Index -> General Programming
View previous topic Tell A FriendPrintable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic

Page 1 of 1  [ 10 Posts ]
Jump to:   


Style:  
Search: