Tkinter Radiobutton "indicatoron" value doesn't effect anything - python

Using Tkinter in Python 3.5, trying to create a series of radiobuttons without indicators (ie. regular push buttons). I set "indicatoron" to 0 but it still appears with indicators. I tried changing the value to 99999, 0.25, -1, and it always appears with indicators (except when I tried to set it to a string, then it told me it was expecting a boolean). What am I doing wrong?
Code snippet:
import tkinter as tk
term=tk.IntVar()
b1=tk.Radiobutton(root, text="1", variable=term, value=1, indicatoron=0).pack()
b2=tk.Radiobutton(root, text="2", variable=term, value=2, indicatoron=0).pack()
b3=tk.Radiobutton(root, text="3", variable=term, value=3, indicatoron=0).pack()
b4=tk.Radiobutton(root, text="4", variable=term, value=4, indicatoron=0).pack()

It appears to not work on OSX. In essence this flag does not work for radiobuttons or checkbuttons, and has not for many years.
This is the reason given by the TK team ...
it is mapped to a specific Cocoa button style (NSSwitchButton) that does not allow us to turn off the checkmark
The full official response (back in 2012), in regards to the checkbutton is ...
wordtech added on 2012-11-07 22:02:38:
As discussed in the Tkinter mailing list:
"After looking at the code that implements the checkbutton, it appears that, internally, it is mapped to a specific Cocoa button style (NSSwitchButton) that does not allow us to turn off the checkmark. I suppose we'll have to add this to the list of Tk configuration flags that are ignored in certain contexts when Mac-native widgets are used (background, relief, etc.). "
This is the less useful responce to the problem logged against the radiobutton ... It works for me
It is unclear why some people on OSX seem to have this working.

Related

How can I change the colour of a button when clicked at runtime? [duplicate]

This question already has answers here:
List of All Tkinter Events
(3 answers)
Closed 2 years ago.
button1=Button(root,text="A1",width=8).grid(row=0,column=0)
button2=Button(root,text="A2",width=8).grid(row=0,column=1)
label1=Label(root,text=" ",padx=20).grid(row=0,column=2)
button22=Button(root,text="A3",width=8).grid(row=0,column=3,sticky='E')
button23=Button(root,text="A4",width=8).grid(row=0,column=4,sticky='E')
I'm trying to make seat arrangement system for a school project. I have an issue: how can I change the colour of the button once it is clicked? I want to change the colour of the booked and available seats once I click on that button.
If you just wish to change the color of a button when clicked, you need to use the .config() method on that button widget.
for example, if a button is defined like
aButton = tk.Button(root, text='change my color').pack()
then to change the color (or pretty much everything related to that widget like text, command or whatever) call the method
aButton.configure(bg='#f0f', fg='#fff') # change to your required colors, bg is background, fg is foreground.
OR .config() can be also be used (these 2 methods do exactly the same)
aButton.config(bg='#f0f', fg='#fff')
Now how will you know when a button is clicked or not. The simplest and intuitive way is to define functions and connect (or bind) them to buttons. Now how you wanna do that is totally up to the user's preferences. Some prefer to create separate different functions for all buttons, some only like to create one.
For your case though, as you don't need to do anything additional than changing colors then single function is enough.
Important In the example code below, I have used lambda functions, a special type of functions, which don't need to be defined separately. That however, by no means, is necessary
Working example for you
from tkinter import * # I don't recommend using global import. better use "import tkinter as tk"
root = Tk()
button1=Button(root,text="A1",width=8, command=lambda: button1.config(bg='#f00'))
button1.grid(row=0,column=0)
button2=Button(root,text="A2",width=8, command=lambda: button2.config(bg='#f00'))
button2.grid(row=0,column=1)
Label(root,text=" ",padx=20).grid(row=0,column=2)
button22=Button(root,text="A3",width=8, command=lambda: button22.config(bg='#f00'))
button22.grid(row=0,column=3,sticky='E')
button23=Button(root,text="A4",width=8, command=lambda: button23.config(bg='#f00'))
button23.grid(row=0,column=4,sticky='E')
root.mainloop()
Using functions
from tkinter import * # I don't recommend using global import. better use "import tkinter as tk"
def changeColor(btn):
# Use your own highlight background argument here instead of bg
btn.configure(bg='#f00')
root = Tk()
button1=Button(root,text="A1",width=8, command=lambda: changeColor(button1))
button1.grid(row=0,column=0)
button2=Button(root,text="A2",width=8, command=lambda: changeColor(button2))
button2.grid(row=0,column=1)
Label(root,text=" ",padx=20).grid(row=0,column=2)
button22=Button(root,text="A3",width=8, command=lambda: changeColor(button22))
button22.grid(row=0,column=3,sticky='E')
button23=Button(root,text="A4",width=8, command=lambda: changeColor(button23))
button23.grid(row=0,column=4,sticky='E')
root.mainloop()

