User avatar
flatmax
Posts: 336
Joined: Thu May 26, 2016 10:36 pm

Tutorial 5 - Programming GTK GUIs using gtkIOStream

Mon Feb 06, 2017 10:01 am

Hi again,

gtkIOStream is a set of C++ headers which enable you to make GTK GUI programs in a very trivial manner.

This tutorial 5 will demonstrate how to create a button with a callback function.
Tutorial contents can be [url=viewtopic.php?f=67&t=173531]found here[/url].

Lets begin by making sure that we are in the correct path location before we start, for these tutorials, we assume gtkiostream-1.5.0 is in your home directory. You can either use the command "cd ~" or simply "cd" to get to your home directory.

The location of gtkiostream is in the home directory of the user pi (cd ~ if you aren't there and want to get there). Our current directory (pwd) is /home/pi. Great gtkiostream-1.5.0 is in our current directory and we are ready to start.

In this tutorial we are going to learn how to create a callback function, a structure to hold required definitions for a string label button and how to create/show the button in the GtkInterface top window dialog.

Matt
p.s. Please reply to this thread with any bug fixes, questions or help requests.
Last edited by flatmax on Wed Feb 08, 2017 9:36 am, edited 3 times in total.
Check the Ultra 2 sound card - use our shop instead of Amazon Europe (Amazon USA is live).
Sound card for the Raspberry Pi with inbuilt microphone : www.audioinjector.net
Audio Inector Octo multitrack GPIO sound card

User avatar
flatmax
Posts: 336
Joined: Thu May 26, 2016 10:36 pm

Re: Tutorial 5 - Programming GTK GUIs using gtkIOStream

Mon Feb 06, 2017 10:36 am

All buttons, whether they show strings, graphics, are toggle buttons, arrow buttons, radio buttons or check buttons require two things.

The first is a callback function to execute when the button signals an event (such as a mouse click).

The second is a user pointer variable to pass to the callback to allow it to have a reference to something meaningful to your program. There is no point executing a function in your program once a button signals if it doesn't have user specific data of some form to do something with - unless of course you either don't need data to execute the function OR all of your variables are global variables !

For that reason, all buttons are created by passing in data (using the << operator) which are derived from a class called AnyFuncData :
[code]class AnyFuncData {
void (*func)(); ///< The function to call when the button is pressed
gpointer data; ///< The data to pass to func when the button it pressed
};
[/code] As you can see the class AnyFuncData defines the callback function AnyFuncData::func and a glib pointer ([url=https://developer.gnome.org/glib/stable ... l#gpointer]void pointer[/url]) AnyFuncData::data.

If you don't understand what I am talking about so far, don't worry, once you do these few tutorials, it will all start to make sense!

We will start by defining a callback function which makes the GTK main loop quit, this function will be preceded by a comment which will tell us about the function and the variables it takes as input/output :
[code]// Define the quit callback function
static void quit(void *wid, gpointer data){
// print out an entry message and also print the input variables
cout<<"quit callback enter with wid="<<wid<<" and data="<<data<<endl;
gtk_main_quit(); // quit the GTK main loop
cout<<"quit callback exit"<<endl; // print out an exit message
}
[/code] This function takes in a widget ID (wid) and the user data pointer (data). It prints an entry message, calls the GTK main program quit function (gtk_main_quit) and then prints the exit message. Note that because the return value is "void" nothing is returned.

So lets write our complete program. To start with, edit the file ButtonCallback.C :
[code]#include <gtkInterface.H>
#include <Buttons.H>

/** Define the quit callback function
\param wid The button widget which was pressed to signal the execution of this function.
\param data The user data you asked this callback to be given.
*/
static void quit(void *wid, gpointer data){
// print out an entry message and also print the input variables
cout<<"quit callback enter with wid="<<wid<<" and data="<<data<<endl;
gtk_main_quit(); // quit the GTK main loop
cout<<"quit callback exit"<<endl; // print out an exit message
}

int main(int argc, char *argv[]){

gtk_init( &argc, &argv ); // init GTK

Buttons buttons; // Instantiate the Buttons class and variable
buttons<<LabelFuncData("Quit", quit, NULL); // Create a string button

HBox hBox; // Create a horizontal box to hold the button
hBox<<buttons; // load the button into the Box

GtkInterface topWindow; // Create the top box
topWindow<<hBox.show(); // show the horizontal box and load it into the top w\
indow

gtk_main(); // run GTK+

cout<<"main exit"<<endl;
return 0;
}[/code] We will talk now about code you haven't seen before.
We have begun by including the Buttons.H class definitions :
[code]#include <Buttons.H>[/code] We then instantiate our buttons variable of type Buttons :
[code] Buttons buttons;[/code] It is now time to create our first button. We are going to create a "label" button which displays the string "quit". Once this button is clicked, it will execute the quit callback function we discussed above. Lets create our first GtkButton widget using the Buttons class :
[code] buttons<<LabelFuncData("Quit", quit, NULL);[/code] Nice and easy eh ! What was all this preambling fuss about ?

This LabelFuncData inherits the AnyFuncData we previously discussed and stores the two necessary variables (callback quit and user data NULL) as well as setting the button label for us. Once the button signals (is clicked), it will pass two variables to the quit callback function. The first is a pointer to the GtkButton widget we created in the line above and the second is the user data we ask it to pass (NULL). We expect the button to print out some messages to the console and also quit the GTK main loop.

We load the buttons we created into a horizontal box :
[code] hBox<<buttons;[/code] and we both show and load that hBox into the GtkInterface top window :
[code] topWindow<<hBox.show();[/code]

Once the quit button has been clicked and signaled the quit callback function to execute, we expect the gtk_main function to return. We check gtk_main returns by printing "main exit" to the console :
[code] gtk_main();

cout<<"main exit"<<endl;
[/code]
Finally our main program returns 0 :
[code] return 0;[/code]
Check the Ultra 2 sound card - use our shop instead of Amazon Europe (Amazon USA is live).
Sound card for the Raspberry Pi with inbuilt microphone : www.audioinjector.net
Audio Inector Octo multitrack GPIO sound card

User avatar
flatmax
Posts: 336
Joined: Thu May 26, 2016 10:36 pm

Re: Tutorial 5 - Programming GTK GUIs using gtkIOStream

Mon Feb 06, 2017 10:52 am

To compile, we run our compile command with the correct file targets :

Code: Select all

g++ ButtonCallback.C -o ButtonCallback `pkg-config gtk+-2.0 --cflags --libs` -Igtkiostream-1.5.0/include
Which we execute using the command : ./ButtonCallback

You should see the following dialog open up:
ButtonCallback.png
Tutorial 5 : gtkIOStream
ButtonCallback.png (4.58 KiB) Viewed 2238 times
Once you click the button you should see the following (with different numbers) printed out to console and the gialogue window should disappear :

Code: Select all

quit callback enter with wid=0x946b438 and data=0
quit callback exit
main exit
Hope that you are enjoying learning how to program GTK GUIs with gtkiostream.
Matt
Check the Ultra 2 sound card - use our shop instead of Amazon Europe (Amazon USA is live).
Sound card for the Raspberry Pi with inbuilt microphone : www.audioinjector.net
Audio Inector Octo multitrack GPIO sound card

1dot0
Posts: 430
Joined: Mon Nov 28, 2016 12:31 pm

Re: Tutorial 5 - Programming GTK GUIs using gtkIOStream

Mon May 15, 2017 12:47 pm

also in that case my window looks different, having the Quit Button on the opposite side, at the right side:
gtkBtnHBoxScrot.jpg
gtkBtnHBoxScrot.jpg (3.88 KiB) Viewed 1561 times
Code from above, kind of reformatted:

Code: Select all

// gtkBtnHBox.c

#include <gtkInterface.H>
#include <Buttons.H>

/** Define the quit callback function
\param wid The button widget which was pressed to signal the execution of this function.
\param data The user data you asked this callback to be given.
*/
static void quit(void *wid, gpointer data){
   // print out an entry message and also print the input variables
   cout<<"quit callback enter with wid="<<wid<<" and data="<<data<<endl;
   gtk_main_quit(); // quit the GTK main loop
   cout<<"quit callback exit"<<endl; // print out an exit message
}

int main(int argc, char *argv[]){

   gtk_init( &argc, &argv ); // init GTK

   Buttons buttons; // Instantiate the Buttons class and variable
   buttons<<LabelFuncData("Quit", quit, NULL); // Create a string button

   HBox hBox; // Create a horizontal box to hold the button
   hBox<<buttons; // load the button into the Box

   GtkInterface topWindow; // Create the top box
   topWindow<<hBox.show(); // show the horizontal box and load it into the top window

   gtk_main(); // run GTK+

   cout<<"main exit"<<endl;
   return 0;
}

can someone check that please?

1dot0
Posts: 430
Joined: Mon Nov 28, 2016 12:31 pm

Re: Tutorial 5 - Programming GTK GUIs using gtkIOStream

Tue May 16, 2017 6:15 am

update:
after Parryn's changes in
viewtopic.php?f=67&t=173446&p=1163189#p1163076

now the "quit" button is shown correctly vertically alligned to the left border, like Matt's picture here:
Image

Return to “Graphics programming”