我不是專業的程式員,目前嘗試使用 python 的 tkinter 模塊撰寫一個在平板電腦上使用的小應用程式。我希望每次單擊/觸摸 tinkter Entry 小部件時都會彈出一個小鍵盤。我在stackoverflow上找到了以下代碼,它創建了一個“NumpadEntry”類(繼承自 tk.Entry),它幾乎完全符合我的要求。但是,一旦關閉小鍵盤視窗,就無法通過再次單擊 NumpadEntry 小部件重新打開它,直到我單擊另一個視窗或使用其間的第二個條目。
示例代碼:
import tkinter as tk
def enumerate_row_column(iterable, num_cols):
for idx, item in enumerate(iterable):
row = idx // num_cols
col = idx % num_cols
yield row,col,item
class NumpadEntry(tk.Entry):
def __init__(self,parent=None,**kw):
tk.Entry.__init__(self,parent,**kw)
self.bind('<FocusIn>', self.numpadEntry)
self.bind('<FocusOut>',self.numpadExit)
self.edited = False
def numpadEntry(self,event):
if self.edited == False:
print("You Clicked on me")
self['bg']= '#ffffcc'
self.edited = True
new = numPad(self)
else:
self.edited = False
def numpadExit(self,event):
self['bg']= '#ffffff'
class numPad(tk.simpledialog.Dialog):
def __init__(self,master=None,textVariable=None):
self.top = tk.Toplevel(master=master)
self.top.protocol("WM_DELETE_WINDOW",self.ok)
self.createWidgets()
self.master = master
def createWidgets(self):
btn_list = ['7', '8', '9', '4', '5', '6', '1', '2', '3', '0', 'Close', 'Del']
# create and position all buttons with a for-loop
btn = []
# Use custom generator to give us row/column positions
for r,c,label in enumerate_row_column(btn_list,3):
# partial takes care of function and argument
cmd = lambda x = label: self.click(x)
# create the button
cur = tk.Button(self.top, text=label, width=10, height=5, command=cmd)
# position the button
cur.grid(row=r, column=c)
btn.append(cur)
def click(self,label):
print(label)
if label == 'Del':
currentText = self.master.get()
self.master.delete(0, tk.END)
self.master.insert(0, currentText[:-1])
elif label == 'Close':
self.ok()
else:
currentText = self.master.get()
self.master.delete(0, tk.END)
self.master.insert(0, currentText label)
def ok(self):
self.top.destroy()
self.top.master.focus()
class App(tk.Frame):
def __init__(self,parent=None,**kw):
tk.Frame.__init__(self,parent,**kw)
self.textEntryVar1 = tk.StringVar()
self.e1 = NumpadEntry(self,textvariable=self.textEntryVar1)
self.e1.grid()
self.textEntryVar2 = tk.StringVar()
self.e2 = NumpadEntry(self,textvariable=self.textEntryVar2)
self.e2.grid()
if __name__ == '__main__':
root = tk.Tk()
root.geometry("200x100")
app = App(root)
app.grid()
root.mainloop()
我試圖以某種方式再次將已編輯的變數設定為 False,例如在 numpadExit 函式中:
def numpadExit(self,event):
self['bg']= '#ffffff'
self.edited == False
但這只會導致每次關閉時都會打開小鍵盤。
我還嘗試在這里使用 lambda 或將“FocusIn”更改為“Enter”:
self.bind('<FocusIn>', self.numpadEntry)
但這也沒有用。
恐怕這個問題有點超出我目前對 python 的理解 :( 因此非常感謝一些幫助。非常感謝提前。
uj5u.com熱心網友回復:
出現問題是因為您系結了焦點和焦點,因此您必須先關注另一個條目,然后才能再次關注第一個條目。相反,系結到<Button-1>,即左鍵單擊。
該程式可以通過使用numPad子類tk.Toplevel而不是Dialog. 這也消除了simpledialog匯入的需要。
我已添加grab_set到小鍵盤視窗。這會將所有事件定向到它,因此用戶在小鍵盤打開時無法與主視窗互動。這意味著您不必擔心用戶重復單擊條目并創建大量視窗。添加focus_force()時會在創建小鍵盤視窗時獲得焦點。我已經洗掉了edited不再需要的變數,并稍微更改了ok方法,numPad因此當小鍵盤被破壞時,條目顏色會發生變化。
class NumpadEntry(tk.Entry):
def __init__(self,parent=None,**kw):
tk.Entry.__init__(self,parent,**kw)
self.bind('<Button-1>', self.numpadEntry)
def numpadEntry(self,event):
print("You Clicked on me")
self['bg']= '#ffffcc'
new = numPad(self)
def numpadExit(self):
self['bg']= '#ffffff'
class numPad(tk.Toplevel):
def __init__(self,master=None,textVariable=None):
tk.Toplevel.__init__(self, master=master)
self.protocol("WM_DELETE_WINDOW",self.ok)
self.createWidgets()
self.master = master
self.grab_set()
self.focus_force()
def createWidgets(self):
btn_list = ['7', '8', '9', '4', '5', '6', '1', '2', '3', '0', 'Close', 'Del']
# create and position all buttons with a for-loop
btn = []
# Use custom generator to give us row/column positions
for r,c,label in enumerate_row_column(btn_list,3):
# partial takes care of function and argument
cmd = lambda x = label: self.click(x)
# create the button
cur = tk.Button(self, text=label, width=10, height=5, command=cmd)
# position the button
cur.grid(row=r, column=c)
btn.append(cur)
def click(self,label):
print(label)
if label == 'Del':
currentText = self.master.get()
self.master.delete(0, tk.END)
self.master.insert(0, currentText[:-1])
elif label == 'Close':
self.ok()
else:
currentText = self.master.get()
self.master.delete(0, tk.END)
self.master.insert(0, currentText label)
def ok(self):
self.master.numpadExit()
self.destroy()
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/527593.html
上一篇:為什么有人會通過一個空函式傳遞一個字串,而不是直接在Python中使用該字串?
下一篇:移動多個物件