Having trouble updating int label but can update string label fine

I'm sure someone is going to mark this as a duplicate the second I post it, but I assure you, I've been looking for hours. I'm brand new to tkinter so bear with me as I'd like a really straightforward answer if possible. Anything related to this specifically was a bit complex for me right now and I didn't feel it answered my question.
I know how to have a Label update with textvariable and StringVar. However, I'm trying to update an integer and I can't seem to figure it out for some reason. The number updates and prints through the console but I can't figure out the right syntax to get it to show up on the interface. It either just shows 0 (as the default variable shows) or there is no text there at all depending on what I've changed the code to)
So all I'm doing is simply incrementing a number. Let's leave it at that for now. And if anyone has any resources to more straightforward documentation please let me know because it seems tkinter in general is pretty obscure in documentation online as far as I can tell.
my_count = 0
def increase_mycount():
global my_count
increment = int(my_count) + 1
my_count = str(increment)
print(my_count)
Label(root, textvariable=my_count).grid(row=2, column=1)
Button(root, text="+", command=inc_mycount).grid(row=3, column=2)
This is where it's at right now, I've tried changing my_count into an IntVar and also a StringVar and I get an error saying I can't use + with int and intvar or int with stringvar
Is there something really simple I'm missing? I'm struggling finding comprehensive documentation on tkinter. It's easy to find Python information but not this really.. I'm in the process of organizing all the info I'd like into some google docs.
Thank you for any time you give. This seems like it should be a really simple thing to do but I've only worked with engines that update things for me. I'm only use tkinter, a .py file, and cmd for this.
And another note, I can't use .set() for this either it seems, like I could for a string. So I'm just struggling with the syntax unless there is a different method for numbers on labels.
You have to use one of tkinter's variable objects when using textvariable. In this case, IntVar.
import tkinter as tk
root = tk.Tk()
my_count = tk.IntVar()
def increase_mycount():
current = my_count.get()
my_count.set(current+1)
tk.Label(root, textvariable=my_count).grid(row=2, column=1)
tk.Button(root, text="+", command=increase_mycount).grid(row=3, column=2)
root.mainloop()

My Radiobutton is checked on creation

