1 回答

TA貢獻(xiàn)1859條經(jīng)驗(yàn) 獲得超6個(gè)贊
您有兩個(gè)問(wèn)題,都與您的類依賴于全局?jǐn)?shù)據(jù)這一事實(shí)有關(guān):您正在使用bind_all它有效地創(chuàng)建全局綁定,并且您對(duì)普通和占位符使用相同的樣式,但樣式是全局的。
第一個(gè)問(wèn)題是您對(duì)bind_all. 每次創(chuàng)建實(shí)例時(shí),bind_all該實(shí)例的綁定都會(huì)替換前一個(gè)實(shí)例的綁定。兩個(gè)實(shí)例都將繼承一個(gè)綁定,該綁定僅調(diào)用最后創(chuàng)建的實(shí)例的_normal和方法。_cursor
作為一般經(jīng)驗(yàn)法則,像這樣的類應(yīng)該始終只在其自身上創(chuàng)建綁定。您需要更改self.bind_all為僅self.bind.
self.bind('<Key>', self._normal)
self.bind('<Button-1>', self._cursor)
第二個(gè)問(wèn)題是您對(duì)樣式的使用。您在兩種狀態(tài)下的兩個(gè)小部件都使用單一樣式,但由于樣式是全局的,因此當(dāng)您更改一個(gè)小部件中的樣式時(shí),它會(huì)影響另一個(gè)小部件。
您不應(yīng)該重新配置單一樣式,而應(yīng)該配置兩種樣式并在它們之間切換。例如,您可以my.TEntry為正常情況創(chuàng)建一個(gè)樣式,并placeholder.TEntry為您想要顯示占位符時(shí)創(chuàng)建一個(gè)樣式。
首先在方法中配置樣式__init__:
def __init__(self, master, placeholder, **kwargs):
? ? # style for ttk widget
? ? self.s = ttk.Style()
? ? self.s.configure('my.TEntry', foreground='black', font=(0, 0, 'normal'))
? ? self.s.configure('placeholder.TEntry', foreground='grey', font=(0, 0, 'bold'))
接下來(lái),無(wú)需重新配置樣式定義,只需交換小部件上的樣式即可。例如,_clear看起來(lái)像這樣:
def _clear(self, *args):? # method to remove the placeholder
? ? if self.get() == self.text and self.__has_placeholder:??
? ? ? ? self.configure(style="my.TEntry")
? ? ? ? ...
同樣,_add應(yīng)該看起來(lái)像這樣:
def _add(self, *args):? # method to add placeholder
? ? if self.get() == '' and not self.__has_placeholder:? # if no text add placeholder
? ? ? ? self.configure(style="placeholder.TEntry")
? ? ? ? ...
最后,您的邏輯有一個(gè)錯(cuò)誤,可能是由于誤解了綁定的工作原理。當(dāng)您綁定到 時(shí)<Key>,該綁定發(fā)生在默認(rèn)綁定之前。因此,您檢查條目self._add是否為空的位置發(fā)生在插入您剛剛鍵入的密鑰之前。因此,代碼認(rèn)為條目小部件是空的,并將樣式切換為具有占位符。因此,它添加占位符文本,然后發(fā)生鍵的默認(rèn)處理并插入鍵。
該特定問(wèn)題至少有三種解決方案。
您可以綁定 on
<KeyRelease>
而不是,<Key>
因?yàn)樗鼘⒃谀J(rèn)綁定插入字符后觸發(fā)。您可以在默認(rèn)綁定之后添加自定義綁定標(biāo)簽,以便首先發(fā)生默認(rèn)綁定,然后再發(fā)生您的綁定。
你可以堅(jiān)持使用
bind_all
.?在這種情況下,您只需要進(jìn)行一次綁定,而不是每個(gè)小部件一次,并且您需要調(diào)整您的函數(shù)以使用event.widget
而不是self
.
添加回答
舉報(bào)