NOGDUS $1670.00 has been donated to NOGDUS!
August 22, 2017, 05:18:25 PM *
Welcome, Guest. Please login or register.

Login with username, password and session length
 
   Home   Help Search Login Register  
Pages: [1]   Go Down
  Print  
Author Topic: C++ and GTK+ 2.0 Programming  (Read 3801 times)
0 Members and 1 Guest are viewing this topic.
Richard Marks
Administrator
Offline Offline

Respect: 3425
« on: October 21, 2008, 12:27:51 AM »

I have finally gotten around to figuring out how to do some stuff in GTK+ with C++.  Cheesy
And now I am going to share my findings with you.

This article assumes a few things about you and your system.
  • You know how to create C++ programs on your system.
  • You know how to install things on your system.
  • You have SConS installed and know how to create a basic SConstruct file.

The rest of this article will use an Ubuntu Linux OS, and all paths and commands will need to be adjusted if you are not using Linux.

First if you haven't done so already, install the GTK+2.0 development files.

Code:
$ sudo apt-get install libgtk2.0-dev

Create a directory to hold your project files.
Create the project files.
Open the project files in a text editor. I'm using gedit here.

Code:
$ mkdir gtkhelloworld
$ cd gtkhelloworld
$ touch SConstruct
$ touch gtkhelloworld.cpp
$ gedit SConstruct gtkhelloworld.cpp &

Now lets write the SConstruct script:

Code:
# SConstruct
# scons build script

demo_libs = Split("""
gtk-x11-2.0
gdk-x11-2.0
atk-1.0
gdk_pixbuf-2.0
m
pangocairo-1.0
pango-1.0
cairo
gobject-2.0
gmodule-2.0
dl
glib-2.0 
""")

demo_includes = Split("""
/usr/include/gtk-2.0
/usr/lib/gtk-2.0/include
/usr/include/atk-1.0
/usr/include/cairo
/usr/include/pango-1.0
/usr/include/glib-2.0
/usr/lib/glib-2.0/include
/usr/include/freetype2
/usr/include/libpng12
/usr/include/pixman-1 
""")

demo_env = Environment(CCFLAGS = '-DPNG_NO_MMX_CODE')
demo_env.Program('gtkhelloworld', 'gtkhelloworld.cpp', LIBS = demo_libs, CPPPATH = demo_includes)

Here we will write the C++ source for our little demo:

First write a basic demo application framework like this:
Code:

// CODESTYLE: v2.0

// gtkhelloworld.cpp
// Project: Hello World in GTK ()
// Author: Richard Marks

#include <gtk/gtk.h>

#include <cstdio>
#include <cstdlib>
#include <cstring>

class Demo
{
public:
Demo();
~Demo();
int Initialize(int argc, char* argv[]);
int Execute();

private:

}; // end class

Demo::Demo()
{
}

Demo::~Demo()
{
}

int Demo::Initialize(int argc, char* argv[])
{
return 0;
}

int Demo::Execute()
{
return 0;
}

int main(int argc, char* argv[])
{
int result = 0;
Demo* demo = new Demo();
if (0 == demo->Initialize(argc, argv))
{
result = demo->Execute();
}
delete demo;
return result;
}


I like to use this format for all my demos, games, applications, etc.
It works well, and is simple and effective.

Now, we need to add our code for the actual demo.

In the private section of the Demo class, place a variable declaration for our main window handle.
Code:
GtkWidget* mainWindow_;

Add some code to the Demo constructor to set a default value to our main window handle to zero.
Code:
Demo::Demo() :
mainWindow_(0)
{
}

Now we need to initialize GTK and create our window, and we will center the window and set its title text.
This of course all goes in the Initialize member function of the Demo class.
Code:
// initialize GTK
gtk_init(&argc, &argv);

// create the main window widget
mainWindow_ = gtk_window_new(GTK_WINDOW_TOPLEVEL);

// set the window title text
gtk_window_set_title(GTK_WINDOW(mainWindow_), "Hello World in GTK!");

// set the window size
gtk_window_set_default_size(GTK_WINDOW(mainWindow_), 600, 400);

// center the window
gtk_window_set_position(GTK_WINDOW(mainWindow_), GTK_WIN_POS_CENTER);

// display the window
gtk_widget_show(mainWindow_);

In order to be able to shutdown the application properly when the X close button is clicked, we have to tell our program HOW to close properly.

We do this in the Initialize member function of the Demo class, after we have initialized everything.
Code:
// attach the signal to quit the application when the window is destroyed
g_signal_connect_swapped(
G_OBJECT(mainWindow_),
"destroy",
G_CALLBACK(gtk_main_quit),
0);

For our program to run, we have to call the function in GTK that handles the events and stuff.
This code goes in the Execute member function of the Demo class.
Code:
// start the GTK event processor
gtk_main();

And we are finished!

Type scons in your project's directory and you can run it.
Code:
$ scons
$ ./gtkhelloworld
Logged

