I have been trying to use GTK-2+ for writting a graphical interface for my research related program. I followed through some of the tutorials for generating different types of widgets and its associated 'callback functions'. Still i have problem understanding some key issues, which are stated below.

1) In a conventional 'c' program the code is executed in a sequential fashion, but in gtk based c program, all the widget which are used and its associated callback acts independently and parallely. 2) I would like to know how to make them work in a sequential fashion.

Here is the thing i wanted to implement....

A main window, with a menubar. A menu item named 'file' was created and two sub menuitems namely 'open' and 'run' was included in the 'file' menu. Finally, the 'file' menu was incorporated in the menubar.

For the 'open' menu item i used a 'callback function' named 'file selection' which inturn calls a 'callback function' named 'store path' to save the path and name of the selected file. (the codes for the above mentioned functions, were copied from the gtk-2+ tutorials). I used 'gpointer data' to save the 'file path' while 'open's callback function was called. In the next step, when the 'run' menu item is selected, i wanted to use the 'filepath' (saved as gpointer data using the previous 'open' menu's selction) and open that selected file in the background to perform some calclations and generate a new output file.

Unfortunately, i was not able to do that. I get segmentation faults. here is the actual code. I greatly appreciate your help and suggestions...

Thanks for your previous reply, I'm using gtk2.0 version. It is pretty old, but firstly, I want to understand the GTK concepts using older version.

If I can get past this problem of passing and modifying the 'gpointer data', I can convert my 'terminal based open sourced programs' into a simple graphic based ones for user's convenience.

To state my actual problem again....1) The user chooses an input file (which contains initial parameters. i.e a txt file)2) The program then stores the path and name of the user selected file3) Subsequently the calculation is initiated by parsing and reading the input file and generating the output.4) The results are either displayed as a message box or saved as an output file.

I was trying to do this in the following way:created two menu items namely: 'open' and 'run'initialized a string: gchar *data;

passed the 'data' as a gpointer data for the callback function of 'open' on event 'clicked'. And this sucessfully stored the file name along with its path. But in the next step, I wanted to pass the 'data' (now modified by clicking 'open'), as an input 'gpointer data' for the callback function of 'run' item on activation. Unfortunately, the second step is not working. Is there a way I can make it happen.

Ultimately, what I need to know is to how a 'gpointer data' is sequentially passed and modified by a series of callback functions affliated to different menu items in a sequential fashion. Any help is greatly appreciated.

If the GTK+ version that you have is genuinely 2.0 then that dates from at latest November 2002 making that over ten years old. GTK+ has progressed a lot since then even in the 2.xx series. I would advise that you up-grade to version 3 or to version 2.24. This way you are not learning things that would need to be unlearned very soon after, or picking up practice that is now considered not good.

Going back to your original problem.

In your function store_filename() you are not actually storing the file name. What is happening is that the local pointer is modified which then goes out of scope at the end of the function. What I expect you wanted to do is copy the string to where the pointer points to. Also you are using fixed sized data storage for storing the file name. This can easily lead to a buffer overflow if the user enters a very long file name. The best way would be to allocate memory as and when needed. If you do want to keep using a fixed sized buffer then use the macro FILENAME_MAX though this is not recommended.

Iam trying to pass a 'char pointer' named 'file_name' declared in main(), which is passed on to 'create_file_selection()' and finally to 'store_filename()', where its value is modified. After modifyng its value using 'open' item, a subsequent click of 'run' item, didnt print the actual path. Can you kindly show me the right way to code it.Also, inside the function file_print() if i use file pointers, i get segmentation fault (here i have commented that part of code appropriately).

Since, iam focussing mainly on correctly passing the 'gpointer data' from one function to other, i did'nt pay much attention to the allocation size of 'filename'. Certainly, in the future code, i will define FILENAME_MAX properly.

Thank you,

Last edited by janarbio on Mon Jan 07, 2013 3:46 am, edited 1 time in total.

which is a pointer to a static field that is compiled right into the program, and

Code:

gchar *data;strcpy ( data, "/tmp/foo" );

which will segfault as the data pointer has no memory yet, it's just a pointer to nothing, or a pointer to anything, nobody knows. It could be 2 bytes ( segfault) or the entire text of Moby Dick (no segfault, but the memory is completely wasted because you're now only using 8 bytes of a few million).

if you're going to assign something to gchar *data, I would use:

Code:

if ( data ) g_free(data);data = g_strdup("/tmp/foo");

It malloc's a fresh new memory chunk just for the purpose. No segfault.

I have already mentioned the use of fixed sized buffers to janarbio which he now knows about. His main problem is that he is using a version of GTK+ that dates over ten years old and is using code that was deprecated and in some cases has been removed from modern versions of GTK+.

Just to clarify the use of g_free(). You do not need to do a check to see if the pointer is not NULL before calling g_free(). This is done internally to g_free() and is stated in the documentation. By doing the extra check all you are doing is adding extra bloat to your code and slowing it down a little bit. So you example becomes.

