Bug with radiobutton - tkinter - python

I use Tkinter for make a GUI. I have a window with 2 radiobutton ('Yes' and 'No'), but when I select one, it don't run the script :
root = Tk()
Button(root, text='TEST', command=root.quit).pack()
root.mainloop()
master = Tk()
v = IntVar()
Radiobutton(master, text='Yes', variable=v, value=0).pack()
Radiobutton(master, text='No', variable=v, value=1).pack()
Button(master, text='Exit', command=master.quit).pack()
master.mainloop()
print(v.get())
if v.get() == 0:
testy = Tk()
Label(testy, text='Bad').pack()
testy.mainloop()
else:
testn = Tk()
Label(testn, text='Bad').pack()
testn.mainloop()
If I don't have the first window, it works but with it, it don't.
Somebody know how to fix this problem ?

You have initiated several Tk() systems, but there should be only one.
If you want to get a new window then use Toplevel()
No code is executed after mainloop() except for events. The code continues to "flow" after mainloop only after closing the windows.
So here is your code with fixes:
from tkinter import *
root = Tk()
Button(root, text='TEST', command=root.quit).pack()
master = Toplevel()
v = IntVar()
def check_radio():
print(v.get())
if v.get() == 0:
Label(Toplevel(), text='Bad').pack()
else:
Label(Toplevel(), text='Good').pack()
Radiobutton(master, text='Yes', variable=v, value=0, command=check_radio).pack()
Radiobutton(master, text='No', variable=v, value=1, command=check_radio).pack()
Button(master, text='Exit', command=master.quit).pack()
root.mainloop()
Check carefully, I changed the parents of widgets and other changes.

Possible duplicate of tkinter radiobutton not updating variable, but seeing as this question was asked first the answer may make more sense here.
Make sure you are assigning a master to the IntVar like self.rbv=tk.IntVar(master) #or 'root' or whatever you are using):
import Tkinter as tk
import ttk
class My_GUI:
def __init__(self,master):
self.master=master
master.title("TestRadio")
self.rbv=tk.IntVar(master)#<--- HERE! notice I specify 'master'
self.rb1=tk.Radiobutton(master,text="Radio1",variable=self.rbv,value=0,indicatoron=False,command=self.onRadioChange)
self.rb1.pack(side='left')
self.rb2=tk.Radiobutton(master,text="Radio2",variable=self.rbv,value=1,indicatoron=False,command=self.onRadioChange)
self.rb2.pack(side='left')
self.rb3=tk.Radiobutton(master,text="Radio3",variable=self.rbv,value=2,indicatoron=False,command=self.onRadioChange)
self.rb3.pack(side='left')
def onRadioChange(self,event=None):
print self.rbv.get()
root=tk.Tk()
gui=My_GUI(root)
root.mainloop()
try running that, click the different buttons (they are radiobuttons but with indicatoron=False) and you will see it prints correctly changed values!

Related

Copying text in tkinter from label or msgbeox