Richard Marks
Administrator
Offline Offline

Respect: 3425
« Reply #1 on: October 21, 2008, 12:29:09 AM »

Here is the full code for the article above, so you can see how it should all go together.
Code:

// CODESTYLE: v2.0

// gtkhelloworld.cpp
// Project: Hello World GTK ()
// Author: Richard Marks

#include <gtk/gtk.h>

#include <cstdio>
#include <cstdlib>
#include <cstring>

class Demo
{
public:
Demo();
~Demo();
int Initialize(int argc, char* argv[]);
int Execute();

private:
GtkWidget* mainWindow_;
}; // end class

Demo::Demo() :
mainWindow_(0)
{
}

Demo::~Demo()
{
}

int Demo::Initialize(int argc, char* argv[])
{
// initialize GTK
gtk_init(&argc, &argv);

// create the main window widget
mainWindow_ = gtk_window_new(GTK_WINDOW_TOPLEVEL);

// set the window title text
gtk_window_set_title(GTK_WINDOW(mainWindow_), "Hello World in GTK!");

// set the window size
gtk_window_set_default_size(GTK_WINDOW(mainWindow_), 600, 400);

// center the window
gtk_window_set_position(GTK_WINDOW(mainWindow_), GTK_WIN_POS_CENTER);

// display the window
gtk_widget_show(mainWindow_);

// attach the signal to quit the application when the window is destroyed
g_signal_connect_swapped(
G_OBJECT(mainWindow_),
"destroy",
G_CALLBACK(gtk_main_quit),
0);

return 0;
}

int Demo::Execute()
{
// start the GTK event processor
gtk_main();

return 0;
}

int main(int argc, char* argv[])
{
int result = 0;
Demo* demo = new Demo();
if (0 == demo->Initialize(argc, argv))
{
result = demo->Execute();
}
delete demo;
return result;
}

Please let me know what you think.
And also,  let me know if you have any questions.
Logged

Richard Marks
Administrator
Offline Offline

Respect: 3425
« Reply #2 on: October 21, 2008, 06:43:10 AM »


Here is an example application of how to work with GTK+

Code:
// CODESTYLE: v2.0

// gtktextentryexample.cpp
// Project: GTK Text Entry Example ()
// Author: Richard Marks

#include <gtk/gtk.h>

#include <cstdio>
#include <cstdlib>
#include <cstring>

class Demo
{
public:
Demo();
~Demo();
int Initialize(int argc, char* argv[]);
int Execute();

private:
// function to create the main menu widgets
// and signal handlers
void CreateMainMenu();

// utility function for displaying a simple message dialog box
static void MessageBox(GtkWidget* parent, const char* title, const char* message);

// event callback functions for the menu
static void FileQuitMenuClicked(GtkWidget* widget, gpointer data);
static void HelpAboutMenuClicked(GtkWidget* widget, gpointer data);

// event callback function for the button that will show what
// the user has entered in the text entry box
static void ShowButtonClicked(GtkWidget* widget, gpointer data);
private:
GtkWidget* mainWindow_;
GtkWidget* mainContainer_;

}; // end class

Demo::Demo() :
mainWindow_(0),
mainContainer_(0)
{
}

Demo::~Demo()
{
}

void Demo::CreateMainMenu()
{
/*
File Help
Quit About
*/
GtkWidget* mainMenuBar = 0;
GtkWidget* fileMenu = 0;
GtkWidget* fileMenuItem = 0;
GtkWidget* fileQuitMenuItem = 0;
GtkWidget* helpMenu = 0;
GtkWidget* helpMenuItem = 0;
GtkWidget* helpAboutMenuItem = 0;


// create the main menu bar
mainMenuBar = gtk_menu_bar_new();

// create the file menu
fileMenu = gtk_menu_new();

//  create the help menu
helpMenu = gtk_menu_new();

// create the menu items
fileMenuItem = gtk_menu_item_new_with_label("File");
fileQuitMenuItem = gtk_menu_item_new_with_label("Quit");
helpMenuItem = gtk_menu_item_new_with_label("Help");
helpAboutMenuItem = gtk_menu_item_new_with_label("About");

// set the file menu item as a submenu of the file menu
gtk_menu_item_set_submenu(GTK_MENU_ITEM(fileMenuItem), fileMenu);

// set the help menu item as a submenu of the help menu
gtk_menu_item_set_submenu(GTK_MENU_ITEM(helpMenuItem), helpMenu);

// honestly I don't fully understand this code yet,
// but it works. I'll research more and update this
// comment to explain what is going on later.
gtk_menu_shell_append(GTK_MENU_SHELL(fileMenu), fileQuitMenuItem);
gtk_menu_shell_append(GTK_MENU_SHELL(mainMenuBar), fileMenuItem);
gtk_menu_shell_append(GTK_MENU_SHELL(helpMenu), helpAboutMenuItem);
gtk_menu_shell_append(GTK_MENU_SHELL(mainMenuBar), helpMenuItem);

// pack the menu bar into the container
gtk_box_pack_start(GTK_BOX(mainContainer_), mainMenuBar, FALSE, FALSE, 3);

// attach a signal to quit the application when the quit menu item is clicked
g_signal_connect(
G_OBJECT(fileQuitMenuItem),
"activate",
G_CALLBACK(Demo::FileQuitMenuClicked),
0);

// attach a signal to show the about box when the about menu item is clicked
g_signal_connect(
G_OBJECT(helpAboutMenuItem),
"activate",
G_CALLBACK(Demo::HelpAboutMenuClicked),
(gpointer)mainWindow_);
}

