I want to create a function that arranges multiple Tkinter checkboxes and gets the value (True, False) when the checkbox is pressed.
In Tkinter, 9x5 layout, the process of arranging the check box and the process of getting the value were implemented using the exec function.
In addition, there are 45 check box items.
Below is the code when implemented.
from tkinter import *
from tkinter import ttk
root = Tk ()
root.title ('Checkbutton')
frame1 = ttk.Frame (root, padding = (10))
frame1.grid ()
# 9 x 5 matrix
for i in range (9): #line
for j in range (5): #column
exec ('v {} = BooleanVar ()'. format (j + 5 * i + 1))
exec ('v {} .set (False)'.format (j + 5 * i + 1))
exec ("" "cb {} = ttk.Checkbutton ("" "cb {}
frame1, padding = 10, text ='test {}',
variable = v {},
command = lambda: print ('v {} =% s'% v {} .get ())) "" ". format (j + 5 * i + 1, j + i * 5 + 1, j + 5 * i + 1, j + 5 * i + 1, j + 5 * i + 1, j + 5 * i + 1))
exec ("cb {} .grid (row = {}, column = {})". format (j + 5 * i + 1, i, j))
print ("cb {} .grid (row = {}, column = {})". format (j + 5 * i + 1, i, j))
root.mainloop ()
When executed, the following screen will be displayed, and if you press or do not press the check box,v1 = True
,v2 = True
,v3 = False
,v3 = True
Can be obtained.
However, if you make it a function like the code below, you will not be able to get it.
from tkinter import *
from tkinter import ttk
root = Tk ()
root.title ('Checkbutton')
def main ():
#Frame
frame1 = ttk.Frame (root, padding = (10))
frame1.grid ()
# 9 x 5 matrix
for i in range (9): #line
for j in range (5): #column
exec ('v {} = BooleanVar ()'. format (j + 5 * i + 1))
exec ('v {} .set (False)'.format (j + 5 * i + 1))
exec ("" "cb {} = ttk.Checkbutton ("" "cb {}
frame1, padding = 10, text ='test {}',
variable = v {},
command = lambda: print ('v {} =% s'% v {} .get ())) "" ". format (j + 5 * i + 1, j + i * 5 + 1, j + 5 * i + 1, j + 5 * i + 1, j + 5 * i + 1, j + 5 * i + 1))
exec ("cb {} .grid (row = {}, column = {})". format (j + 5 * i + 1, i, j))
print ("cb {} .grid (row = {}, column = {})". format (j + 5 * i + 1, i, j))
main ()
root.mainloop ()
If i make it a function, for example, when you press the check box of test1, the following error will be displayed.
Example
NameError: name'v1' is not defined
How can I get the value when I make it a function?
Actually, I think it is less likely to cause an error if you declare variables one by one without using the exec function, but I don't like the large number of variables, so I definitely want to use the exec function.
Also, if it does not function, it will work normally, but I would like to incorporate it into other processing based on the created function, so please let me know if there is a way to make it a function.
-
Answer # 1
-
Answer # 2
How to make multiple checkbuttons
The checkbutton is generated in a loop.
Variables generated including checkbutton are stored in the dictionary.
To identify the checked widget and print its status
In the event before the check status changes, hold down the widget that generated the event.
In the event after the check state changes, the necessary data is fetched from the widget and printed.
Example using functools.partial proposed by teamiklfrom tkinter import * from tkinter import ttk root = Tk () root.title ('Checkbutton') frame1 = ttk.Frame (root, padding = (10)) frame1.grid () #Before the check status changes def prev_cb (e): # Hold down the widget from which the event occurred global cur_cb cur_cb = e.widget #After the check status changes def after_cb (): row, col, var = cbs [cur_cb] print (f'{row + 1}, {col + 1} = {var.get ()}') # Initialize one checkbutton def init_check (frm, row, col): var = BooleanVar () var.set (False) cb = ttk.Checkbutton (frm, padding = 10, text = f'{row + 1} x {col + 1}', variable = var, command = after_cb) cb.bind ('<1>', prev_cb) cb.grid (row = row, column = col) return cb, var cbs = {} #Dictionary for holding widget etc. cur_cb = None # event checkbutton for row in range (2): #row for col in range (3): #column cb, var = init_check (frame1, row, col) cbs [cb] = (row, col, var) # Keep necessary variables linked to widget root.mainloop ()
from tkinter import * from tkinter import ttk import functools root = Tk () root.title ('Checkbutton') frame1 = ttk.Frame (root, padding = (10)) frame1.grid () def after_cb (row, col, var): print (f'{row + 1}, {col + 1} = {var.get ()}') # Initialize one checkbutton def init_check (frm, row, col): var = BooleanVar () var.set (False) f = functools.partial (after_cb, row, col, var) #print (id (f)) cb = ttk.Checkbutton (frm, padding = 10, text = f'{row + 1} x {col + 1}', variable = var, command = f) cb.grid (row = row, column = col) for row in range (2): #row for col in range (3): #column init_check (frame1, row, col) root.mainloop ()
Related articles
- python - [tkinter] multiple selectable combobox
- sql - when you want to display multiple values in one column
- python - tkinter photo image question
- python 3x - tkinter i want to write code concisely
- python 3x - change font size for python3 tkinter entry
- python - how to load multiple time formats with pandas
- python - reopening the file dialog in tkinter results in an error
- [python] [tkinter] i want to change the acquisition contents of the second and subsequent menu lists by selecting the previous p
- i can't select checkbox when scraping with python
- python - cannot inherit a class with multiple arguments
- python - [tkinter] [py installer] unable to execute exe file
- python 3x - unintended behavior of python3 tkinter binding
- python - pltshow does not run unless you close the tkinter window
- python 3x - multiple outputs from a list of tuples
- python - about multiple processing and loop processing in discordpy
- python3 tkinter i want to be able to input only character strings in a fixed format
- python 3x - python3 tkinter toplevel behaves differently than intended
- python 3x - valueerror: not enough values to unpack (expected 3, got 2)
- python 3x - i want to get a matrix with the values of a certain column removed for each row of the matrix with pytorch (speedu
- Python Tkinter not seeing 'TimePL' instance of Label widget
- python : How can a scrollbar be attached to a label in tkinter
- python : Why root.attributes('-topmost', False) fires every other time?
- python : How to write functions for buttons to work?
- Working buttons in TKinter in Python in OOP
- python : How to create a large text input field?
- python : How to keep the scale of buttons, text, etc in tkinter?
- python : how to bind keyboard input in Tkinter
- python : how to find out the size of a Tkinter window?
- python : How to make txt to html text converter
If the reason is the number of variables
It's definitely better not to use the exec function here.
There is no need to increase the number of variables, manage them in a list or dictionary.
rather,The number of variables is increased by using exec.
It is also not a good use for exec.
The cause is that tk.BooleanVar is a local variable in the main function.
If you didn't use any functions, they were all global variables.
If you make it a global variable, it will cause malfunction when used elsewhere.
I don't recommend this, but you can see it in action.
Addendum: Other changes, root ~ mainloop (), will be moved into the main function.
To make it a local variable, you can specify a dictionary of local variables as an argument to exec.
However, this is also not the recommended solution. The code becomes more complicated.
Use a list or dictionary to manage Checkbuttons and BooleanVar.