选中特定的Checkbutton还会选中Tkinter中的另一个复选框

问题描述

我测试复选框时遇到了这个问题。

enter image description here

当我选中显示提示复选框时,字数也会选中,反之亦然。

enter image description here

了解两个人之间的关系。这是我的代码

import tkinter as tk

COLOUR = 'grey80'
WORDS = ['motor','anaconda','supervise','walnut','manicure','acre']
gui = tk.Tk()

# Root Interface
gui.geometry('720x480')
gui.title('Password Generator')
gui.resizable(0,0)
gui.configure(bg = COLOUR)

frame_header = tk.Frame(bg='black')
tk.Label(text = 'Password Generator',font = 'Helvetica 30 bold',bg = 'black',fg='white').pack(ipady=10,fill='both')
tk.Label(text = 'A Password Generator based on Diceware',font = 'arial 11',fg='white').pack(fil='both')
frame_header.pack(fill='both')

tk.Label(text= '',width = 70,height = 3,borderwidth = 2,relief = tk.SUNKEN).pack(pady=5)
tk.Checkbutton(gui,text='Show Hint',bg = COLOUR).pack(anchor='nw',padx=110)
tk.Label(text= f'Words Used : {WORDS}',bg = COLOUR).pack(anchor = 'nw',padx=130)


frame = tk.Frame(gui,bg=COLOUR)
tk.Label(frame,text='Generate a norMAL password :',font = 'arial 12',bg=COLOUR).grid(row=0,column=0,columnspan=2,sticky=tk.W)
tk.Button(frame,text='Generate',bg='black',fg='white').grid(row=0,column=2,padx=5,pady=10)
tk.Label(frame,text='Generate a COMPLEX password :',bg=COLOUR).grid(row=1,fg='white').grid(row=1,text='Generate a CUSTOM password :',bg=COLOUR).grid(row=2,fg='white').grid(row=2,text='Password must contain-',font = 'arial 9',bg=COLOUR).grid(row=3,column=1,sticky=tk.W)

tk.Checkbutton(frame,text='Number of words(Default is 4) :',bg = COLOUR).grid(row=4,sticky=tk.W)
tk.Entry(frame,textvariable='sdfafd',width=5).grid(row=4,sticky=tk.E)
tk.Checkbutton(frame,text='Uppercase Letters',bg = COLOUR).grid(row=5,sticky=tk.W)
tk.Checkbutton(frame,text='Digits',text='Symbols',column=2)

frame.pack(side=tk.LEFT,expand=True,padx=160,ipady=20)

tk.Label(text = 'by spicymaterial',bg = COLOUR).pack(side=tk.RIGHT,anchor='se')


gui.mainloop()

也知道为什么页脚被剪掉了。

解决方法

每个复选按钮都需要关联的变量。如果您未明确定义变量,则tkinter将为您定义一个。当tkinter为您定义一个名称时,它将基于小部件的内部名称,使用全名的最后一部分。

gui中创建第一个复选按钮时,其全名可能是.!checkbutton,因为它是根窗口的子级,变量名将是!checkbutton。 / p>

当您在frame中创建第二个复选按钮时,其全名可能是.!frame2.!checkbutton,因为它是框架的子级,而变量名将是!checkbutton

由于变量具有相同的内部名称,因此tkinter在内部将它们视为相同的变量,因此选中按钮已链接。

创建Checkbutton的正确方法是始终显式定义variable选项。

hint_var = tk.IntVar()
num_words_var = tk.IntVar()

tk.Checkbutton(...,variable=hint_var)
tk.Checkbutton(...,variable=num_words_var)

如果您从不打算使用变量,则可以提供普通字符串,而不必创建单独的变量对象

tk.Checkbutton(...,variable="hint")
tk.Checkbutton(...,variable="num words")
,

@jasonharper指出需要设置variable中的Checkbuttons选项。如果未设置,则Checkbutton似乎按它们在包含的小部件中的位置分组。

此代码演示了错误的行为。 “显示提示”链接到“单词数”,“测试”链接到“大写字母”。 gui中的第一项链接到frame中的第一项。第二个项目也已链接。

import tkinter as tk

COLOUR = 'grey80'
gui = tk.Tk()

# Root Interface
gui.title('Password Generator')
gui.resizable(0,0)
gui.configure(bg = COLOUR)

tk.Checkbutton(gui,text='Show Hint',bg = COLOUR).pack(anchor='nw')
tk.Checkbutton( gui,text='Test').pack( anchor = 'nw')

frame = tk.Frame(gui,bg=COLOUR)
tk.Checkbutton(frame,text='Number of words(Default is 4) :',bg = COLOUR).grid(row=4,column=1,sticky=tk.W)
tk.Checkbutton(frame,text='Uppercase Letters',bg = COLOUR).grid(row=5,text='Digits',column=2,text='Symbols',column=2)

frame.pack(side=tk.LEFT)

tk.Label(text = 'by spicymaterial',font = 'arial 9',bg = COLOUR).pack(side=tk.RIGHT,anchor='se')

gui.mainloop()

要获得预期的行为,将创建tk.IntVars并使用variable选项将其链接到Checkbuttons。

import tkinter as tk

COLOUR = 'grey80'
WORDS = ['motor','anaconda','supervise','walnut','manicure','acre']
gui = tk.Tk()

# Root Interface
gui.geometry('720x480')
gui.title('Password Generator')
gui.resizable(0,0)
gui.configure(bg = COLOUR)

# Checkbox variables
hint_var = tk.IntVar()
words_var = tk.IntVar()
upper_var = tk.IntVar()
digits_var = tk.IntVar()
symbols_var = tk.IntVar()


frame_header = tk.Frame(bg='black')
tk.Label(text = 'Password Generator',font = 'Helvetica 30 bold',bg = 'black',fg='white').pack(ipady=10,fill='both')
tk.Label(text = 'A Password Generator based on Diceware',font = 'arial 11',fg='white').pack(fil='both')
frame_header.pack(fill='both')

tk.Label(text= '',width = 70,height = 3,borderwidth = 2,relief = tk.SUNKEN).pack(pady=5)
tk.Checkbutton(gui,bg = COLOUR,variable = hint_var).pack(anchor='nw',padx=110)
# Note variable = hint_var
tk.Label(text= f'Words Used : {WORDS}',bg = COLOUR).pack(anchor = 'nw',padx=130)


frame = tk.Frame(gui,bg=COLOUR)
tk.Label(frame,text='Generate a NORMAL password :',font = 'arial 12',bg=COLOUR).grid(row=0,column=0,columnspan=2,sticky=tk.W)
tk.Button(frame,text='Generate',bg='black',fg='white').grid(row=0,padx=5,pady=10)
tk.Label(frame,text='Generate a COMPLEX password :',bg=COLOUR).grid(row=1,fg='white').grid(row=1,text='Generate a CUSTOM password :',bg=COLOUR).grid(row=2,fg='white').grid(row=2,text='Password must contain-',bg=COLOUR).grid(row=3,sticky=tk.W)

tk.Checkbutton(frame,variable = words_var,sticky=tk.W)
tk.Entry(frame,textvariable='sdfafd',width=5).grid(row=4,sticky=tk.E)
tk.Checkbutton(frame,variable = upper_var).grid(row=5,variable = digits_var).grid(row=4,variable = symbols_var).grid(row=5,column=2)

frame.pack(side=tk.LEFT,expand=True,padx=160,ipady=20)

tk.Label(text = 'by spicymaterial',anchor='se')


gui.mainloop()

生成密码的代码现在可以访问tk.IntVars来更改生成密码的方式。