1

私は、アプリケーションを PyGTK から PyGObject に移植中です。ほとんどはPyGTKで従来のことをやったので、ほとんどうまくいっています。しかし、SpinButton の値を通貨 (前に $ を付けて) として表示するために使用していた、やや醜いハックが 1 つあります。

このソリューションは、スタック オーバーフローの数日前に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 コンテンツの前に $ を表示する) に対するより簡単な解決策はありますか?

4

2 に答える 2

2

PyGtk ドキュメントから:

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

値が変更されると、「入力」シグナルが発行されます。value_ptr は、PyGTK からアクセスできない値への GPointer です。このシグナルは PyGTK では処理できません

だから、私は次のようなものを見て憤慨しています:

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

これは本当のハックなので、「Segmentation Fault」というひどいエラーが発生します。これは、必要のないメモリをいじっていることを意味します。これは非常に一般的です。たとえば、C でメモリ ポインタに手動でアクセスしようとすると発生します。アプリケーションでは処理されません。

これは難しいものになるでしょう。私は 1 時間試しましたが、試したすべてのアプローチに問題がありました。私はそうではないことを知っていますが、回避策として、(グループ化ではなく) 通貨記号のみが必要な場合は、継承された Gtk.Entry set_icon_from_pixbuf()に通貨記号の画像を追加して試すことができます:

ここに画像の説明を入力

(もちろん画像は通貨画像に設定)

敬具

于 2012-05-10T07:24:15.963 に答える