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

Reply via email to