I been searching for methods to copy text to clipboard or copy the results from Tkinter gui but idk if there is a command or something
here is my code for now here the result comes in a messagebox can i copy it to clipboard
import tkinter.messagebox
import string
import random
def qs_msgbbox(): # qs_msgbbox
tkinter.messagebox.showinfo("Info", "For customer support or tip or rating contact:"
"dghaily725#gmail.com\npress the button for generated pass\nmsg will appear then copy\nthe generated password")
def gen_pass(k=9): # gen_pass
char = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!##$%^&*"
password = ''
for i in range(9):
password += random.choice(char)
tkinter.messagebox.showinfo("Password", password)
root = Tk()
root.title("Password Generator")
lbl1 = Label(root, text="Generate Password", bd=2, relief=SUNKEN, height=5, width=50, bg='black', fg='white')
lbl1.configure(font=(70))
lbl1.grid(row=0, column=2)
lbl2 = Label(root, text='For more information press the Question mark', bd=2, relief=SUNKEN, fg='red')
lbl2.configure(font=(70))
lbl2.grid(row=0, column=0, pady=10)
btn1 = Button(root, text='Press to Generate', height=5, width=50, bg='grey', command=gen_pass)
btn1.configure(font=(70))
btn1.grid(row=1, column=2, padx=460, pady=50)
btn2photo = PhotoImage(file='question.png')
btn2 = Button(root, image=btn2photo, width=30, height=30, command= qs_msgbbox)
btn2.grid(row=0, column=1)
root.mainloop()
and also just a quick small question is it better to use classes or this form
Tkinter does have a function for that, simply just
from tkinter import Tk
root = Tk()
root.clipboard_clear()
root.clipboard_append("Something to the clipboard")
root.update() # the text will stay there after the window is closed
Hope I could help
Greets
The above answer is perfectly fine. Infact its the method to do it. I read the comments, He had mentioned that it could only take in string. That is completely false. It can also take in functions. For example..
import tkinter as tk
root = tk.Tk()
#creating a entry Widget.(Labels are fine as well)
entry = tk.Entry(root)
entry.pack()
#NOW if you want to copy the whole string inside the above entry box after you
typed in #
def copy ():#assign this function to any button or any actions
root.clipboard_clear()
root.clipboard_append(entry.get()) #get anything from the entry widget.
root.mainloop()
Hoping this was helpful

Checkbox always reads 0 in popup window - Tkinter

