I have a CheckBox in Tkinter. I want it to always stay checked but disabling the checkbox destroys the looks of the GUI application. I want to keep its state as Normal and if a user tries to uncheck it the box remains checked, or rechecks itself immediately after.
global ghistory
ghistory = IntVar()
cc = Checkbutton(frame3, text="History", variable=ghistory)
cc.select()
cc.pack()
How do I do it?
Add a function that sets the variable to True. A quick lambda function would do the trick:
cc=tk.Checkbutton(frame3,text="History",variable=ghistory, command=lambda:ghistory.set(1))
Or you could use the select command:
cc=tk.Checkbutton(frame3,text="History",variable=ghistory)
cc['command'] = cc.select
use .cget('state') to see if the button is disabled...
self.widget_checkbutton = tk.Checkbutton(self, variable=self.some_variable, command=lambda:self.stay_checked())
def stay_checked(self):
if self.widget_checkbutton.cget('state') == 'disabled':
self.widget_checkbutton.select()
else:
self.widget_checkbutton.deselect()
#this will only let the button be checked if widget is active.
(so basically, if some widget is disabled... you tell the checkbox to stay the same. else if some widget is normal, you allow the checkbox to work normally... select... deselect...)
Related
I'm trying to create a button in Tkinter that only appears (becoming visible) when it finds the word "hello" in a textbox.
I could imagine using Threads, and Global variables but i do not know how to code it,
I've imagined something like :
import Tkinter as *
from threading import Thread
window = Tk()
active = True
def check_for_word():
global active
textbox1 = textbox.get("1,0", "end")
while active == True:
if "hello" in textbox1:
button.pack()
else:
button.pack_forget()
save_button = Button(window)
textbox = scrolledtext.ScrolledText(window)
textbox.pack()
threading = Thread (target=check_for_word)
threading.start()
window.mainloop()
this is something I would suspect to work but ends up not, the button either doesn't show at all like the code isn't even running, or the thread doesn't work properly. So am I doing something wrong, if so, can you help me, please? Thank you!
You don't need to make use of threads to do this, you can use tkinter event bindings instead.
def check_for_word():
if "hello" in textbox.get("1.0", "end"):
save_button.pack()
else:
save_button.pack_forget()
save_button = Button(window)
textbox = scrolledtext.ScrolledText(window)
textbox.bind("<KeyRelease>", lambda event:check_for_word())
textbox.pack()
To make a binding, you use widget.bind. In this case, the widget is textbox and it's binding to <KeyRelease>, which is when the user releases a key. It then calls check_for_word when a key is released. (The lambda part is to ignore the event parameter). check_for_word then does what it did before.
You have to put the textbox1 assignment inside the while loop and before the if condition, otherwise it will check the value one time before entering the loop and will keep checking always the same value.
I also want to point out that the in operator is case sensitive and return True if it find even just a substring inside the variable you are checking and not just the precise single word (but I'm not shure if this is intensional).
For the while loop you don't necessarily need a global variable, you could just use while True: if you want it to continuously check the condition (if you want the button to disappear after the user cancel the word).
I'm trying to build a listbox using Tkinter and receive the selected option by clicking it.
import Tkinter as tk
from Tkinter import *
root = tk.Tk()
lst=Listbox(root, height=30, width=50)
lst.insert(1, "hy")
lst.insert(2, "hello")
lst.insert(3, "hey")
lst.pack()
sel = lst.curselection()
print sel
root.mainloop()
However, when I run the code it prints me an empty tuple before I pressed any choise.
Does someone know how to get the selected choise after I press one and not right after I run it?
Thanks a lot :)
You are getting the selection about a millisecond after creating the widget, well before the user has a chance to see the UI much less interact with it.
GUI programs are event based, meaning that things happen in response to events. Events are things like clicking buttons, inserting data into input widgets, and selecting items from listboxes.
You need to do one of two things: create a button or other widget which will get the selected item, or configure it so that a function is called whenever an item is selected.
No matter which solution you use, you will need a function that ultimately calls the curselection method of the listbox to get a list of indices. You can then call the get method to get the selected item or items.
Here's a function definition that will print the selected item, or print "no selection" if nothing is selected. So that it can be resused without modification. we'll define it to take the listbox as an argument.
Note: this example assumes the widget only supports a single select, to keep it simple:
def print_selection(listbox):
selection = listbox.curselection()
if selection:
print(f"selected item: {listbox.get(selection[0])}")
else:
print("nothing is selected")
Using a button
To call this from a button is straight-forward. We just create a button after we create the listbox, and use the command attribute to call the function. Since the function we wrote earlier needs a parameter, we'll use lambda to create a temporary function for the button.
button = tk.Button(root, text="Print Selected Item", command=lambda: print_selection(lst))
button.pack()
Calling the function when the selection is made
To call the function whenever the user changes the selection, we can bind a function to the <<ListboxSelect>> event. We'll create a separate function for this, and then pull the widget from the event object that is automatically passed to the function.
def print_callback(event):
print_selection(event.widget)
lst.bind("<<ListboxSelect>>", print_callback)
First of all, the reason you are getting an empty tuple is because you have executed the statements:
sel = lst.curselection()
print(sel)
before you have executed the root.mainloop()
Secondly, your setup for listbox fails to include a StringVar variable to hold your list.
Once the variable has been defined, you should be able to use the .insert statements to add your list items one at a time, or you can initialize the StringVar variable using a .set('hy', 'hello', 'hey') command.
To provide a return of a selected variable, you must incorporate an event handler to determine the list position selected onclick or some other triggering method.
For a pretty clear explanation of these characteristics check here
I create my radio buttons and store them in a list as a class property:
for possible_answer in self.possible_answers:
possible_answer =
R = ttk.Radiobutton(self,
text=possible_answer,
variable=var,
value=possible_answer,
command=lambda: self.set_chosen_answer(var.get()))
self.radio_buttons.append(R)
and when the users selects any of the options, I want the radio buttons to become inactive or disabled. I tried doing this in the following manner:
for radio_button in self.radio_buttons:
radio_button.state = DISABLED
The code runs without problems, the only problem I have is that I am still able to click on other buttons after this - which I do not want.
Those two lines do get called as I have verified with printing each of radio button's state right after setting it and it prints "disabled" for each of them.
What am I doing wrong? I have read through documentation and similar posts but did not find anything useful. Did I misunderstand what the disabled state means? Should I do this differently?
state is not an attribute of the widget object. It is a configuration option, which must be set by the config or configure method:
for radio_button in self.radio_buttons:
radio_button.configure(state = DISABLED)
I have created the following button in a tinter window:
resetall = Button(text = "Clear ALL", command = confirmation)
resetall.pack(side = "left")
This button "Clears" the canvas that the user is drawing on with the Python turtle, but I want this button to be enabled under CERTAIN CONDITIONS, such as if one function is running or not. I have tried this:
if draw.drawing == False:
resetall.config(state = DISABLED)
elif draw.drawing == True:
resetall.config(state = NORMAL)
to enable the button ONLY when the "draw" function is true, otherwise disable it. However, it does not seem to work, as even when the draw function becomes true, it does not get enabled. What am I doing wrong here? Any help is much appreciated! :)
Twas a very simple fix. All I had to do was make resetall a global variable, and then assign resetall.config(state = ACTIVE) to draw.
Make the variable containing a button to be a global variable and then the state of the button can be changed by using button_name.config(state=ACTIVE) or button_name.config(state=DISABLED).
Remember- once the button has been disabled you will not be able to activate it if you have changed the state of the button to disabled inside that same function. You would need another function to activate your previous button once disabled
goal
To understand how the check button works in a Tkinter menu. Especially how the value of the variable associated is changed and when the function mentioned in the command is called.
code
I have the following checkbutton that I have added to a Tkinter menu:
window = Tk()
shown = BooleanVar()
shown.set(True)
menubar = Menu(window)
optionsmenu = Menu(menubar,tearoff=0)
optionsmenu.add_checkbutton(label='Show timing after the run is completed',command=PopUp,variable=shown,onvalue = True,offvalue = False)
For simplicity the on value of the check button is true and the off value is false.
what I want to know:
Is the value of the variable changed when the check button is pressed or is the function called and the value of the variable needs to be changed explicitly?
Is the command executed before the variable is toggled or after it has been toggled??
specs
Windows XP SP3
Python 2.7
Please help me with this doubt.
The answers to your questions are as so:
Yes the variable is changed when the check button is pressed. That is the normal behavior of the check button widget.
The command is called after the value of the variable has been toggled from on to off or vice versa whatsoever be the case.