Tkinter Radiobuttons autoselect and always on...Python 2.7 - python

I am trying to create a GUI for one of my school projects and I have an issue with the radio buttons... When I run the script the radio buttons automatically activate and the stay on.
from Tkinter import *
def sel():
label.config(text = "You have selected 'HOSTS'")
target = "hosts"
def selnet():
label.config(text = "You have selected 'NETWORKS'")
target = "networks"
root = Tk()
var = StringVar()
var2 = IntVar()
R1 = Radiobutton(root, text = "HOSTS", var = 'hosts', value = 1, command = sel)
R1.pack(anchor = W)
R2 = Radiobutton(root, text = "NETWORKS", var = 'networks', value = 2, command = selnet)
R2.pack(anchor = W)
label = Label(root)
label.pack()
root.mainloop()

Add an option 'variable' to link two radiobuttons. E.g. (look at the end of RadioButton constructors):
R1 = Radiobutton(root, text = "HOSTS", var = 'hosts', value = 1, command = sel, variable=var2)
R1.pack(anchor = W)
R2 = Radiobutton(root, text = "NETWORKS", var = 'networks', value = 2, command = selnet, variable=var2)
R2.pack(anchor = W)

Related

Get variable value created inside a function

I want to get a variable from a function to use this variable in another function.
Simple example:
from tkinter import *
def test():
intro = "I am "
name = "Phil"
text = intro + name
def printresult():
print(text)
root = Tk()
root.title("Test")
testbutton = Button(root, text="Test", command = test)
printbutton = Button(root, text="print Test", command = printresult)
testbutton.grid(row = 1, column = 0)
printbutton.grid(row = 1, column = 1)
mainloop()
If I press the testbutton and afterwards the printbutton, then I get the error "name 'text' is not defined".
So how am I able to get the text variable from the def test() to use it in the def printresult()?
You need to save the value somewhere well known:
from tkinter import *
def test():
intro = "I am "
name = "Phil"
text = intro + name
test.text = text # save the variable on the function itself
def printresult():
print(test.text)
root = Tk()
root.title("Test")
testbutton = Button(root, text="Test", command = test)
printbutton = Button(root, text="print Test", command = printresult)
testbutton.grid(row = 1, column = 0)
printbutton.grid(row = 1, column = 1)
mainloop()
Since you are using tkinter, I'd use a StringVar to store the result. Using a string var makes it easy for other tkinter widgets to use the value.
from tkinter import *
def test():
intro = "I am "
name = "Phil"
text.set(intro + name)
def printresult():
print(text.get())
root = Tk()
root.title("Test")
text = StringVar()
testbutton = Button(root, text="Test", command = test)
printbutton = Button(root, text="print Test", command = printresult)
testbutton.grid(row = 1, column = 0)
printbutton.grid(row = 1, column = 1)
mainloop()

Random tkinter window opening on if/else statement

