【问题标题】:Formatting a spinbutton's display in PyGObject/GTK+3在 PyGObject/GTK+3 中格式化旋转按钮的显示
【发布时间】:2012-01-29 05:28:13
【问题描述】:

我正在将应用程序从 PyGTK 移植到 PyGObject。大多数情况下它进展顺利,因为大多数情况下我用 PyGTK 做了常规的事情。但是我使用了一个有点丑陋的 hack 来将 SpinButton 的值显示为货币(前面有一个 $)。

在 Stack Overflow 之前的日子里,我最初是从 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 内容前显示 $)?

【问题讨论】:

  • 问题发生在double.value = ... 行。对我来说看起来像一个 PyGObject 错误(尽管我们需要使用 ctypes 本身就是一个错误,恕我直言)。

标签: python gtk pygtk gtk3 pygobject


【解决方案1】:

来自 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))

这是一个真正的 hack,所以你得到了一个可怕的错误“Segmentation Fault”,这意味着你在内存中弄乱了你不必这样做,而且它非常通用,例如当你在 C 中尝试手动访问时就会发生这种情况您的应用程序未处理的内存指针。

这将是一个艰难的过程,我尝试了一个小时,我尝试的所有方法都有问题。我知道不是和答案,但作为一种解决方法,如果您只需要货币符号(而不是分组),您可以尝试将货币符号图像添加到继承的 Gtk.Entry set_icon_from_pixbuf():: p>

(显然是把图片设置为货币图片)

亲切的问候

【讨论】:

【解决方案2】:

或者,更好的是,更直接地解决我原来的问题(在 SpinButton 内容前显示 $)?

我通过将 GTKSpinButton 的 output 信号连接到一个简单的处理程序来完成这项工作:

    def onSpinOutput(self, spinbutton):
      adjustment = spinbutton.get_adjustment()
      spinbutton.set_text(str(int(adjustment.get_value())) + "%")
      return True

在我的例子中,我在数字之后添加了一个百分号,但您可以轻松地更改它以在前面插入其他内容。请注意,这会设置条目的 text 而不是 value;这不适用于数字旋转按钮。

【讨论】:

    猜你喜欢
    • 2012-07-20
    • 2022-01-07
    • 1970-01-01
    • 2012-06-17
    • 1970-01-01
    • 2019-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多