I have a GUI using Tkinter, it has a main screen and then when you press a button a popup window appears, where you select a checkbutton and then a email will get sent to you.
Not matter what I do, I cannot read the value of the checkbutton as 1 or True it always = 0 or False.
This is my code:
import tkinter as tk
from tkinter import *
import time
root = tk.Tk()
root.title('Status')
CheckVar1 = IntVar()
def email():
class PopUp(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
popup = tk.Toplevel(self, background='gray20')
popup.wm_title("EMAIL")
self.withdraw()
popup.tkraise(self)
topframe = Frame(popup, background='gray20')
topframe.grid(column=0, row=0)
bottomframe = Frame(popup, background='gray20')
bottomframe.grid(column=0, row=1)
self.c1 = tk.Checkbutton(topframe, text="Current", variable=CheckVar1, onvalue=1, offvalue=0, height=2, width=15, background='gray20', foreground='snow', selectcolor='gray35', activebackground='gray23', activeforeground='snow')
self.c1.pack(side="left", fill="x", anchor=NW)
label = tk.Label(bottomframe, text="Please Enter Email Address", background='gray20', foreground='snow')
label.pack(side="left", anchor=SW, fill="x", pady=10, padx=10)
self.entry = tk.Entry(bottomframe, bd=5, width=35, background='gray35', foreground='snow')
self.entry.pack(side="left", anchor=S, fill="x", pady=10, padx=10)
self.button = tk.Button(bottomframe, text="OK", command=self.on_button, background='gray20', foreground='snow')
self.button.pack(side="left", anchor=SE, padx=10, pady=10, fill="x")
def on_button(self):
address = self.entry.get()
print(address)
state = CheckVar1.get()
print (state)
time.sleep(2)
self.destroy()
app = PopUp()
app.update()
tk.Button(root,
text="EMAIL",
command=email,
background='gray15',
foreground='snow').pack(side=tk.BOTTOM, fill="both", anchor=N)
screen = tk.Canvas(root, width=400, height=475, background='gray15')
screen.pack(side = tk.BOTTOM, fill="both", expand=True)
def latest():
#Other code
root.after(300000, latest)
root.mainloop()
The popup works perfectly, and the email will print when entered but the value of checkbox is always 0.
I have tried:
CheckVar1 = tk.IntVar() - No success
self.CheckVar1 & self.CheckVar1.get() - No success
Removing self.withdraw() - No success
I only have one root.mainloop() in the script, I am using app.update() for the popup window because without this it will not open.
I have checked these existing questions for solution and none have helped:
Self.withdraw - Can't make tkinter checkbutton work normally when running as script
Self.CheckVar1 - TKInter checkbox variable is always 0
Only one instance of mainloop() - Python tkinter checkbutton value always equal to 0
I have also checked very similar questions but I wasn't going to post them all.
Any help is appreciated.
The problem is that you have two root windows. Each root window gets its own internal tcl interpreter, and the widgets and tkinter variables in one are completely invisible to the other. You're creating the IntVar in the first root window, and then trying to associate it with a checkbutton in a second root window. This cannot work. You should always only have a single instance of Tk in a tkinter program.
because of variable scope
try to put CheckVar1 = IntVar() inside the class
use it with self like this
self.CheckVar1 = tk.IntVar() # object of int
self.CheckVar1.set(1) # set value
variable=self.CheckVar1 # passing to the checkbutton as parameter
state = self.CheckVar1.get() # getting value

Tkinter checkbox 'Name not defined'

I am currently writing an application that uses Tkinter to provide a graphical interface for the user.
The app has been working very well and recently I decided to add some checkboxes, the idea being that when the user checks one of the boxes, another set of text is sent through an API.
I have input boxes that I am able to get to work perfectly, however for some reason whenever I try and retrieve the value of the checkbox, I get the following error:
if check.get():
NameError: name 'check' is not defined
For the life of me I can't figure out why this error is popping up, here is the rest of my code, to make it clearer I have removed the working code for the input boxes.
from tkinter import *
class GUI:
def __init__(self, master):
check = IntVar()
self.e = Checkbutton(root, text="check me", variable=check)
self.e.grid(row=4, column=2)
self.macro_button = Button(master, text="Test Button", command=self.test)
self.macro_button.grid(row=11, column=1)
def test(self):
if check.get():
print('its on')
else:
print('its off')
root = Tk()
root.resizable(width=False, height=False)
my_gui = GUI(root)
root.mainloop()
When I run this code, and press the button labeled 'test button', that is when the error appears in my terminal.
Anyone have any idea why this is happening for my checkboxes, and not for my inputboxes?
EDIT:
what's even odder for me is that this code that I found online made to teach you how to use a tkinter checkbox works like a charm, and its almost identical to mine:
import tkinter as tk
root = tk.Tk()
var = tk.IntVar()
cb = tk.Checkbutton(root, text="the lights are on", variable=var)
cb.pack()
def showstate():
if var.get():
print ("the lights are on")
else:
print ("the lights are off")
button = tk.Button(root, text="show state", command=showstate)
button.pack()
root.mainloop()
You just need to make check an instance variable with self.
I.E
class GUI:
def __init__(self, master):
self.check = IntVar()
self.e = Checkbutton(root, text="check me", variable=self.check)
self.e.grid(row=4, column=2)
self.macro_button = Button(master, text="Test Button", command=self.test)
self.macro_button.grid(row=11, column=1)
def test(self):
if self.check.get():
print('its on')
else:
print('its off')
root = Tk()
root.resizable(width=False, height=False)
my_gui = GUI(root)
root.mainloop()
The example you found online is written in an 'inline' style - which is fine until your GUI becomes larger and you require many methods and variables to be used / passed.

Tkinter: widgets not highlighting on <Tab> event

I'm running Python 2.7.9 on a Mac. I've been unable to figure out why it is when I run my programs that only the Entry Widgets highlight each time I hit the Tab key to move to the next widget. Following is some test code. When I run the script and hit the Tab key, the first entry field is highlighted. The next time I hit the Tab key, the second entry field is highlighted. However, when I hit the tab key to move to the Button Widget, the Button is receiving the focus but there is not highlight to visually indicate to the user the focus.
The OptionMenu widget is skipped altogether, which is also a mystery. Both the radiobutton and the checkbox receives focus, just like the button widget, and again no highlight is present.
I've tried a variety of .config() arrangements to no avail. What am I missing?
from tkinter import *
class App:
def __init__(self, master):
frame = Frame(master)
frame.grid()
#Tests to make sure that Button receives focus.
def yup(self):
print "yup"
entry1 = Entry(frame)
entry1.pack()
entry2 = Entry(frame)
entry2.pack()
button1 = Button(frame, text="Test")
button1.pack()
button1.bind('<Return>', yup)
var1 = IntVar()
c = Checkbutton(frame, text="Expand", variable=var1)
c.pack()
var2 = StringVar()
radio = Radiobutton(frame, text="Test", variable=var2, value=1)
radio.pack()
var3 = StringVar()
optionmenu1 = OptionMenu(frame, var3, "one", "two", "three")
optionmenu1.pack()
root = Tk()
root.geometry('400x400+0+0')
app = App(root)
root.mainloop()
It sounds like you need to configure OS X for "Full Keyboard Access" to allow Tab to focus on all UI controls (versus just text boxes and lists).
In Yosemite (10.10), this setting can be found under System Preferences > Keyboard > Shortcuts, and can be toggled with Control+F7. Note that has nothing to do with Python, and will occur system-wide.
EDIT
So after doing some more testing, there appears to be some issues with the actual highlighting of certain widgets using tk on a Mac. Below is a condensed version of your original sample with some minor modifications for simplicity.
import Tkinter as tk
import ttk # more on this in a minute
class App(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master)
self.master = master
entry1 = tk.Entry(self)
entry1.pack()
entry2 = tk.Entry(self)
entry2.pack()
button1 = tk.Button(self, text="Test", command=self.yup)
button1.pack()
def yup(self):
print("yup")
# ...
root = tk.Tk()
app = App(root).pack()
root.mainloop()
With full keyboard access enabled as previously mentioned, I can verify that the button does indeed receive focus: on the third tab, after the first two entry widgets, hitting <space> "clicks" the button and prints to stdout. However there is no visual indication that the button is selected.
Changing the button from a tk.Button to a ttk.Button "fixes" this, and does indeed show the normal "selection" frame around the button when tabbing through the UI.
button1 = tk.Button(self, text="Test", command=self.yup)
# change this to:
button1 = ttk.Button(self, text="Test", command=self.yup)
I have no idea why this is, and I don't know what the consensus about tkinter.ttk is, but I prefer ttk to "plain" tk as it seems to produce widgets which appear more "native" to OS X in my experience. Note I also removed the bind statement, and am reporting my result using the OS X default of space to activate UI elements with full keyboard access enabled.
More on ttk here. Note also that not all tk widgets have a ttk implementation, and that there are also some ttk widgets which do not exist in tk.
Lastly below find the "ttk" version of the original snippet.
import Tkinter as tk
import ttk
class App(ttk.Frame):
def __init__(self, master):
ttk.Frame.__init__(self, master)
self.master = master
entry1 = ttk.Entry(self)
entry1.pack()
entry2 = ttk.Entry(self)
entry2.pack()
button1 = ttk.Button(self, text="Test", command=self.yup)
button1.pack()
def yup(self):
print("yup")
# ...
root = tk.Tk()
app = App(root).pack()
root.mainloop()
Hope this helps.
Try changing the background and highlightbackground colors as below but the problem is possibly because of the way the program is indented --> run the second code block.
top=Tk()
## active background
Button(top, text="Quit", bg="lightblue", activebackground="orange",
command=top.quit).grid(row=1)
top.mainloop()
##--------------- note the 3 lines that have been changed ---------
class App:
## function was not indented
def __init__(self, master):
frame = Frame(master)
frame.grid()
entry1 = Entry(frame)
entry1.pack()
entry1.focus_set()
entry2 = Entry(frame)
entry2.pack()
button1 = Button(frame, text="Test")
button1.pack()
## function called incorrectly
button1.bind('<Return>', self.yup)
var1 = IntVar()
c = Checkbutton(frame, text="Expand", variable=var1)
c.pack()
var2 = StringVar()
radio = Radiobutton(frame, text="Test", variable=var2, value=1)
radio.pack()
var3 = StringVar()
optionmenu1 = OptionMenu(frame, var3, "one", "two", "three")
optionmenu1.pack()
Button(frame, text="Quit", bg="orange", command=master.quit).pack()
## function indented too far
#Tests to make sure that Button receives focus.
def yup(self, args):
print "yup"
root = Tk()
root.geometry('400x400+0+0')
app = App(root)
root.mainloop()

Why is Tkinter Entry's get function returning nothing?

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()

Categories

Resources