[英]Gtk 3 position attribute on insert-text signal from Gtk.Entry is always 0
我在管理Gtk.Entry小部件發出的插入文本信號時遇到了麻煩。 請考慮以下示例:
from gi.repository import Gtk
def on_insert_text(entry, new_text, new_text_length, position):
print(position)
entry = Gtk.Entry()
entry.connect('insert-text', on_insert_text)
window = Gtk.Window()
window.connect("destroy", lambda q: Gtk.main_quit())
window.add(entry)
window.show_all()
Gtk.main()
我在信號處理程序上收到的位置屬性總是為0.除非我誤解了這應該是不應該插入下一個文本的位置?
最后我想要做的是驗證小部件中文本的輸入以限制將被接受的字符。 我計划這樣做的方式類似於文檔中提供的示例,其中所有字符都轉換為大寫。
“insert-text”的處理程序應該更新position參數(我們在不正確的情況下看到)中收到的值,以反映應該插入未來文本的位置並將其返回。 這很重要,因此在信號處理程序返回后光標會更改到正確的位置(這由gtk
完成)。 如果不更新並返回,則光標保持在位置0。
在遵循使用entry.get_position()
獲取正確位置值的建議之后,我發現pygobject
正在忽略我的處理程序中的更新和返回位置。 它表現得好像我沒有返回任何東西(光標保持在位置0)。 設置處理程序內的位置沒有幫助,因為gtk
會在處理程序返回后將其再次更改為0。
在進行了一些進一步的調查之后,我了解到問題在於pygobject
中輸入/輸出參數的處理,這在大多數情況下效果很好但不能用於信號(參見bug 644927 )
如果使用connect將處理程序附加到信號並且信號具有輸入/輸出參數,則可能無法在處理程序中收到您期望的內容,即使您返回值, pygobject
也可能無法正確處理此值。 依賴於該值的任何內容都可能無法按預期工作(例如,將光標前進到新位置)
有一個解決方案是覆蓋關聯的vfunc(默認處理程序)而不是連接connect()
。 這個解決方案意味着從基類派生但它確實有效。
您可以在Gtk.Entry
上使用此方法進行輸入驗證/轉換。 處理我的用例的一個例子是:
import re
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
class MyEntry(Gtk.Entry, Gtk.Editable):
def __init__(self):
super(MyEntry, self).__init__()
def do_insert_text(self, new_text, length, position):
regexp = re.compile('^(\d*\.?\d*)$')
if new_text == '.' and '.' in self.get_text():
return position
elif regexp.match(new_text) is not None:
self.get_buffer().insert_text(position, new_text, length)
return position + length
return position
entry = MyEntry()
window = Gtk.Window()
window.connect("destroy", lambda q: Gtk.main_quit())
window.add(entry)
window.show_all()
Gtk.main()
在這種情況下,正確接收位置參數,並且pygobject可以看到並使用返回值,因此光標位置正確。
重要說明除了Gtk.Entry之外,您還必須繼承Gtk.Editable。 如果您不這樣做,您將開始看到驗證或您在do_insert_text
執行的任何操作, do_insert_text
應用程序中的每個其他Gtk.Entry
。 如果您不繼承,則覆蓋Gtk.Editable提供的基本實現,該實現由應用程序中的所有其他Gtk.Entry
小部件調用。 通過繼承自Gtk.Editable,您只覆蓋僅適用於您的自定義類的基本實現的“本地”副本。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.