GTK+ Forums

Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
It is currently Wed Sep 03, 2014 2:06 am

All times are UTC




Post new topic Reply to topic  [ 18 posts ]  Go to page Previous  1, 2
Author Message
 Post subject: Re: GtkCellRendererSpin Seg Fault
PostPosted: Mon Apr 23, 2012 8:30 pm 
Offline
Familiar Face

Joined: Tue Feb 09, 2010 12:33 am
Posts: 32
Hello Errol,

I have tried to debug the program written by Kepica using insight, http://sources.redhat.com/insight/. I seem to be only able to step through the GTK source code in assembler and I am not proficient at reading assembler so I am not able to see what is happening there. One thing I have noticed is that when stepping through editing_started the button variable has a value when created but says "(GtkSpinButton* ) Could not read variable object value after assignment" after the call to g_signal_connect. I am still in the editing_started function at line 124 (break) so I would think the pointer should still be valid. This might be expected behavior I do not know.

After stepping through value_changed I end up in g_closure_invoke at "0x3db540ea24 <g_closure_invoke+340>: mov (%rbx),%rdx" and then after more stepping through in g_closure_unref at "0x3db540e130 <g_closure_unref>: push %rbx"
After stepping through g_closure_unref I think the program goes into the main loop but I am not able to follow.

Is there a way I can keep stepping through the code? I have installed gtk3_debuginfo but it does not seem to have any effect.

When I click on the spinbutton and I get the message "(test:30833): GLib-GObject-CRITICAL **: g_object_notify: assertion `G_IS_OBJECT (object)' failed" it occurs somewhere between the main loop (?) and before the execution of tree_path = gtk_tree_path_new_from_string (path); in the editing_started function. Once I get this message for the first time I get it every time.

Eventually I get the message "Program received signal SIGSEGV, Segmentation fault" and end up at 0x3db54135b8 <g_object_notify+56>: cmpq $0x50,(%rax) every time which might be normal behavior.

I hope this helps with your debugging. Let me know if I can provide more information.

Thanks,

Patrick


Top
 Profile  
 
 Post subject: Re: GtkCellRendererSpin Seg Fault
PostPosted: Tue Jul 10, 2012 7:13 pm 
Offline
Familiar Face

Joined: Tue Feb 09, 2010 12:33 am
Posts: 32
Hello,

