I am creating a Listbox using Tkinter and Python. I want to make a Button for select all, but I can't find any info regarding selecting elements using code.
self.l = Listbox(self, height=12, selectmode=MULTIPLE)
self.selectAll=Button(self, text="select all",
command=self.selectAllCallback())
def selectAllCallback(self)
# What to do here
You can use selection_set (or select_set) method with 0 and END as arguments.
For example, try following code:
from Tkinter import *
def select_all():
lb.select_set(0, END)
root = Tk()
lb = Listbox(root, selectmode=MULTIPLE)
for i in range(10): lb.insert(END, i)
lb.pack()
Button(root, text='select all', command=select_all).pack()
root.mainloop()
In the following statement, you are calling self.selectAllCallback, not bind it with button click. It is called before the button is generated.
self.selectAll=Button(self,text="select all", command=self.selectAllCallback())
^^
It should be:
self.selectAll=Button(self, text="select all", command=self.selectAllCallback)
Related
Using Tkinter and Python. Already created a window for the buttons to be placed on. I want there to be four buttons to appear, and I want to be able to click one of the four buttons, and be able for it to set the selection variable = "whatever I clicked", so that I can then use this variable later to call an API. When I run the program and click on the "General knowledge" button and print the selection, it does correctly print "General knowledge", but then when I try to return this selection variable it just doesn't work and I don't know why.
def select1():
selection = "General Knowledge"
print(selection)
def select2():
selection = "Science"
def select3():
selection = "Entertainment"
def select4():
selection = "Miscellaneous"
button1 = tk.Button(text = "General Knowledge", command = select1)
button1.place(x=100, y=100)
button2 = tk.Button(text = "Science", command = select2)
button2.place(x=100, y=140)
button3 = tk.Button(text = "Entertainment", command = select3)
button3.place(x=100, y=180)
button4 = tk.Button(text = "Miscellaneous", command = select4)
button4.place(x=100, y=220)
There are several ways to accomplish your goal.
One way is to write a single function that will take a value to assign to your variable. This way you can have as many buttons as you like and only a single function.
Not if you are using functions you have to either pass the variable to the function or let the function know it is in the global namespace.
import tkinter as tk
root = tk.Tk()
selection = ''
def assign_value(value):
global selection
selection = value
lbl["text"] = value
print(selection)
lbl = tk.Label(root, text='Selection Goes Here')
lbl.grid(row=0, column=0)
tk.Button(text="General Knowledge", command=lambda: assign_value("General Knowledge")).grid(row=1, column=0)
tk.Button(text="Science", command=lambda: assign_value("Science")).grid(row=2, column=0)
tk.Button(text="Entertainment", command=lambda: assign_value("Entertainment")).grid(row=3, column=0)
tk.Button(text="Miscellaneous", command=lambda: assign_value("Miscellaneous")).grid(row=4, column=0)
root.mainloop()
Or you can assign the value directly from the button.
import tkinter as tk
root = tk.Tk()
selection = tk.StringVar()
selection.set('Selection Goes Here')
lbl = tk.Label(root, textvariable=selection)
lbl.grid(row=0, column=0)
tk.Button(text="General Knowledge", command=lambda: selection.set("General Knowledge")).grid(row=1, column=0)
tk.Button(text="Science", command=lambda: selection.set("Science")).grid(row=2, column=0)
tk.Button(text="Entertainment", command=lambda: selection.set("Entertainment")).grid(row=3, column=0)
tk.Button(text="Miscellaneous", command=lambda: selection.set("Miscellaneous")).grid(row=4, column=0)
root.mainloop()
I am sure if I spent more time on this I could think up something else but the idea is basically write your code in a more DRY (Don't Repeat Yourself) fashion and make sure you are assigning the value to the variable in the global namespace or else it will not work as you expect.
Recently I was working on a program where when one clicked a button, it would delete all of the tkinter buttons they made through a .yml file. Here is an example of what I mean:
(All TKinter Root Init Here)
button1 = Button(root, text="hi")
button2 = Button(root, text="hi again")
button3 = Button(root, text="hi again again")
button4 = Button(root, text="OK this is getting tiring")
button5 = Button(root, text="go away")
button6 = Button(root, text="...")
def del_all():
for i in range(999999999):
button(i).place_forget() #I was hoping to make button(i) give the output button1, then button2, and so on.
root.mainloop()
Try nametowidget in tkinter,example like:
import tkinter as tk
r = tk.Tk()
for i in range(5):
tk.Button(r,text=i).pack()
r.nametowidget(".!button").pack_forget()
r.mainloop()
This will remove the first button.If you want to remove the second button, you need to use r.nametowidget(".!button2").pack_forget()
So for you code,you may need to use:
def del_all():
root.nametowidget(".!button").place_forget()
for i in range(2, 999999999):
root.nametowidget(".!button"+str(i)).place_forget()
About the parameter in the nametowidget, there is a clear description.
You could also use winfo_children and use .widgetName to check whether it is a button,like:
import tkinter as tk
r = tk.Tk()
tk.Label(r, text="test").pack()
for i in range(5):
tk.Button(r,text=i).pack()
for i in r.winfo_children():
if i.widgetName == 'button':
i.pack_forget()
r.mainloop()
The solution would depend on how the buttons are named/stored.
For example, if the buttons were a list. Something like:
buttons = ['button1', 'button2', 'button3', 'button4']
Then you an delete by calling:
buttons.remove()
And that would 'clear' the list.
I would like to make a file button on my Tkinter application that displays three of four options to the user. I have this code:
self.file_button_text = StringVar(master)
self.file_button_text.set('File')
self.file_buton = OptionMenu(self, self.file_button_text, "Com Ports", "Bottle Information", "Reset Graphs")
self.file_buton.grid(row=0, column=0)
self.file_button_text.trace("w", self.file_option)
def file_option(self, *args):
print(self.file_button_text.get())
self.file_button_text.set('File')
However, once an option is selected, the text of the button changes to that option. Is there a way I can get the value of the selection without changing the text of the button itself? I tried using trace to see the option selected and then change the text back to File but it takes too long. Is there a better/another way to do this?
An option menu is nothing but a Menubutton with a Menu, and some special code specifically to change the text of the button. If you don't need that feature, just create your own with a Menubutton and Menu.
Example:
import tkinter as tk
root = tk.Tk()
var = tk.StringVar()
label = tk.Label(root, textvariable=var)
menubutton = tk.Menubutton(root, text="Select an option",
borderwidth=1, relief="raised",
indicatoron=True)
menu = tk.Menu(menubutton, tearoff=False)
menubutton.configure(menu=menu)
menu.add_radiobutton(label="One", variable=var, value="One")
menu.add_radiobutton(label="Two", variable=var, value="Two")
menu.add_radiobutton(label="Three", variable=var, value="Three")
label.pack(side="bottom", fill="x")
menubutton.pack(side="top")
root.mainloop()
I'm trying to use an Entry field to get manual input, and then work with that data.
All sources I've found claim I should use the get() function, but I haven't found a simple working mini example yet, and I can't get it to work.
I hope someone can tel me what I'm doing wrong. Here's a mini file:
from tkinter import *
master = Tk()
Label(master, text="Input: ").grid(row=0, sticky=W)
entry = Entry(master)
entry.grid(row=0, column=1)
content = entry.get()
print(content) # does not work
mainloop()
This gives me an Entry field I can type in, but I can't do anything with the data once it's typed in.
I suspect my code doesn't work because initially, entry is empty. But then how do I access input data once it has been typed in?
It looks like you may be confused as to when commands are run. In your example, you are calling the get method before the GUI has a chance to be displayed on the screen (which happens after you call mainloop.
Try adding a button that calls the get method. This is much easier if you write your application as a class. For example:
import tkinter as tk
class SampleApp(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.entry = tk.Entry(self)
self.button = tk.Button(self, text="Get", command=self.on_button)
self.button.pack()
self.entry.pack()
def on_button(self):
print(self.entry.get())
app = SampleApp()
app.mainloop()
Run the program, type into the entry widget, then click on the button.
You could also use a StringVar variable, even if it's not strictly necessary:
v = StringVar()
e = Entry(master, textvariable=v)
e.pack()
v.set("a default value")
s = v.get()
For more information, see this page on effbot.org.
A simple example without classes:
from tkinter import *
master = Tk()
# Create this method before you create the entry
def return_entry(en):
"""Gets and prints the content of the entry"""
content = entry.get()
print(content)
Label(master, text="Input: ").grid(row=0, sticky=W)
entry = Entry(master)
entry.grid(row=0, column=1)
# Connect the entry with the return button
entry.bind('<Return>', return_entry)
mainloop()
*
master = Tk()
entryb1 = StringVar
Label(master, text="Input: ").grid(row=0, sticky=W)
Entry(master, textvariable=entryb1).grid(row=1, column=1)
b1 = Button(master, text="continue", command=print_content)
b1.grid(row=2, column=1)
def print_content():
global entryb1
content = entryb1.get()
print(content)
master.mainloop()
What you did wrong was not put it inside a Define function then you hadn't used the .get function with the textvariable you had set.
you need to put a textvariable in it, so you can use set() and get() method :
var=StringVar()
x= Entry (root,textvariable=var)
Most of the answers I found only showed how to do it with tkinter as tk. This was a problem for me as my program was 300 lines long with tons of other labels and buttons, and I would have had to change a lot of it.
Here's a way to do it without importing tkinter as tk or using StringVars. I modified the original mini program by:
making it a class
adding a button and an extra method.
This program opens up a tkinter window with an entry box and an "Enter" button. Clicking the Enter button prints whatever is in the entry box.
from tkinter import *
class mini():
def __init__(self):
master = Tk()
Label(master, text="Input: ").grid(row=0, sticky=W)
Button(master, text='Enter', command=self.get_content).grid(row=1)
self.entry = Entry(master)
self.entry.grid(row=0, column=1)
master.mainloop()
def get_content(self):
content = self.entry.get()
print(content)
m = mini()
I'm trying to use an Entry field to get manual input, and then work with that data.
All sources I've found claim I should use the get() function, but I haven't found a simple working mini example yet, and I can't get it to work.
I hope someone can tel me what I'm doing wrong. Here's a mini file:
from tkinter import *
master = Tk()
Label(master, text="Input: ").grid(row=0, sticky=W)
entry = Entry(master)
entry.grid(row=0, column=1)
content = entry.get()
print(content) # does not work
mainloop()
This gives me an Entry field I can type in, but I can't do anything with the data once it's typed in.
I suspect my code doesn't work because initially, entry is empty. But then how do I access input data once it has been typed in?
It looks like you may be confused as to when commands are run. In your example, you are calling the get method before the GUI has a chance to be displayed on the screen (which happens after you call mainloop.
Try adding a button that calls the get method. This is much easier if you write your application as a class. For example:
import tkinter as tk
class SampleApp(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.entry = tk.Entry(self)
self.button = tk.Button(self, text="Get", command=self.on_button)
self.button.pack()
self.entry.pack()
def on_button(self):
print(self.entry.get())
app = SampleApp()
app.mainloop()
Run the program, type into the entry widget, then click on the button.
You could also use a StringVar variable, even if it's not strictly necessary:
v = StringVar()
e = Entry(master, textvariable=v)
e.pack()
v.set("a default value")
s = v.get()
For more information, see this page on effbot.org.
A simple example without classes:
from tkinter import *
master = Tk()
# Create this method before you create the entry
def return_entry(en):
"""Gets and prints the content of the entry"""
content = entry.get()
print(content)
Label(master, text="Input: ").grid(row=0, sticky=W)
entry = Entry(master)
entry.grid(row=0, column=1)
# Connect the entry with the return button
entry.bind('<Return>', return_entry)
mainloop()
*
master = Tk()
entryb1 = StringVar
Label(master, text="Input: ").grid(row=0, sticky=W)
Entry(master, textvariable=entryb1).grid(row=1, column=1)
b1 = Button(master, text="continue", command=print_content)
b1.grid(row=2, column=1)
def print_content():
global entryb1
content = entryb1.get()
print(content)
master.mainloop()
What you did wrong was not put it inside a Define function then you hadn't used the .get function with the textvariable you had set.
you need to put a textvariable in it, so you can use set() and get() method :
var=StringVar()
x= Entry (root,textvariable=var)
Most of the answers I found only showed how to do it with tkinter as tk. This was a problem for me as my program was 300 lines long with tons of other labels and buttons, and I would have had to change a lot of it.
Here's a way to do it without importing tkinter as tk or using StringVars. I modified the original mini program by:
making it a class
adding a button and an extra method.
This program opens up a tkinter window with an entry box and an "Enter" button. Clicking the Enter button prints whatever is in the entry box.
from tkinter import *
class mini():
def __init__(self):
master = Tk()
Label(master, text="Input: ").grid(row=0, sticky=W)
Button(master, text='Enter', command=self.get_content).grid(row=1)
self.entry = Entry(master)
self.entry.grid(row=0, column=1)
master.mainloop()
def get_content(self):
content = self.entry.get()
print(content)
m = mini()