0

I ran into this problem when I tested my checkbox. enter image description here

When I check the show hint checkbox, Number of words also checks and vice versa. enter image description here

Idk how they both are related. Here is my code.

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', bg = 'black', 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 :', font = 'arial 12', bg=COLOUR).grid(row=1, column=0, columnspan=2, sticky=tk.W)
tk.Button(frame, text='Generate', bg='black', fg='white').grid(row=1, column=2, padx=5, pady=10)
tk.Label(frame, text='Generate a CUSTOM password :', font = 'arial 12', bg=COLOUR).grid(row=2, column=0, columnspan=2, sticky=tk.W)
tk.Button(frame, text='Generate', bg='black', fg='white').grid(row=2, column=2, padx=5, pady=10)
tk.Label(frame, 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, column=1, sticky=tk.W)
tk.Entry(frame, textvariable='sdfafd', width=5).grid(row=4, column=1, sticky=tk.E)
tk.Checkbutton(frame, text='Uppercase Letters', bg = COLOUR).grid(row=5, column=1, sticky=tk.W)
tk.Checkbutton(frame, text='Digits', bg = COLOUR).grid(row=4, column=2, sticky=tk.W)
tk.Checkbutton(frame, text='Symbols', bg = COLOUR).grid(row=5, column=2)

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

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


gui.mainloop()

Also idk why the footer is getting cut.

Mohit
  • 31
  • 4
  • 1
    The usual cause for that is that you mistakenly gave both Checkbuttons the same `variable=` option. I don't see any such options here, is there more code to your full program? – jasonharper Nov 06 '20 at 13:32
  • That was the full code – Mohit Nov 06 '20 at 13:34

2 Answers2

2

Every checkbutton requires an associated variable. If you do not explicitly define a variable, tkinter will define one for you. When tkinter defines one for you, it will be based off of the internal name of the widget, using the last part of the full name.

When you create the first checkbutton in gui, its full name will likely be .!checkbutton since it is a child of the root window, and the variable name will be !checkbutton.

When you create the second checkbutton in frame, its full name will likely be .!frame2.!checkbutton because it is the child of a frame, and the variable name will be !checkbutton.

Because the variables have the same internal name, they are the considered the same variable internally by tkinter and thus the checkbuttons are linked.

The proper way to create a Checkbutton is to always explicitly define the variable option.

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

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

If you don't ever plan on using the variables you can supply a normal string and avoid having to create separate variable objects

tk.Checkbutton(..., variable="hint")
tk.Checkbutton(..., variable="num words")
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • Thanks for explaining why the behaviour with the Checkbuttons was happening. I was trying to understand why two buttons were linked but not all five. – Tls Chris Nov 06 '20 at 16:47
1

As @jasonharper indicated the variable option in the Checkbuttons needs to be set. If they are not set The Checkbuttons seem to be grouped by where they are in the containing widget.

This code demonstrates the wrong behaviour. 'Show Hint' is linked to 'Number of Words' and 'Test' is linked to 'Uppercase Letters'. The first item in gui is linked to the first item in frame. The two second items are linked too.

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, column=1, sticky=tk.W)
tk.Checkbutton(frame, text='Digits', bg = COLOUR).grid(row=4, column=2, sticky=tk.W)
tk.Checkbutton(frame, text='Symbols', bg = COLOUR).grid(row=5, 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()

To get the expected behaviour tk.IntVars are created and linked to the Checkbuttons with the variable option.

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', bg = 'black', 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, 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, column=2, padx=5, pady=10)
tk.Label(frame, text='Generate a COMPLEX password :', font = 'arial 12', bg=COLOUR).grid(row=1, column=0, columnspan=2, sticky=tk.W)
tk.Button(frame, text='Generate', bg='black', fg='white').grid(row=1, column=2, padx=5, pady=10)
tk.Label(frame, text='Generate a CUSTOM password :', font = 'arial 12', bg=COLOUR).grid(row=2, column=0, columnspan=2, sticky=tk.W)
tk.Button(frame, text='Generate', bg='black', fg='white').grid(row=2, column=2, padx=5, pady=10)
tk.Label(frame, 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) :',  variable = words_var, bg = COLOUR).grid(row=4, column=1, sticky=tk.W)
tk.Entry(frame, textvariable='sdfafd', width=5).grid(row=4, column=1, sticky=tk.E)
tk.Checkbutton(frame, text='Uppercase Letters', bg = COLOUR, variable = upper_var).grid(row=5, column=1, sticky=tk.W)
tk.Checkbutton(frame, text='Digits', bg = COLOUR, variable = digits_var).grid(row=4, column=2, sticky=tk.W)
tk.Checkbutton(frame, text='Symbols', bg = COLOUR, variable = symbols_var).grid(row=5, column=2)

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

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


gui.mainloop()

The code to generate the passwords can now access the tk.IntVars to change how passwords are generated.

Tls Chris
  • 3,564
  • 1
  • 9
  • 24
  • Thx for the help mate :) – Mohit Nov 06 '20 at 14:20
  • Also how do I display footer properly? – Mohit Nov 06 '20 at 14:20
  • I think it's because the width specified by the geometry is inconsistent with the total widths specified. Remove the geometry statement and it shows as expected or reduce the `padx` for the frame. – Tls Chris Nov 06 '20 at 14:53
  • If the original answer solves your problem you can accept it? This will then show as solved for somebody looking for the answer to a similar question. – Tls Chris Nov 06 '20 at 14:55