Я занимаюсь переносом приложения с 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)?
double.value = ...
. Для меня это похоже на ошибку PyGObject (хотя тот факт, что нам нужно использовать ctypes, сам по себе является ошибкой, ИМХО). - person Johannes Sasongko   schedule 29.01.2012