簡體   English   中英

來自Gtk.Entry的插入文本信號的Gtk 3位置屬性始終為0

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM