Я в процессе переноса приложения из PyGTK в PyGObject. В основном все идет хорошо, потому что в основном я делал обычные вещи с PyGTK. Но есть один уродливый хак, который я использовал, чтобы отобразить значение SpinButton в качестве валюты (с $ перед ним).
Изначально я получил это решение из списка рассылки PyGTK еще за несколько дней до переполнения стека. Как видите, волшебство происходит на входных и выходных сигналах:
import gtk, ctypes
def _currency_input(spinbutton, gpointer):
text = spinbutton.get_text()
if text.startswith('$'):
text = text[1:]
double = ctypes.c_double.from_address(hash(gpointer))
double.value = float(text)
return True
def _currency_output(spinbutton):
text = '$%.*f' % (int(spinbutton.props.digits),
spinbutton.props.adjustment.value)
spinbutton.set_text(text)
return True
def format_spinbutton_currency(spinbutton):
spinbutton.connect('input', _currency_input)
spinbutton.connect('output', _currency_output)
def _test():
s = gtk.SpinButton(gtk.Adjustment(value=1, lower=0, upper=1000,
step_incr=1))
s.props.digits = 2
format_spinbutton_currency(s)
w = gtk.Window()
w.props.border_width = 12
w.add(s)
w.show_all()
w.connect('destroy', gtk.main_quit)
gtk.main()
if __name__ == '__main__':
_test()
Делая все возможное, чтобы перевести это на PyGObject, я придумал:
from gi.repository import Gtk
import ctypes
def _currency_input(spinbutton, gpointer):
text = spinbutton.get_text()
if text.startswith('$'):
text = text[1:]
double = ctypes.c_double.from_address(hash(gpointer))
double.value = float(text)
return True
def _currency_output(spinbutton):
text = '$%.*f' % (int(spinbutton.props.digits),
spinbutton.get_value())
spinbutton.set_text(text)
return True
def format_spinbutton_currency(spinbutton):
spinbutton.connect('input', _currency_input)
spinbutton.connect('output', _currency_output)
def _test():
s = Gtk.SpinButton()
s.set_adjustment(Gtk.Adjustment(value=1, lower=0, upper=1000,
step_increment=1))
s.props.digits = 2
format_spinbutton_currency(s)
w = Gtk.Window()
w.props.border_width = 12
w.add(s)
w.show_all()
w.connect('destroy', Gtk.main_quit)
Gtk.main()
if __name__ == '__main__':
_test()
К сожалению, это не работает. Сначала он хорошо отображается, но когда я нажимаю на ошибку вверх или вниз, происходит сбой, и я вижу:
/usr/lib/python2.7/dist-packages/gi/types.py:43: Warning: g_value_get_double: assertion `G_VALUE_HOLDS_DOUBLE (value)' failed
return info.invoke(*args, **kwargs)
Segmentation fault
Есть идеи, что означает это сообщение об ошибке?
Или какая часть моего кода может не работать под PyGObject?
Или, еще лучше, как исправить эту ошибку?
Или, что еще лучше, более простое решение моей первоначальной проблемы (отображение $ перед содержимым SpinButton)?