I'm wondering if I got my if else statement wrong or if its a tkinter issue. I want it so that if a 0 is left in any or all boxes, it gives an error message. But after the error message is closed, it opens a random blank window. This is my code. The specific area is the if else statement within the function valueget()
import tkinter as tk
def mainwindow():
mainwindow = tk.Tk()
mainwindow.title('Enter values')
mainwindow.geometry('160x110')
mainwindow.config(bg='#aaf0d1')
tk.Label(mainwindow, text = 'Enter a', font = ('verdana'), bg='#aaf0d1').grid(row=0)
tk.Label(mainwindow, text = 'Enter b', font = ('verdana'), bg='#aaf0d1').grid(row=1)
tk.Label(mainwindow, text = 'Enter c', font = ('verdana'), bg='#aaf0d1').grid(row=2)
getA = tk.IntVar()
aBox = tk.Entry(mainwindow, textvariable = getA, width=3, bg='#aaf0d1')
aBox.grid(row=0, column=1)
aBox.config(highlightbackground='#aaf0d1')
getB = tk.IntVar()
bBox = tk.Entry(mainwindow, textvariable = getB, width=3, bg='#aaf0d1')
bBox.grid(row=1, column=1)
bBox.config(highlightbackground='#aaf0d1')
getC = tk.IntVar()
cBox = tk.Entry(mainwindow, textvariable = getC, width=3, bg='#aaf0d1')
cBox.grid(row=2, column=1)
cBox.config(highlightbackground='#aaf0d1')
button = tk.Button(mainwindow, text='Obtain roots', command = lambda: valueget(), font = ('verdana'), highlightbackground='#aaf0d1')
button.grid(row=4)
button.config(bg='#aaf0d1')
def valueget():
readA = getA.get()
readB = getB.get()
readC = getC.get()
intA = int(readA)
intB = int(readB)
intC = int(readC)
negroot = (readB**2)-(4*readA*readC)
quadformulaplus = (-readB + (pow(negroot,0.5)))/(2*readA) #quad forumla
quadformulaminus = (-readB - (pow(negroot,0.5)))/(2*readA) #quad forumla
messagewindow = tk.Tk()
messagewindow.geometry('290x50')
messagewindow.title('Roots of the equation')
messagewindow.config(bg='#aaf0d1')
if readA == 0 or readB==0 or readC==0 or (readA==0 and readB==0 and readC==0):
errorwindow = tk.messagebox.showerror(message='none').pack()
else:
label = tk.Label(messagewindow, text = f'The roots are {quadformulaplus:.1f} and {quadformulaminus:.1f}', bg='#aaf0d1', font = ('verdana'))
label.grid(row=1)
closebutton = tk.Button(messagewindow, text='Close', command = lambda: messagewindow.destroy(), font = ('verdana'), highlightbackground='#aaf0d1')
closebutton.grid(row=2)
closebutton.config(bg='#aaf0d1')
messagewindow.mainloop()
# print(f'the roots are {quadformulaplus:.1f} and {quadformulaminus:.1f}')
mainwindow.mainloop()
def startup():
startpage = tk.Tk()
startpage.title('Solver')
photo = tk.PhotoImage(file = r"/Users/isa/Desktop/DiffEqns/cover.png") #image load
coverbutton = tk.Button(startpage, image = photo, command = lambda: [startpage.destroy(), mainwindow()])
coverbutton.pack()
coverbutton.configure(highlightbackground='#aaf0d1')
startpage.mainloop()
startup()
Here's a basic idea of what I would do:
import tkinter as tk
from tkinter import messagebox
def mainwindow(root):
# Creates a toplevel window
mainwindow = tk.Toplevel()
mainwindow.protocol("WM_DELETE_WINDOW", root.destroy) # This overrides the "X" being clicked to also destroy the root window.
root.withdraw() # "Hides" the root window, leaving it (and mainloop) running in the background.
mainwindow.title('Enter values')
mainwindow.geometry('160x110')
mainwindow.config(bg='#aaf0d1')
# Since all three of the labels/entries are the same
# we can save space by generating them in a loop
entry_items = ('Enter a', 'Enter b', 'Enter c')
values = []
for x, item in enumerate(entry_items): # Using enumerate and x to assign rows
tk.Label(mainwindow, text = item,
font = ('verdana'), bg='#aaf0d1').grid(row=x) # Row assigned to x.
values.append(tk.StringVar()) # Appended StringVar to list.
tk.Entry(mainwindow,
textvariable = values[-1], # Uses the last value appended to the values list.
highlightbackground='#aaf0d1',
width=3,
bg='#aaf0d1').grid(row=x, column=1) # Row assigned to x.
tk.Button(mainwindow,
text='Obtain roots',
command = lambda vals = values: valueget(vals), # Here the button command is assigned with the values list
font = ('verdana'), bg='#aaf0d1',
highlightbackground='#aaf0d1').grid(row=3) # we know there are 3 items before this.
mainwindow.lift() # This is a method of bringing a window to the front
def valueget(vals):
# This line gets the values from the StringVars, converts them to ints,
# and returns them to their respective variables.
try:
readA, readB, readC = [int(val.get()) for val in vals]
except ValueError:
messagebox.showerror(title="Number Error", message='Values must be numbers')
return
# Here the variables are checked to see if they are 0
# Since each one is being checked if it is 0, there is no need to check if they are all 0.
for val in (readA, readB, readC):
if val == 0:
# If they are 0, shows an error message
messagebox.showerror(title="Zero Error", message='Values must not be zero')
return
# Creates a toplevel to display the results
messagewindow = tk.Toplevel()
messagewindow.title('Roots of the equation')
messagewindow.config(bg='#aaf0d1')
negroot = (readB**2)-(4*readA*readC)
quadformulaplus = (-readB + (pow(negroot,0.5)))/(2*readA) #quad forumla
quadformulaminus = (-readB - (pow(negroot,0.5)))/(2*readA) #quad forumla
tk.Label(messagewindow,
text = f'The roots are {quadformulaplus:.1f} and {quadformulaminus:.1f}',
bg='#aaf0d1',
font = ('verdana')).pack(padx = 5, pady = 2)
tk.Button(messagewindow,
text='Close',
command = messagewindow.destroy, # There is no need for a lambda for this.
font = ('verdana'),
bg = '#aaf0d1',
highlightbackground='#aaf0d1').pack(padx = 5, pady = 2)
# print(f'the roots are {quadformulaplus:.1f} and {quadformulaminus:.1f}')
messagewindow.lift() # This is a method of bringing a window to the front
def startup():
startpage = tk.Tk()
startpage.title('Solver')
# COMMENTED OUT FOR TESTING
#photo = tk.PhotoImage(file = r"/Users/isa/Desktop/DiffEqns/cover.png") #image load
coverbutton = tk.Button(startpage,
# COMMENTED OUT FOR TESTING
#image = photo,
text = "TESTING", # HERE FOR TESTING
highlightbackground='#aaf0d1',
command = lambda root = startpage: mainwindow(root)).pack() # Passes the startpage to the mainwindow function.
startpage.mainloop() # The only mainloop you need.
startup()
I would recommend to improve the readability of the if-else statement for a start.
coefficients = [readA, readB, readC]
if sum(coefficients): # If they all are all zeros this will be False
if min(coefficients): # If any one is zero, this will be False
label = tk.Label(messagewindow, text = f'The roots are {quadformulaplus:.1f} and {quadformulaminus:.1f}', bg='#aaf0d1', font = ('verdana'))
label.grid(row=1)
closebutton = tk.Button(messagewindow, text='Close', command = lambda: messagewindow.destroy(), font = ('verdana'), highlightbackground='#aaf0d1')
closebutton.grid(row=2)
closebutton.config(bg='#aaf0d1')
else:
errorwindow = tk.messagebox.showerror(message='none').pack()
else:
errorwindow = tk.messagebox.showerror(message='none').pack()

