在 PyGObject/GTK+3 中格式化旋转按钮的显示

发布于 2024-12-29 17:34:08 字数 2618 浏览 2 评论 0原文

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

我最初是从 PyGTK 邮件列表 得到这个解决方案的在 Stack Overflow 之前的日子里。正如您所看到的,神奇的事情发生在输入和输出信号上:

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 内容前面显示 $)?

I'm in the process of porting an application from PyGTK to PyGObject. Mostly it's going well because mostly I did conventional things with PyGTK. But there's one somewhat ugly hack I was using to display the value of a SpinButton as currency (with a $ in front of it).

I originally got this solution from the PyGTK mailing list back in the days before Stack Overflow. As you can see, the magic happens on the input and output signals:

import gtk, ctypes

def _currency_input(spinbutton, gpointer):
    text = spinbutton.get_text()
    if text.startswith('

Doing my best to translate that into PyGObject, I came up with:

from gi.repository import Gtk
import ctypes

def _currency_input(spinbutton, gpointer):
    text = spinbutton.get_text()
    if text.startswith('

Unfortunately, this doesn't work. It shows up fine initially, but when I click the up or down error, it crashes and I see:

/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

Any idea what this error message means?

Or what part of my code might not work under PyGObject?

Or, better yet, how to fix this error?

Or, even better still, a more straightforward solution to my original problem (displaying a $ in front of the SpinButton contents)?

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

Doing my best to translate that into PyGObject, I came up with:


Unfortunately, this doesn't work. It shows up fine initially, but when I click the up or down error, it crashes and I see:


Any idea what this error message means?

Or what part of my code might not work under PyGObject?

Or, better yet, how to fix this error?

Or, even better still, a more straightforward solution to my original problem (displaying a $ in front of the SpinButton contents)?

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

Unfortunately, this doesn't work. It shows up fine initially, but when I click the up or down error, it crashes and I see:

Any idea what this error message means?

Or what part of my code might not work under PyGObject?

Or, better yet, how to fix this error?

Or, even better still, a more straightforward solution to my original problem (displaying a $ in front of the SpinButton contents)?

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

Doing my best to translate that into PyGObject, I came up with:

Unfortunately, this doesn't work. It shows up fine initially, but when I click the up or down error, it crashes and I see:

Any idea what this error message means?

Or what part of my code might not work under PyGObject?

Or, better yet, how to fix this error?

Or, even better still, a more straightforward solution to my original problem (displaying a $ in front of the SpinButton contents)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

薄荷港 2025-01-05 17:34:08

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

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

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

在此处输入图像描述

(显然将图像设置为货币图像)

亲切的问候

From the PyGtk documentation:

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

The "input" signal is emitted when the value changes. The value_ptr is a GPointer to the value that cannot be accessed from PyGTK. This signal cannot be handled in PyGTK.

So, I'm atonished to see something like:

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

This is a real hack, so you got and awful error "Segmentation Fault" which means your are messing in memory you don't have to, and it's quite generic, it happens for example when in C you try to manually access a memory pointer not handled by your application.

This will be a hard one, I tried for one hour and all approaches I tried had problems. I know is not and answer, but as a workaround and if you only need the currency symbol (not grouping) you can experiment adding a currency symbol image to the inherited Gtk.Entry set_icon_from_pixbuf():

enter image description here

(Obviously set the image to a currency image)

Kind regards

倾城泪 2025-01-05 17:34:08

或者,更好的是,对我原来的问题有一个更直接的解决方案(在 SpinButton 内容前面显示 $)?

我通过将 GTKSpinButton 的 output 信号连接到一个简单的处理程序来实现此功能:

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

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

Or, even better still, a more straightforward solution to my original problem (displaying a $ in front of the SpinButton contents)?

I got this working by hooking up the GTKSpinButton's output signal to a simple handler:

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

In my case I'm adding a percentage sign after the number, but you can easily change this to insert something else in front instead. Note that this sets the text and not the value of the entry; this will not work for numerical spin buttons.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文