My problem is that when creating a Radiobutton it is automatically checked and i can't uncheck it. I create it inside a frame of x and y dimensions.
I've tried the .deselect() function but it changes nothing
(Python 3.6)
code:
frm = ttk.Frame(root)
frm.place(x=0,y=0,width=1000,height=1000)
Ek = ttk.Radiobutton(frm,text="text")
Ek.place(x=100,y=400)
And photo of it:
photo
First, if we just wanted to modify your code to give us a single unchecked radio button all by itself, this would do the trick.
from tkinter import Tk, IntVar, Radiobutton, mainloop, ttk
root = Tk()
frm = ttk.Frame(root)
frm.place(x = 0, y = 0, width = 1000, height = 1000)
v = IntVar()
Ek = ttk.Radiobutton(frm, text = "text", variable = v, value = 1)
Ek.place(x = 100, y = 100)
mainloop()
Aside from the boilerplate for setup at the beginning and end, the only thing we had to change in your original code was to add the arguments variable = v, value = 1 to the Radiobutton call.
Those extra arguments don't really make sense in isolation, for the same reason that it doesn't generally make sense to have a single radio button. Once we add two of them, we can see what's going on a bit better.
In the documentation #Stack posted (this thing), the first code sample looks like this:
from Tkinter import *
master = Tk()
v = IntVar()
Radiobutton(master, text="One", variable=v, value=1).pack(anchor=W)
Radiobutton(master, text="Two", variable=v, value=2).pack(anchor=W)
mainloop()
If we run that, we get two unchecked radio buttons by default. If we then change the value=1 part to value=0, the first radio button shows up checked, and if we change value=2 to value=0, the second radio button shows up checked. So value=0 seems to give us buttons that are checked by default, but we don't know why yet. Let's experiment a bit more.
If we try to delete pieces in the new sample until we get back to something more closely resembling what you wrote originally, we can sort of see what happened. Deleting the value arguments entirely and running it like this:
Radiobutton(master, text="One", variable=v).pack(anchor=W)
Radiobutton(master, text="Two", variable=v).pack(anchor=W)
leaves us with neither button checked by default, though then further deleting the variable arguments to make the code look like your original call:
Radiobutton(master, text="One").pack(anchor=W)
Radiobutton(master, text="Two").pack(anchor=W)
gives us two buttons that are both checked by default, which gets us back to your original problem.
Basically, we're running into various odd corner cases here because we just started fiddling with code and forgot what a radio button actually represents.
What the concept of a radio button represents in the first place is the value of a variable. Not the entire variable, just one of the things it might be equal to. And the set of radio buttons itself, taken together, gives us a visual representation of a discrete variable: a thing that can be in 1 of N states.
So the API for Radiobuttons, naturally, is asking us for some information like "what python variable do you want us to use to hold these values?" (that's roughly the variable keyword) and "what values do you want us to glue to each of these buttons behind the scenes to distinguish the different states?" (that's the value keyword).
As expected, the code works best in the case above where the values were 1 and 2, because in that case the code is properly reflecting what a radio button actually is, conceptually. When we collide the values or set them to zero or leave them out entirely, things get a bit weird and less predictable because we're then dealing with the implementation details of the tkinter API, rather than with the simple concept of a radio button that the API is meant to implement.
Laptop's about to die, so I'm gonna go ahead and hit send. Hope that wasn't too wordy. Good luck. :)
Radiobuttons need to be associated with one of the special Tkinter variables (StringVar, etc), and are designed to work in groups of two or more. If you don't specify a variable, one will be created for you. The default value of a Radiobutton is the empty string, which is also the default variable will be set to.
Just assign a different value to the declared variable
from tkinter import Tk, IntVar, Radiobutton, mainloop, ttk
root = Tk()
frm = ttk.Frame(root)
frm.place(x=0,y=0,width=100,height=400)
language=StringVar(value='portuguese')
Ek = ttk.Radiobutton(frm,variable="language",text="spanish",value="spanish")
Ek.place(x=10,y=50)
Ek = ttk.Radiobutton(frm,variable="language",text="english",value="english")
Ek.place(x=10,y=85)
mainloop()

Creating GUI with multiple function buttons