creating button with tkinter

I was really curious why I cannot get my add_button to work,
as the window fails to come up when creating it.
from tkinter import *
class Calculator:
#-------------------------------------------------
def __init__(self, master):
self.master = master
master.title("Calculator")
self.close_button = Button(master, text = "Close", command = master.destroy)
Label(master, text = "First Digit").grid(row = 0)
Label(master, text = "Second Digit").grid(row = 1)
self.input1 = 0
self.input2 = 0
input1 = Entry(master)
input2 = Entry(master)
input1.grid(row = 0, column = 1)
input2.grid(row = 1, column = 1)
self.close_button.grid(row = 2, column = 0)
self.add_buton = Button(master, text = "Add", command = self.add())
self.add_button.grid(row = 2, column = 1)
master.configure(background = 'grey')
return
#-------------------------------------------------
def add(self):
return self.input1.get() + self.input2.get()
#-------------------------------------------------
#-------------------------------------------------
root = Tk()
calc = Calculator(root)
root.mainloop()
#-------------------------------------------------
Welcome to Stack!
I've looked through you code I've been able to do what you are asking. There were a few errors within your code:
a) you had self.add_buton and self.add_button which caused an error.
b) self.input1 = 0 and self.input2 = 0 are not required.
c) You were calling self.add() as the command and you should be calling self.add. When calling it as a command you do not need ()
d)input1 = Entry(master) should be self.input1 = tk.Entry(master)
e) You should convert your input values into int or float as otherwise it will just one value onto the end of the other. (Eg, 1 + 5 = 15 whereas int(1) + int(5) = 6
Here is your code with the entry boxes working as they should. I have import tkinter as tk hence why it is tk.Entry
from tkinter import *
import tkinter as tk
class Calculator:
#-------------------------------------------------
def __init__(self, master):
self.master = master
master.title("Calculator")
self.close_button = Button(master, text = "Close", command = master.destroy)
Label(master, text = "First Digit").grid(row = 0)
Label(master, text = "Second Digit").grid(row = 1)
self.input1 = tk.Entry(bd=5, width=35, background='gray35', foreground='snow')
self.input2 = tk.Entry(bd=5, width=35, background='gray35', foreground='snow')
self.input1.grid(row = 0, column = 1)
self.input2.grid(row = 1, column = 1)
self.close_button.grid(row = 2, column = 0)
self.add_button = tk.Button(master, text = "Add", command = self.add)
self.add_button.grid(row = 2, column = 1)
master.configure(background = 'grey')
return
#-------------------------------------------------
def add(self):
val = self.input1.get()
print(val)
#-------------------------------------------------
#-------------------------------------------------
root = Tk()
calc = Calculator(root)
root.mainloop()
This should now work how you wanted it too. The variables within the entry can be changed to suit. You were correct in calling the value of the entry with self.input1.get().
Hope this has helped.

how to get the the value from the entry widget in tkinter in python3.6

I'm trying to get the data from the entry box.I'm not getting the use of those variables. It's showing me blank when I try to print the result. I tried using lambda but still not working. I'm new at this. Please show me where I'm wrong. I tried online but they are older version solutions.
def insertdata(E1):
print(E1)
e1 = StringVar()
L1 = Label(F1, text ="Serial No:",anchor = E)
L1.grid(row = 0 ,column = 0)
E1 = Entry(F1,textvariable = e1)
E1.grid(row = 0 ,column = 2, sticky = N)
v1 = e1.get()
Button (F2,text = "Paid",command=lambda:insertdata(v1)).pack(side= TOP)
This how to get content in entry widget and print. With the code you posted, you are doing a lot of wrong things; you cannot use pack and grid to postion your widget in the same window. Also never do this: Button (F2,text = "Paid",command=lambda:insertdata(v1)).pack(side= TOP), but always position your layout manager on the next line.
EXAMPLE
b = Button (F2,text = "Paid",command=lambda:insertdata(v1))
b.pack(side= TOP)
FULL CODE
from tkinter import *
def insertdata():
print(e1)
print(E1.get())
root = Tk()
L1 = Label( text="Serial No:", anchor=E)
L1.grid(row=0, column=0)
e1 = StringVar()
E1 = Entry( textvariable=e1)
E1.grid(row=0, column=2, sticky=N)
b = Button( text="Paid", command=insertdata)
b.grid(row=10, column=30)
root.mainloop()
You have set v1 to e1.get() before anything could be entered into the entry.
I tried the following code, and it works fine.
from tkinter import * # SHOULD NOT USE.
F1=Tk()
F2=Tk()
def insertdata(E1):
print(E1)
e1 = StringVar()
L1 = Label(F1, text ="Serial No:",anchor = E)
L1.grid(row = 0 ,column = 0)
E1 = Entry(F1,textvariable = e1)
E1.grid(row = 0 ,column = 2, sticky = N)
Button (F2,text = "Paid",command=lambda:insertdata(e1.get())).pack(side= TOP) # SHOULD NOT USE.

python TypeError when using OptionMenu Tkinter [duplicate]

This question already has answers here:
Why is my Button's command executed immediately when I create the Button, and not when I click it? [duplicate]
(5 answers)
Closed 6 years ago.
ive currently been trying to build a GUI application in Tkinter that takes user input from an Entry and subsiquently populate a drop down menu. The probelm is that the OptionMenu keeps throwing:
Traceback (most recent call last):
File "C:/Python34/food2GUIree.py", line 70, in <module>
mealOneButton = Button(root, text = "query database", command = GetEntry(mealOneString))
File "C:/Python34/food2GUIree.py", line 68, in GetEntry
meal = OptionMenu(root, '', *getMeal).pack()
TypeError: __init__() missing 1 required positional argument: 'value'
when i replace getMeal in:
def GetEntry(x):
formatted = x.get().split()##gets the entry and forms a list
getMeal = CsvLoadSearch(u, formatted)
meal = OptionMenu(root, '', *getMeal).pack()
with list = [1,2,3,4] or any other list it works fine. why is this?
bellow is the complete program:
from tkinter import *
from tkinter import ttk
import csv
import os
u = "C:\\Users\\luke daniels\\Documents\\fooddata.csv"
"""
Loads csv and compares elements from foodList with current row.
returns a list of rows that match elements in foodList.
"""
def CsvLoadSearch(u, foodList):
results = []
inputfile = open(u)
for row in csv.reader(inputfile):
for food in foodList:
if food in row[0]:
results.append(row[0])
##print(row)
return results
root = Tk()
root.title("MacroCalc")
caloriesAim = StringVar()
protien = StringVar()
fat = StringVar()
carbs = StringVar()
mealOneString = StringVar()
mealTwoString = StringVar()
mealThreeString = StringVar()
mealFourString = StringVar()
mealFiveString = StringVar()
mealSixString = StringVar()
mealOneKeyword = Entry(root, textvariable = mealOneString)
mealTwoKeyword = Entry(root, textvariable = mealTwoString)
mealThreeKeyword = Entry(root, textvariable = mealThreeString)
mealFourKeyword = Entry(root, textvariable = mealFourString)
mealFiveKeyword = Entry(root, textvariable = mealFiveString)
mealSixKeyword = Entry(root, textvariable = mealSixString)
mealLabel = Label(root,text = "meals")
mealLabel.config(font=("Courier", 30))
mealLabel.pack()
mealLone = Label(root,text = "meal one")
mealLtwo = Label(root,text = "meal two")
mealLthree = Label(root,text = "meal three")
mealLfour = Label(root,text = "meal four")
mealLfive = Label(root,text = "meal five")
mealLsix = Label(root,text = "meal six")
caloriesLabel = Label(root,text = "calories needed").pack()
calories = Text(root, height = 1, width = 10).pack()
protienLabel= Label(root,text = "protien ratio").pack()
protien = Text(root, height = 1, width = 4).pack()
carbsLabel = Label(root,text = "carbohydrate ratio").pack()
carbs = Text(root, height = 1, width = 4).pack()
fatsLabel = Label(root,text = "fats ratio").pack()
fats = Text(root, height = 1, width = 4).pack()
displayText = Text(root).pack(side = RIGHT)
def GetEntry(x):
formatted = x.get().split()##gets the entry and forms a list
getMeal = CsvLoadSearch(u, formatted)
meal = OptionMenu(root, '', *getMeal).pack()
mealOneButton = Button(root, text = "query database", command = GetEntry(mealOneString))
mealTwoButton = Button(root, text = "query database", command = GetEntry(mealTwoString))
mealThreeButton = Button(root, text = "query database", command = GetEntry(mealThreeString))
mealFourButton = Button(root, text = "query database", command = GetEntry(mealFourString))
mealFiveButton = Button(root, text = "query database", command = GetEntry(mealFiveString))
mealSixButton = Button(root, text = "query database", command = GetEntry(mealSixString))
mealButtons = [mealOneButton, mealTwoButton, mealThreeButton, mealFourButton, mealFiveButton, mealSixButton]
mealKeywords = [mealOneKeyword, mealTwoKeyword, mealThreeKeyword, mealFourKeyword, mealFiveKeyword, mealSixKeyword]
mealLabels = [mealLone, mealLtwo, mealLthree, mealLfour, mealLfive, mealLsix]
##meals = [mealOne, mealTwo, mealThree, mealFour, mealFive, mealSix]
##packs the drop downs and respective lables
i = 0
while i < len(mealLabels):
mealLabels[i].pack()
mealKeywords[i].pack()
mealButtons[i].pack()
##meal.pack()
i = i + 1
root.mainloop()
throw away lambda function is needed after command when creating the buttons

Categories