For example, the telephone format is +999 99 9999-9999. That is, the GtkEntry automatically add the characters (+,[space] and -) as the user types.

例如,电话格式是+999 9999-9999。也就是说,GtkEntry会自动添加字符(+、[空格]和-)作为用户类型。

1 个解决方案

#1


11

1. How to make an entry validator?

In order to do an entry validator in gtk, you need to connect the insert_text signal to a validation method. It goes like so:

为了在gtk中执行输入验证器,需要将insert_text信号连接到验证方法。它是这样的:

class EntryWithValidation(Gtk.Entry):
    """A Gtk.Entry with validation code"""

    def __init__(self):
        Gtk.Entry.__init__(self)
        self.connect("insert_text", self.entryInsert)

    def entryInsert(self, entry, text, length, position):
        # Called when the user inserts some text, by typing or pasting.

        # The `position` argument is not working as expected in Python
        pos = entry.get_position() 

        # Your validation code goes here, outputs are new_text and new_position (cursor)

        if new_text:
            # Set the new text (and block the handler to avoid recursion).
            entry.handler_block_by_func(self.entryInsert)
            entry.set_text(new_text)
            entry.handler_unblock_by_func(self.entryInsert)

            # Can't modify the cursor position from within this handler,
            # so we add it to be done at the end of the main loop:
            GObject.idle_add(entry.set_position, new_pos)

        # We handled the signal so stop it from being processed further.
        entry.stop_emission("insert_text")

This code will generate a warning: Warning: g_value_get_int: assertion 'G_VALUE_HOLDS_INT (value)' failed Gtk.main() because of the incapacity of handling return arguments in the Python bindings of Gtk signals. This question gives details about the bug. As suggested in the accepted answer, you can override the default signal handler like so:

此代码将生成一个警告:警告:g_value_get_int:断言'G_VALUE_HOLDS_INT (value)'失败的Gtk.main(),因为在Gtk信号的Python绑定中处理返回参数的能力不足。这个问题提供了有关这个错误的细节。正如在已接受的答案中所建议的,您可以这样覆盖默认信号处理程序:

class EntryWithValidation(Gtk.Entry, Gtk.Editable):

    def __init__(self):
        super(MyEntry, self).__init__()

    def do_insert_text(self, new_text, length, position):

        # Your validation code goes here, outputs are new_text and new_position (cursor)

        if new_text:
            self.set_text(new_text)
            return new_position
        else:
            return position

2.The validation code

You now need to write the validation code. It is a bit fiddly since we need to place the cursor at the end of the inserted text but we may have added some extra characters while formatting.

现在需要编写验证代码。这有点麻烦,因为我们需要将光标放在插入文本的末尾,但是在格式化时我们可能添加了一些额外的字符。

import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GObject

class TelNumberEntry(Gtk.Entry):
    """A Gtk.Entry field for phone numbers"""

    def __init__(self):
        Gtk.Entry.__init__(self)
        self.connect("insert_text", self.entryInsert)

    def entryInsert(self, entry, text, length, position):

        pos = entry.get_position() 
        old_text = entry.get_text()

        # Format entry text

        # First we filter digits in insertion text
        ins_dig = ''.join([c for c in text if c.isdigit()]) 
        # Second we insert digits at pos, truncate extra-digits
        new_text = ''.join([old_text[:pos], ins_dig, old_text[pos:]])[:17] 
        # Third we filter digits in `new_text`, fill the rest with underscores
        new_dig = ''.join([c for c in new_text if c.isdigit()]).ljust(13, '_')
        # We are ready to format 
        new_text = '+{0} {1} {2}-{3}'.format(new_dig[:3], new_dig[3:5], 
                                               new_dig[5:9], new_dig[9:13]).split('_')[0] 

        # Find the new cursor position

        # We get the number of inserted digits
        n_dig_ins = len(ins_dig) 
        # We get the number of digits before
        n_dig_before = len([c for c in old_text[:pos] if c.isdigit()])
        # We get the unadjusted cursor position
        new_pos = pos + n_dig_ins

        # If there was no text in the entry, we added a '+' sign, therefore move cursor
        new_pos += 1 if not old_text else 0 
        # Spacers are before digits 4, 6 and 10
        for i in [4, 6, 10]:
            # Is there spacers in the inserted text?
            if n_dig_before < i <= n_dig_before + n_dig_ins: 
                # If so move cursor
                new_pos += 1

        if new_text:
            entry.handler_block_by_func(self.entryInsert)
            entry.set_text(new_text)
            entry.handler_unblock_by_func(self.entryInsert)

            GObject.idle_add(entry.set_position, new_pos)

        entry.stop_emission("insert_text")

if __name__ == "__main__":
    window = Gtk.Window()
    window.connect("delete-event", Gtk.main_quit)
    entry = TelNumberEntry()
    window.add(entry)
    window.show_all()
    Gtk.main()

更多相关文章

  1. scikit-learn:在标记化时不要分隔带连字符的单词
  2. 你怎么检查python字符串是否只包含数字?
  3. Python - 去除字符串首尾填充
  4. python - pandas或者sklearn中如何将字符形式的标签数字化
  5. Python处理字符串
  6. python list range 字符串的截取 如 text[1:5]
  7. python的list要打印中文字符
  8. Python——字符格式化
  9. 在Python中使用正则表达式匹配的字符串周围添加括号

随机推荐

  1. 如果没有匹配,则使用默认值执行左连接。
  2. mysql非安装包安装教程
  3. 解决Navicat数据传输问题:The‘InnoDB’f
  4. 如何在codeigniter上的一个提交中插入多
  5. Mysql数据库四大特性、事物的四个隔离、
  6. solr6.3与MySQL结合使用的简明教程(五)——
  7. mysql 判断null 和 空字符串
  8. 通过Bash脚本语言逃避MYSQL命令行。
  9. 如何创建一个新表,该表根据名称获取其他表
  10. 错误1452:无法添加或更新子行:外键约束失败