I am trying to create a GUI as shown in the attached picture
I wrote the following code which does the job but not the way I need it to.
try:
import Tkinter as tk
import tkMessageBox as mb
except ImportError:
import tkinter as tk
import tkinter.messagebox as mb
root = tk.Tk()
root.geometry("500x300")
tk.Label(root, text="Python First GUI Template", bg="goldenrod", font="bold").pack()
tk.Label(root, text="").pack()
def addFn():
a = int(input('enter first number'))
b = int(input('enter second number'))
mb.showinfo('showinfo', a+b)
def subtractFn():
a = int(input('enter first number'))
b = int(input('enter second number'))
mb.showinfo('showinfo', a - b)
tk.Button(root, text="Add Function", bg="SkyBlue1", command=addFn).pack()
tk.Label(root, text="").pack()
tk.Button(root, text="Subtract Function", bg="SkyBlue1", command=subtractFn).pack()
root.mainloop()
So, I have the following problems:
(1) I am not able to create the design as I want in the attached picture in terms of relative color and relative location of "add" and "subtract" buttons.
(2) When I hit the buttons to activate "add" or "subtract" functions, the inputs are required on the console. I need a pop up with input box and drop down for two numbers I want to add. I am looking for following format for "add" function.
(3) I want to add a "quit" button to close the console when I am done
I'm new to this myself, and unfortunately can't answer most of your questions, but regarding the quit button, I'm thinking you can write a function that calls quit(), just like you would type in order to exit the Python interactive interpreter. Then you link that function to a button just as you did for the first two buttons. This is the same idea with a lambda expression:
from tkinter import *
root =Tk()
root.geometry("500x300")
Button(root,text="QUIT",bg='Red',command=lambda:(quit())).pack(side=BOTTOM)
root.mainloop()
This here is a TKinter frame that gives you a red quit button at the bottom whose sole reason for existence is to quit the frame it's in.
Regarding the layout, I think the pack method requires you to indicate where pack should prefer to put the widget, but doesn't give you much absolute control. Wouldn't grid method allow for better alignment?
Why do your input boxes have to pop out? Why can't they be embedded into the app frame? I would think that would eliminate some difficulty with the issue, no?
Sorry this isn't the most helpful answer ever... but I hope it gives you something to work with until someone more knowledgeable happens by. Cheers.
There are a couple of ways you could do this, the simplest being using .grid() instead of .pack():
from tkinter import *
root = Tk()
title = Label(root, text="Python First GUI Template")
add = Button(root, text="Add")
subtract = Button(root, text="Subtract")
_quit = Button(root, text="Quit")
title.grid(row=0, column=1, padx=5, pady=5)
add.grid(row=1, column=0, padx=5, pady=5)
subtract.grid(row=1, column=2, padx=5, pady=5)
_quit.grid(row=2, column=3, padx=5, pady=5)
root.mainloop()
.grid() allows you to place widgets on the window in a grid fashion, imagine there are cells which you are placing each widget into, whereas .pack() by default will place items stacked on top of eachother unless certain attributes are given values.
You could also use .place() which allows you to place the widgets based on coordinates but this requires a lot more effort make responsive to window size changes or adding new widgets and the like.
On a side note, Stack Overflow is not a free programming resource, we will not write programs for you based on a list of demands. There are plenty of freelance programmers who are happy to do that in exchange for money. I would recommend in future that rather than asking a question about an incredibly well documented library with over 17000 questions on Stack Overflow, a large number of which are about the difference in the three geometry managers you instead find a tutorial or ask a colleague, schoolmate, teacher or friend for help.

tkinter puts WAY too much space between checkbuttons

I can't figure out how to get tkinter to put checkbuttons and radiobuttons closer together. Even specifying pady=0 anyplace it seems valid has no effect. The vertical distance between the buttons is unnaturally large, ugly, and just wastes space. In order to make a set of buttons appear as a group separate from other controls requires that I add extra space elsewhere, which just gets out of control.
Here's a working example I extracted:
from Tkinter import *
def rbtest(frame):
group = LabelFrame( frame, text="Target", padx=0, pady=0)
btnVal = StringVar(frame,' ')
for b in ( "option1", "another option", "Someth Else", "go away"):
rb=Radiobutton( group, text=b, value=b, variable=btnVal)
rb.pack( anchor=W, pady=2)
boardname = StringVar()
Label( group, text="Name").pack( anchor=W)
Entry( group, text=boardname).pack()
group.pack( side=LEFT, fill=Y, padx=0, pady=0)
tk = Tk()
rbtest(tk)
tk.mainloop()
[Well, I can't post an image showing what it produces because I don't have enough reputation, so sorry about that... I tried.]
Edit: I'm using Python 2.6.6 and Windows 7.
Considering how closely together it packs other elements, I'm surprised this is normal behavior, but all the examples I've found on the web look similar...
I ran your code on a Mac and on a windows box, and in both cases it looked about right to me. If you want them literally as close as possible, set the borderwidth to zero and the pady option to zero.
To eek out another two pixels between each button, set the highlightthickness to zero, though that affects the user experience when they are using keyboard traversal.
It looks pretty normal to me:
If it really needs to be made super-compact, there are ways of doing so, but I suspect your system is rendering the window differently.

Categories

Resources