I have compiled the program written by Kepica on Fedora 17 and somewhere in gtk it still seems to be buggy. I have not had the program segfault yet but I get this error, (test:21097): GLib-GObject-CRITICAL **: g_object_notify: assertion `G_IS_OBJECT (object)' failed, repeatedly when I click on the spinbutton + or - sign. The value for "bottles of coke" starts at 20.000000, climbs to 20.200000 and then switches between 20.20000 and 20.100000 even though I am only clicking the + button. When I click the - button the value counts down as expected but here seems to be a floating point rounding error when calling gtk_list_store_set to display the new value. When I print out the value with g_print (" %f ",value); it shows 19.800000 in the terminal window but setting the list_store with the value displays 19.799999.

Should I file a bug at https://bugzilla.gnome.org/?

Thanks,

Patrick


Top
 Profile  
 
 Post subject: Re: GtkCellRendererSpin Seg Fault
PostPosted: Thu Jul 12, 2012 11:37 am 
Offline
Never Seen the Sunlight

Joined: Mon Apr 28, 2008 5:52 am
Posts: 745
Location: UK
Hi,

It has taken a far bit of time for many different reasons, but here goes.

There is no need to file a bug report, as all is actually OK, but not what you may expect should happen. I have done a fair bit of rewriting of your code.

Code:
#include <gtk/gtk.h>
#include <string.h>
#include <stdlib.h>


static GtkWidget *window = NULL;

typedef struct
{
  gchar *product;
  gfloat  yummy;
}
Item;

enum
{
  COLUMN_ITEM_PRODUCT,
  COLUMN_ITEM_YUMMY,
  NUM_ITEM_COLUMNS
};

static GtkWidget *treeview;
static GtkListStore *model;

static GArray *
add_items (void)
{
  Item foo;
  GArray *articles = g_array_sized_new (FALSE, FALSE, sizeof (Item), 2);

  if (!articles) return NULL;

  foo.product = "bottles of coke";
  foo.yummy = 20.0;
  g_array_append_vals (articles, &foo, 1);

  foo.product = "packages of noodles";
  foo.yummy = 50.0;
  g_array_append_vals (articles, &foo, 1);

  return articles;
}

static void
create_items_model (void)
{
  gint i = 0;
  GtkTreeIter iter;
  GArray *articles = add_items();

  /* create list store */
  model = gtk_list_store_new (NUM_ITEM_COLUMNS, G_TYPE_STRING,
                              G_TYPE_FLOAT, G_TYPE_BOOLEAN);

  /* add items */
  for (i = 0; i < articles->len; i++)
    {
      gtk_list_store_append (model, &iter);

      gtk_list_store_set (model, &iter,
                          COLUMN_ITEM_PRODUCT,
                          g_array_index (articles, Item, i).product,
                          COLUMN_ITEM_YUMMY,
                          g_array_index (articles, Item, i).yummy,
                          -1);
    }

  g_array_free (articles, TRUE);
}

static void
edited_done (GtkCellRendererText *renderer,
             gchar               *path,
             gchar               *new_text,
             gpointer             user_data)
{
  GtkTreeIter iter;
  gfloat value = g_strtod(new_text, NULL);

  if (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (model), &iter, path)) {
    gtk_list_store_set (model, &iter,
      COLUMN_ITEM_YUMMY, value, -1);
  }
}

static void
edit_started_spin_cb (GtkCellRenderer *renderer,
                       GtkCellEditable *editable,
                       gchar           *path,
                       gpointer         user_data)
{
  GtkAdjustment *adj;

  g_object_get (renderer, "adjustment", &adj, NULL);
  if (adj)
    g_object_unref (adj);

  adj = gtk_adjustment_new (0.0, 0.0, 1000.0, 0.1, 1.0, 1.0);
  g_object_set (renderer, "adjustment", adj, NULL);
}

static void
add_columns ()
{
  GtkCellRenderer *renderer;
  GtkAdjustment *adjust;

  /* product column */
  renderer = gtk_cell_renderer_text_new ();
  g_object_set_data (G_OBJECT (renderer),
        "column", GINT_TO_POINTER (COLUMN_ITEM_PRODUCT));

  gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview),
                                               -1, "Product", renderer,
                                               "text", COLUMN_ITEM_PRODUCT,
                                               NULL);

  /* yummy column */
  adjust = gtk_adjustment_new (0.0, 0.0, 1000.0, 0.1, 1.0, 1.0);
  renderer = gtk_cell_renderer_spin_new ();
  g_object_set_data (G_OBJECT (renderer), "column", GINT_TO_POINTER (COLUMN_ITEM_YUMMY));
  g_object_set (renderer,
    "editable", TRUE,
    "adjustment", adjust,
    "digits", 3,
//  "climb-rate", 0.5
    NULL);

  g_signal_connect (renderer, "edited", G_CALLBACK (edited_done), NULL);
  g_signal_connect (renderer, "editing-started", G_CALLBACK (edit_started_spin_cb), NULL);

  gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview),
                                               -1, "Yummy", renderer,
                                               "text", COLUMN_ITEM_YUMMY,
                                               NULL);
}


int main (int argc, char *argv[])
{
    GtkWidget *vbox;
    GtkWidget *hbox;
    GtkWidget *sw;
    GtkWidget *button;

    gtk_init(&argc, &argv);

   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);    // GTK_WINDOW_TOPLEVEL
   gtk_widget_set_size_request(window, 800, 600);

   gtk_window_set_resizable(GTK_WINDOW(window), TRUE);   
   gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);

    gtk_window_set_title (GTK_WINDOW (window), "Shopping list");
    gtk_container_set_border_width (GTK_CONTAINER (window), 5);
    g_signal_connect (window, "destroy",
                      G_CALLBACK (gtk_main_quit), &window);

    vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
    gtk_container_add (GTK_CONTAINER (window), vbox);

    gtk_box_pack_start (GTK_BOX (vbox),
                        gtk_label_new ("Shopping list (you can edit only SPIN-BUTTON cell !)"),
                        FALSE, FALSE, 0);

    sw = gtk_scrolled_window_new (NULL, NULL);
    gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
                                         GTK_SHADOW_ETCHED_IN);
    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
                                    GTK_POLICY_AUTOMATIC,
                                    GTK_POLICY_AUTOMATIC);
    gtk_box_pack_start (GTK_BOX (vbox), sw, TRUE, TRUE, 0);

    /* create models */
    create_items_model ();

    /* create tree view */
    treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
    gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (treeview), TRUE);
    gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)),
                                 GTK_SELECTION_SINGLE);

    add_columns ();

    gtk_container_add (GTK_CONTAINER (sw), treeview);

    /* some buttons */
    hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
    gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);

    button = gtk_button_new_with_label ("EXIT");
    g_signal_connect (button, "clicked", G_CALLBACK(gtk_main_quit), NULL);
    gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);

  gtk_widget_show_all(window);
  gtk_main ();

  return 0;
}


First I removed the deprecated use of code. These were gtk_hbox_new() and gtk_vbox_new() and replced them with gtk_box_new().

You were using the wrong signals for your original code. The signals that you should have used are "edited" and "editing-started".

The call back function for the signal "editing-started" is call before the editing is started and the GtkSpinButton is displayed. This function removes the old GtkAdjustment from the cell renderer and replaces it with a new one. Without doing this every time the user edits a GtkCellRendererSpin field more signals are added to the GtkAdjustment, and when the value changes all the signals are called including the old ones with invalid data.

The call back function for the signal "edited" is call once all editing has completed. All this function has to do is get the new data and insert it into the correct place in the tree view model.

I have also tided up the code is various places.

Hopefully the code is easier to read although still not perfect. There is still rounding errors, this is partly due to the different precision that is used for displaying the values and for working with the values in the GtkSpinButton.

I shall leave this as an exercise to improve the displaying of the values in the tree view. As a hint the function that you need is gtk_tree_view_column_set_cell_data_func () and the property to set is "text".

Hope this is of help.

_________________
E.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 18 posts ]  Go to page Previous  1, 2

All times are UTC


Who is online

Users browsing this forum: Google [Bot] and 3 guests


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

Search for:
Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group