It took me some time to install gtk3+ and modify the previous code based on the available tutorial files. The code pasted below is intended to perform the following.1) Opens a main window -> with 1 menuitem "file"-> containing 2 menuitems "Open" and "Run".2) On clicking "Open"-> Filechooserdialog opens.

Further, the "Filechooserdialog box" has three gdkevent "selection-changed", "current-folder-changed" and "response" with three callbacks namely, "print_selected", "print_current_folder" and response_cb, whose prototype are as follows.

When I select a file, the callback function to "response" prints the fullpath of the selected file. Till this point, things are fine.

Now I have one minor problem and one major problem. The minor one is, with the following 'response_cb' callback function, on clicking either the 'open' or 'close' buttons which are present by default in the file selection dialog box, the main window also closes. When I changed the function from 'response_cb' to 'gtk_widget_destroy', this problem was averted. (I'm not sure whether this is the correct way to do it.)

But the major one is the passing of the gpointer data to these callback functions. I searched for the standard prototype definitions of the callbacks for the mentioned gdkevents (selection-changed, current-folder-changed, response), I could find none, except for the functions defined in the demo files, which does not pass any gpointer data. i.e.

Code:

static void print_current_folder (GtkFileChooser *chooser);

Code:

static void print_selected (GtkFileChooser *chooser);

Code:

static void response_cb (GtkDialog *dialog, gint response_id);

But what I wanted is to pass a structure similar to the following example; to each of the callbacks and copy and store the filepath as it prints to the terminal.

Code:

typedef struct{ gchar *filename; GtkFileChooser *chooser;} Data_type;

Unfortunately, when I try to initialize and pass it as a data I ran into trouble as 'GtkFileChooser' is an object of a class and allocationg memory is through 'new' function available in c++. I'm not sure how malloc can be used in this instance,

Any help/suggestions on passing the data and printing it to terminal when the 'File->'run' menu is activated (after activation of 'File->open') would be greatly appreciated. Thank you,The currently working code is as follows,

Dear Zerohour, Errol and Mevin,Thanks for your previous help. I found the prototype of the callbacks very useful.I found where i was making the mistake, (which i would not have sorted out if you had not pointed me to the correct doc reference). (I will learn to use grid rather than boxes in future).

(Iam elaborating the problem so that it will be helpful for newbie like me...)My objective was simple,1) create a main Window -> with a menubar-> with a menu "file"-> with two submenuitems "Open" and "Run".2) On clicking "open" submenuitem, "filechoosedialog box" opens. The selected filename with its full path is saved into a string variable.3) On Clicking "run" submenuitem, the saved variable is printed to the terminal. (Infact this will be used to open the file, read and perform some useful calculations).

I had a problem using the callback functions correctlyas i was not aware that, the number and order of input arguments for the callbacks are very important. For example, In the below example

Unfortunatley, the 'file_name_ptr' was not passed properly and when printed showed strange characters. But the prototype of callback of "activate" Gdkevent when used as 'g_signal_connect' has two arguments with a widget and a gpointer.

Code:

void callback_func( GtkWidget *widget, gpointer callback_data );

My callback had only one argument, which was a gpointer, so whenever, i called 'file_name_retrieve', the passed argument was considered as a widget. hence, printed strange charcters. When i used,

Below is how I would write your code (still not great code). This shows how simple it is to use the new GtkGrid container. I have also modified it so that the "response" signal can be used. The original problem was that you had used gtk_main_quit() which eventually quit the application. gtk_widget_destroy() should have been used instead. This way would allow the use of Cancel, OK, etc.

With the file name I have used memory allocated from the heap instead of statically allocated memory. This is always safer as there is less risk of a buffer overflow or any limit on the size of the file name. In your function file_name_retrive() I have used the Glib function g_filename_from_uri(). This function converts from a URI to a file name with proper checking, again this is safer than assuming that the beginning of the URI will always be a fixed size. The way the code is set up it is only possible to select one file at a time. If you needed to you can ask the File Chooser to allow selection of more than one file and instead of passing around a single gchar * you can pass around a GSList. This should only take a little bit of extra work and thought.

You mentioned about C++ in a previous posting. There are bindings for C++ which you may find easier if you are more at home with the C++ way of doing things. Also whenever I am coding I always keep a off-line reference manual to hand (normally DevHelp). This way I can easily find out what parameters a signal call-back takes and look up those useful little functions that would make my code better.

Thank you very much Errol!I appreciate your patience in rewriting the code and exemplifying the usage of allocating memory from the heap, grid and filename conversion from url format to normal format. I will start adopting this better way of coding. Thanks again.

Hi Errol,Thanks for your good suggestions. I tried modifying the code to select multiple files and also passing GSList as the gpointer data. The program compiled well. But, i think the way i copied the contents of one GSList to another inside a function is not the best way. Your suggestions on this problem will be very useful to me. (For some reasons iam not able to use the function correctly)

Who is online

Users browsing this forum: Yahoo [Bot] and 6 guests

You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot post attachments in this forum