Short question: It this me, or should I file a bug agains pygtk? Using: pygtk-1.99.8 gtk+ 2.0.0-3 (debian package)
I have a small C program (spins.c and Makefile attached) that connect to the input/output signal of a spin button to display month names instead of numbers. This is taken from testgtk.c from gtk+ 2.0 and works ok. My port to python (attached spin.py) has the problem that after spinning the button up once and then let the window loose focus, the output-callback get called, but the value is corrupted and spinner.get_value() returns 6.487572 or 6.487575. (Always one of those two values. The attached spin-bug-workaround.py is the simplest workaround I have found. Anyone care to compile the program and test it to see if this is a local problem? -- Tom Cato Amundsen <[EMAIL PROTECTED]> GNU Solfege - free eartraining, http://www.gnu.org/software/solfege/
all: spins clean: rm -f spins CC=gcc `pkg-config gtk+-2.0 --cflags --libs` spins: spins.c $(CC) -g -o spins spins.c
#!/usr/bin/python2.2 import sys, re sys.path.insert(0, "/home/tom/pygtk2/lib/python2.2/site-packages") import gtk, gtk, pango # This was not defined in gtk-types.defs yet INPUT_ERROR=-1 months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"] xval = 0.0 def spin_button_month_input_func(spin, cob): print "input:", spin.get_value(), " ", if spin.get_text() in months: print "Found, returning true" return gtk.TRUE else: print "Not found, returning INPUT_ERROR" return INPUT_ERROR def spin_button_month_output_func(spin): global xval if spin.get_value()-int(spin.get_value()) > 0.1: spin.set_value(xval) return gtk.TRUE print "output %f text:%s" % (spin.get_value(), spin.get_text()), if spin.get_text() != months[spin.get_value_as_int()-1]: print "Setting (oldval: %s " % spin.get_text(), spin.set_text(months[int(spin.get_value())-1]) xval = spin.get_value_as_int() print "newval: %s)" % spin.get_text() else: print return gtk.TRUE window = gtk.Window(gtk.WINDOW_TOPLEVEL) window.show() adj = gtk.Adjustment(1.0, 1.0, 12.0, 1.0, 5.0, 0.0) spinner = gtk.SpinButton(adj, 0, 0) spinner.set_update_policy(gtk.UPDATE_IF_VALID) spinner.connect('input', spin_button_month_input_func) spinner.connect('output', spin_button_month_output_func) spinner.set_size_request(85, -1) window.add(spinner) window.show_all() window.connect('destroy', gtk.mainquit) gtk.mainloop()
#!/usr/bin/python2.2 import sys, re sys.path.insert(0, "/home/tom/pygtk2/lib/python2.2/site-packages") import gtk, gtk, pango # This was not defined in gtk-types.defs yet INPUT_ERROR=-1 months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"] def spin_button_month_input_func(spin, cob): print "input:", spin.get_value(), " ", if spin.get_text() in months: print "Found, returning true" return gtk.TRUE else: print "Not found, returning INPUT_ERROR" return INPUT_ERROR def spin_button_month_output_func(spin): print "output %f text:%s" % (spin.get_value(), spin.get_text()), if spin.get_text() != months[spin.get_value_as_int()-1]: print "Setting (oldval: %s " % spin.get_text(), spin.set_text(months[int(spin.get_value())-1]) print "newval: %s)" % spin.get_text() else: print return gtk.TRUE window = gtk.Window(gtk.WINDOW_TOPLEVEL) window.show() adj = gtk.Adjustment(1.0, 1.0, 12.0, 1.0, 5.0, 0.0) spinner = gtk.SpinButton(adj, 0, 0) spinner.set_update_policy(gtk.UPDATE_IF_VALID) spinner.connect('input', spin_button_month_input_func) spinner.connect('output', spin_button_month_output_func) spinner.set_size_request(85, -1) window.add(spinner) window.show_all() window.connect('destroy', gtk.mainquit) gtk.mainloop()
/* * Taken from testgtk.c from gtk+ 2.0 */ #include <gtk/gtk.h> #include <string.h> #include <math.h> gint spin_button_month_input_func (GtkSpinButton *spin_button, gdouble *new_val) { gint i; static gchar *month[12] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; gchar *tmp1, *tmp2; gboolean found = FALSE; printf("input %f ", gtk_spin_button_get_value(spin_button)); for (i = 1; i <= 12; i++) { tmp1 = g_strdup (month[i-1]); g_strup (tmp1); tmp2 = g_strdup (gtk_entry_get_text (GTK_ENTRY (spin_button))); g_strup (tmp2); if (strstr (tmp1, tmp2) == tmp1) { found = TRUE; } g_free (tmp1); g_free (tmp2); if (found) break; } if (!found) { // seems to be unnecessary // *new_val = 0.0; printf("Not found, returning INPUT_ERROR\n"); return GTK_INPUT_ERROR; } // seems to be unnecessary // *new_val = (gdouble) i; printf("Found, returning TRUE\n"); return TRUE; } gint spin_button_month_output_func (GtkSpinButton *spin_button) { gint i; static gchar *month[12] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; printf("output %f text:%s, ", gtk_spin_button_get_value(spin_button), gtk_entry_get_text(spin_button)); for (i = 1; i <= 12; i++) if (fabs (spin_button->adjustment->value - (double)i) < 1e-5) { if (strcmp (month[i-1], gtk_entry_get_text (GTK_ENTRY (spin_button)))) { printf("Setting (oldval: %s ", gtk_entry_get_text(spin_button)); gtk_entry_set_text (GTK_ENTRY (spin_button), month[i-1]); printf("newval: %s)", gtk_entry_get_text(spin_button)); } } printf("\n"); return TRUE; } int main(int argc, char *argv[]) { static GtkWidget *window = NULL; GtkWidget *spinner; GtkAdjustment *adj; gtk_init(&argc, &argv); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_signal_connect (GTK_OBJECT (window), "destroy", GTK_SIGNAL_FUNC (gtk_main_quit), //GTK_SIGNAL_FUNC (gtk_widget_destroyed), &window); gtk_widget_show(GTK_WIDGET(window)); /***********************/ adj = (GtkAdjustment *) gtk_adjustment_new(1.0, 1.0, 12.0, 1.0, 5.0, 0.0); spinner = gtk_spin_button_new(adj, 0, 0); gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (spinner), GTK_UPDATE_IF_VALID); gtk_signal_connect (GTK_OBJECT (spinner), "input", GTK_SIGNAL_FUNC (spin_button_month_input_func), NULL); gtk_signal_connect (GTK_OBJECT (spinner), "output", GTK_SIGNAL_FUNC (spin_button_month_output_func), NULL); gtk_widget_set_usize (spinner, 85, -1); gtk_container_add( GTK_CONTAINER(window), spinner); gtk_widget_show_all( GTK_WIDGET(window)); gtk_main(); return 0; }