如何格式化Gtk.Entry中的条目
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()
更多相关文章
- scikit-learn:在标记化时不要分隔带连字符的单词
- 你怎么检查python字符串是否只包含数字?
- Python - 去除字符串首尾填充
- python - pandas或者sklearn中如何将字符形式的标签数字化
- Python处理字符串
- python list range 字符串的截取 如 text[1:5]
- python的list要打印中文字符
- Python——字符格式化
- 在Python中使用正则表达式匹配的字符串周围添加括号