Python gtk.Entry中的"preedit-changed"事件无效

1 投票
1 回答
1429 浏览
提问于 2025-04-27 21:43

我想让我的 gtk.Entry 只接受数字。一开始我试着在事件发生时在我的标准输出中打印一些东西,但当我运行我的脚本时,在我输入内容到 gtk.Entry 时什么也没有发生(我使用的是pygtk 2.24,python 2.7.2,Windows XP,我在Linux上运行相同的代码,结果也是一样)。我的代码可能有什么问题呢?

import gtk

class UI:
    def delete_event(self, widget, event, data=None):
        return False

    def destroy(self, widget, data=None):
        gtk.main_quit()

    def preedit_changed(self, widget, preedit, data=None):
        print "preedit_changed"
        return True

    def __init__(self):
        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.window.connect("delete_event", self.delete_event)
        self.window.connect("destroy", self.destroy)
        self.window.set_border_width(5)
        self.entry = gtk.Entry()
        self.entry.connect("preedit-changed", self.preedit_changed)
        self.window.add(self.entry)
        self.window.show_all()
        gtk.main()

if __name__ == "__main__":
    ui = UI()
暂无标签

1 个回答

3

我之前不知道这个信号(我习惯参考我电脑上比较旧的GTK+文档),但看起来它并不是你想的那样。

在查阅了Gnome的文档后,我发现“preedit-changed”这个信号是用来处理那些需要多次按键输入的字符,比如大多数键盘上的带重音的字母,还有像™这样的符号。在Linux系统中,输入这些符号需要用到一个叫Compose的键:比如输入™就要按Compose键,然后再按t和m。所以如果你在输入框中输入了这些多键字符,你就会收到一个“preedit_changed”的信号。不过在我的实验中,preedit返回的总是一个空字符串……

不过你可以用传统的“changed”信号来实现你想要的功能。我对你的代码做了一些修改,给出了一个简单的例子,只处理数字,但扩展到处理+-.也很简单;如果要处理科学计数法的数字,就需要用不同的方法了。

#! /usr/bin/env python

import pygtk
pygtk.require('2.0')
import gtk

class UI:
    def delete_event(self, widget, event):
        return False

    def destroy(self, widget):
        gtk.main_quit()

    def preedit_changed(self, widget, preedit):
        value = widget.get_text()
        print "preedit_changed: '%s', preedit: '%s'" % (value, preedit)
        return True

    def activated(self, widget):
        value = widget.get_text()
        print "activated: '%s'" % value
        return True

    def changed(self, widget):
        value = widget.get_text()
        print "changed: '%s'" % value
        return True

    def digits_only(self, widget):
        value = widget.get_text()
        #Remove non-digits from string
        value = ''.join([c for c in value if c.isdigit()]) 
        widget.set_text(value)
        return True

    def __init__(self):
        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.window.connect("delete_event", self.delete_event)
        self.window.connect("destroy", self.destroy)
        self.window.set_border_width(5)

        self.entry = gtk.Entry()
        self.entry.connect("activate", self.activated)
        #self.entry.connect("changed", self.changed)
        self.entry.connect("changed", self.digits_only)
        self.entry.connect("preedit_changed", self.preedit_changed)
        self.window.add(self.entry)
        self.window.show_all()
        gtk.main()

if __name__ == "__main__":
    ui = UI()        

撰写回答