2012-01-29 4 views
1

Я в настоящее время переношу приложение из PyGTK в PyGObject. В основном это происходит хорошо, потому что в основном я делал обычные вещи с PyGTK. Но есть один уродливый хак, который я использовал, чтобы отобразить значение SpinButton как валюты (с $ перед ним).Форматирование дисплея спинбаута в PyGObject/GTK + 3

Первоначально Я получил это решение от the PyGTK mailing list еще в прошлые дни перед переполнением стека. Как вы можете видеть, волшебство происходит на входных и выходных сигналов:

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)?

+2

проблема происходит в 'double.value = ...' линии. Похож на ошибку PyGObject для меня (хотя тот факт, что нам нужно использовать ctypes, является самой ошибкой, IMHO). –

ответ

2

Из документации PyGtk:

http://developer.gnome.org/pygtk/stable/class-gtkspinbutton.html#signal-gtkspinbutton--input

Сигнал "вход" испускается при изменении значения. Значение_ptr является GPointer для значения, которое невозможно получить из PyGTK. Этот сигнал не может обрабатываться в PyGTK.

Итак, я atonished, чтобы увидеть что-то вроде:

double = ctypes.c_double.from_address(hash(gpointer)) 

Это настоящий хак, так что вы получили и ужасная ошибка «Segmentation Fault», что означает, что ваши будут баловаться в памяти у вас нет к, и это довольно общее, это происходит, например, когда в C вы пытаетесь вручную получить доступ к указателю памяти, который не обрабатывается вашим приложением.

Это будет сложно, я пробовал в течение одного часа, и все подходы, которые я пытался, имели проблемы. Я знаю, что это не так и ответ, но как временное решение, и если вам нужно только символ валюты (не группировка), вы можете экспериментировать, добавив символ валюты изображения в унаследованной Gtk.Entry set_icon_from_pixbuf():

enter image description here

(Очевидно установить изображение в валюте изображения)

Сердечные приветы

+1

Для справки, вот ошибка pygobject об этом: https://bugzilla.gnome.org/show_bug.cgi?id=644927 –

Смежные вопросы