python tkinter 鼠标左键单击仅适用于双击
python tkinter mouse left click works only with double click
使用下面的代码 Button-1
点击调用 relief
更改仅在已点击一次时才有效(只有第一次双击有效,第二次正常,但如果其他小部件是选择,同样的事情发生):
def selected(event):
event.widget.config(relief=SUNKEN if event.widget.cget("relief") == "raised" else RAISED)
B1 = Button(root, text ='BUTTON1', font='-size 8', relief=RAISED)
B1.bind("<Button>", selected)
B1.grid(row = 1, column = 2, sticky = N+E+S+W)
B2 = Button(root, text ='BUTTON2', font='-size 8', relief=RAISED)
B2.bind("<Button>", selected)
B2.grid(row = 2, column = 2, sticky = N+E+S+W)
Button-2 和 Button-3 工作正常,
这是什么原因?
看来您只需要调整一个东西就可以 single-click 在按钮上激活该功能。尝试将绑定更改为此:
def selected(event):
event.widget.config(relief=SUNKEN if event.widget.cget("relief") == "raised" else RAISED)
B1 = Button(root, text ='BUTTON1', font='-size 8', relief=RAISED)
B1.bind("<Button-1>", selected)
B1.grid(row = 1, column = 2, sticky = N+E+S+W)
B2 = Button(root, text ='BUTTON2', font='-size 8', relief=RAISED)
B2.bind("<Button-1>", selected)
B2.grid(row = 2, column = 2, sticky = N+E+S+W)
只需将“Button”改为“Button-1”,如有错误请告知
问题是 tkinter
可以将许多函数绑定到事件,并且已经绑定了默认函数,当您单击按钮时它会更改 relief
。您可以在您的函数中使用 return "break"
来通知 tkinter
您处理了此事件,它将跳过其他函数。
或者您可以使用标准 command=
来分配函数,然后它会跳过其他函数。
import tkinter as tk # PEP8: `import *` is not preferred
# --- functions ---
def selected1(event):
event.widget.config(relief='sunken' if event.widget.cget('relief') == 'raised' else 'raised')
return "break"
def selected2():
B2.config(relief='sunken' if B2.cget("relief") == 'raised' else 'raised')
# --- main ---
root = tk.Tk()
B1 = tk.Button(root, text='BUTTON1', relief='raised')
B1.bind("<Button>", selected1)
B1.grid(row=1, column=2, sticky='news')
B2 = tk.Button(root, text='BUTTON2', relief='raised', command=selected2)
B2.grid(row=2, column=2, sticky='news')
root.mainloop()
同样使用for
循环和lambda
。
通常它仅使用对 button
的引用,循环中更改的值因此最终所有函数都使用对相同值的引用 - 这是循环中分配的最后一个值。
使用 lambda arg=button
它在每个循环中创建新变量并将值从 button
复制到 arg
因此每个小部件使用不同的 arg 和不同的值。
import tkinter as tk # PEP8: `import *` is not preferred
# --- functions ---
def selected(widget):
widget.config(relief='sunken' if widget.cget('relief') == 'raised' else 'raised')
# --- main ---
root = tk.Tk()
for x in range(1, 6):
button = tk.Button(root, text=f'LOOP BUTTON {x}', relief='raised')
#button.config(command=lambda arg=button:selected3(arg))
button['command'] = lambda arg=button:selected(arg)
button.grid(row=x, column=2, sticky='news')
root.mainloop()
正如@acw1668 在评论中提到的,您也可以使用 Checkbutton(..., indicator=False)
获得相同的效果而无需额外的功能
import tkinter as tk # PEP8: `import *` is not preferred
# --- main ---
root = tk.Tk()
for x in range(1, 6):
button = tk.Checkbutton(root, text=f'LOOP BUTTON {x}', indicator=False, padx=10, pady=5)
button.grid(row=x, column=2, sticky='news')
root.mainloop()
使用下面的代码 Button-1
点击调用 relief
更改仅在已点击一次时才有效(只有第一次双击有效,第二次正常,但如果其他小部件是选择,同样的事情发生):
def selected(event):
event.widget.config(relief=SUNKEN if event.widget.cget("relief") == "raised" else RAISED)
B1 = Button(root, text ='BUTTON1', font='-size 8', relief=RAISED)
B1.bind("<Button>", selected)
B1.grid(row = 1, column = 2, sticky = N+E+S+W)
B2 = Button(root, text ='BUTTON2', font='-size 8', relief=RAISED)
B2.bind("<Button>", selected)
B2.grid(row = 2, column = 2, sticky = N+E+S+W)
Button-2 和 Button-3 工作正常,
这是什么原因?
看来您只需要调整一个东西就可以 single-click 在按钮上激活该功能。尝试将绑定更改为此:
def selected(event):
event.widget.config(relief=SUNKEN if event.widget.cget("relief") == "raised" else RAISED)
B1 = Button(root, text ='BUTTON1', font='-size 8', relief=RAISED)
B1.bind("<Button-1>", selected)
B1.grid(row = 1, column = 2, sticky = N+E+S+W)
B2 = Button(root, text ='BUTTON2', font='-size 8', relief=RAISED)
B2.bind("<Button-1>", selected)
B2.grid(row = 2, column = 2, sticky = N+E+S+W)
只需将“Button”改为“Button-1”,如有错误请告知
问题是 tkinter
可以将许多函数绑定到事件,并且已经绑定了默认函数,当您单击按钮时它会更改 relief
。您可以在您的函数中使用 return "break"
来通知 tkinter
您处理了此事件,它将跳过其他函数。
或者您可以使用标准 command=
来分配函数,然后它会跳过其他函数。
import tkinter as tk # PEP8: `import *` is not preferred
# --- functions ---
def selected1(event):
event.widget.config(relief='sunken' if event.widget.cget('relief') == 'raised' else 'raised')
return "break"
def selected2():
B2.config(relief='sunken' if B2.cget("relief") == 'raised' else 'raised')
# --- main ---
root = tk.Tk()
B1 = tk.Button(root, text='BUTTON1', relief='raised')
B1.bind("<Button>", selected1)
B1.grid(row=1, column=2, sticky='news')
B2 = tk.Button(root, text='BUTTON2', relief='raised', command=selected2)
B2.grid(row=2, column=2, sticky='news')
root.mainloop()
同样使用for
循环和lambda
。
通常它仅使用对 button
的引用,循环中更改的值因此最终所有函数都使用对相同值的引用 - 这是循环中分配的最后一个值。
使用 lambda arg=button
它在每个循环中创建新变量并将值从 button
复制到 arg
因此每个小部件使用不同的 arg 和不同的值。
import tkinter as tk # PEP8: `import *` is not preferred
# --- functions ---
def selected(widget):
widget.config(relief='sunken' if widget.cget('relief') == 'raised' else 'raised')
# --- main ---
root = tk.Tk()
for x in range(1, 6):
button = tk.Button(root, text=f'LOOP BUTTON {x}', relief='raised')
#button.config(command=lambda arg=button:selected3(arg))
button['command'] = lambda arg=button:selected(arg)
button.grid(row=x, column=2, sticky='news')
root.mainloop()
正如@acw1668 在评论中提到的,您也可以使用 Checkbutton(..., indicator=False)
获得相同的效果而无需额外的功能
import tkinter as tk # PEP8: `import *` is not preferred
# --- main ---
root = tk.Tk()
for x in range(1, 6):
button = tk.Checkbutton(root, text=f'LOOP BUTTON {x}', indicator=False, padx=10, pady=5)
button.grid(row=x, column=2, sticky='news')
root.mainloop()