Форматирование отображения спин-кнопки в PyGObject / GTK + 3 - PullRequest
1 голос
/ 29 января 2012

Я в процессе переноса приложения из 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)?

1 Ответ

2 голосов
/ 10 мая 2012

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

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

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

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

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

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

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

enter image description here

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

С уважением

...