void Demo::MessageBox(GtkWidget* parent, const char* title, const char* message)
{
// create the dialog that will be displayed
GtkWidget* msgBox = gtk_dialog_new_with_buttons(
title,
GTK_WINDOW(parent),
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_STOCK_OK,
GTK_RESPONSE_NONE,
0);

// attach a signal that ensures the dialog is destroyed when the OK
// button is clicked
g_signal_connect_swapped(
msgBox,
"response",
G_CALLBACK(gtk_widget_destroy),
msgBox);

// add the label to the dialog
GtkWidget* msgLabel = gtk_label_new(message);
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(msgBox)->vbox), msgLabel);

// show the dialog
gtk_widget_show_all(msgBox);
}

void Demo::FileQuitMenuClicked(GtkWidget* widget, gpointer data)
{
gtk_main_quit();
}

void Demo::HelpAboutMenuClicked(GtkWidget* widget, gpointer data)
{
// call the utility function that we made to show a simple messagebox
Demo::MessageBox((GtkWidget*)data,
"About",
"\n\nA Simple GTK Text Entry Example\n"
"Created by Richard Marks\n"
"ccpsceo@gmail.com\n\n");
}

void Demo::ShowButtonClicked(GtkWidget* widget, gpointer data)
{
// create a message to show the user
char message[1024];
sprintf(message,
"\n\nYou have entered the following:\n\n%s\n\n",
gtk_entry_get_text(GTK_ENTRY((GtkWidget*)data)));

// display the message box
Demo::MessageBox(0,
"Entry Demo",
(const char*)message);
}

int Demo::Initialize(int argc, char* argv[])
{
// initialize GTK
gtk_init(&argc, &argv);

// create the main window widget
mainWindow_ = gtk_window_new(GTK_WINDOW_TOPLEVEL);

// set the window title text
gtk_window_set_title(GTK_WINDOW(mainWindow_), "How to use Text Entry in GTK!");

// set the window size
gtk_window_set_default_size(GTK_WINDOW(mainWindow_), 600, 400);

// center the window
gtk_window_set_position(GTK_WINDOW(mainWindow_), GTK_WIN_POS_CENTER);

// create a widget container
mainContainer_ = gtk_vbox_new(FALSE, 0);

// add the container to the main window
gtk_container_add(GTK_CONTAINER(mainWindow_), mainContainer_);

// call the member function to create the main menu
// widgets and setup the menu
CreateMainMenu();

// create a horizontal container to hold the text entry and the button
GtkWidget* entryContainer = gtk_hbox_new(FALSE, 0);

// create the text entry box and the "show" button
GtkWidget* textEntry = gtk_entry_new();
GtkWidget* showTextButton = gtk_button_new_with_label("Show");

// pack the entry container into the main container
gtk_box_pack_start(GTK_BOX(mainContainer_), entryContainer, FALSE, TRUE, 0);

// pack the text entry
gtk_box_pack_start(GTK_BOX(entryContainer), textEntry, TRUE, TRUE, 0);

// pack the button
gtk_box_pack_start(GTK_BOX(entryContainer), showTextButton, TRUE, TRUE, 0);

// attach the signal handler to the show button
g_signal_connect(
G_OBJECT(showTextButton),
"clicked",
G_CALLBACK(Demo::ShowButtonClicked),
(gpointer)textEntry);


// display the window, and all widgets on it
gtk_widget_show_all(mainWindow_);

// attach the signal to quit the application when the window is destroyed
g_signal_connect_swapped(
G_OBJECT(mainWindow_),
"destroy",
G_CALLBACK(gtk_main_quit),
0);

return 0;
}

int Demo::Execute()
{
// start the GTK event processor
gtk_main();

return 0;
}

int main(int argc, char* argv[])
{
int result = 0;
Demo* demo = new Demo();
if (0 == demo->Initialize(argc, argv))
{
result = demo->Execute();
}
delete demo;
return result;
}


Its commented, and should be easy enough to understand.
If not, then just post questions, and I will answer them.
Logged

Tags:
Pages: [1]   Go Up
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines
.: Theme by Richard Marks :.
Valid XHTML 1.0! Valid CSS!