2012-01-29 4 views
1

私はPyGTKからPyGObjectにアプリケーションを移植しています。主にPyGTKで従来のことをしていたので、うまくいっています。しかし、SpinButtonの値を通貨として表示するために私が使用していたやや醜いハックがあります(その前に$が付いています)。PyGObject/GTK + 3でのスピンボタンの表示のフォーマット

私はもともとStack Overflowの前日にthe PyGTK mailing listからこのソリューションを手に入れました。あなたが見ることができるように、魔法が入力信号と出力信号に起こる:

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

残念ながら、これは動作しません:

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にそれを翻訳するために私の最善を尽くして、私が思い付きました。最初はうまく表示されますが、上または下のエラーをクリックするとクラッシュして表示されます。

/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の内容の前に$を表示)に対するより簡単な解決方法はありますか?私はPyGtkドキュメントから

+2

みなします。私にはPyGObjectのバグのように見えます(ただし、ctypesを使用する必要があるという事実はIMHO自体のバグです)。 –

答えて

2

:値が変化したとき

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

"入力" 信号が発せられます。 value_ptrは、PyGTKからアクセスできない値へのGPointerです。 この信号はPyGTKでは処理できません。

だから、私のような何かを見るためにatonishedだ:

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

あなたが持って、ひどいエラー「セグメンテーション違反」あなたは、あなたが持っていないメモリにいじりされていることを意味するので、これは、実際のハックですこれは非常に一般的です。たとえば、Cでアプリケーションが処理しないメモリポインタに手動でアクセスしようとしたときです。

これは難しいことですが、私は1時間試してみましたが、試みたすべてのアプローチに問題がありました。

enter image description here

:私は、答えはありませんが、回避策として、あなたが唯一の継承Gtk.Entry set_icon_from_pixbuf()に通貨記号の画像を追加し、あなたが試すことができます(グループ化ではない)通貨記号を必要とするかどうかを知ります

(明らか通貨画像に画像を設定する)

種類は問題が `double.value = ...`ラインで発生

+1

参考までに、これに関するpygobjectのバグは次のとおりです:https://bugzilla.gnome.org/show_bug.cgi?id=644927 –

関連する問題