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;
}