overlapping statuses using tkinter module - python

I am trying to work on GUI using tkinter module. I created label with random greetings generator. However,they are overlapping with previous generated labels.This is the code:
import tkinter
import random
window = tkinter.Tk()
# to rename the title of the window
window.title("GUI")
window.geometry("500x500")
#defining Functions
def search_greetings():
phrases = ["Hallo ", "Hoi ", "Greetings "]
name = str(entry1.get())
text = ".Please enter your search term below."
return phrases[random.randint(0, 2)] + name + text
def search_display():
greeting = search_greetings()
# This creates the text field
greeting_display = tkinter.Label(window,text = search_greetings())
greeting_display.grid(row=6,column=1)
search_box = tkinter.Entry()
search_box.grid(row=7)
# pack is used to show the object in the window
label = tkinter.Label(window, text = "Hello World! Welcome to my app")
label.grid(row = 0)
# creating 2 text labels and input labels
tkinter.Label(window, text = "Username").grid(row = 2) # this is placed in 1 0
# 'Entry' is used to display the input-field
entry1 = tkinter.Entry()
entry1.grid(row = 2, column = 1) # this is placed in 1 1
tkinter.Label(window, text = "Password").grid(row = 3) # this is placed in 2 0
tkinter.Entry().grid(row = 3, column = 1) # this is placed in 2 1
# 'Checkbutton' is used to create the check buttons
tkinter.Checkbutton(window, text = "Keep Me Logged In").grid(columnspan = 2) # 'columnspan' tells to take the width of 2 columns
# you can also use 'rowspan' in the similar manner
# Submit button
button = tkinter.Button(text = "Submit",command = search_display).grid(row = 5)
window.mainloop()
It is returning the labels like below:
Greetings 1234.Please enter your search term below.
G Hallo ashita.Please enter your search term below.v.
G Hallo ashita.Please enter your search term below..v.
Please check the error in the code.

Seems like you are making a new Label every time. You can edit a Label's text like so:
mylabel = tkinter.Label(root, text="First!")
mylabel["text"] = "Second!"
This will display "Second!" (after being packed). You can even change the text after the Label is packed.

Related

Using if statements in Tkinter won't output on click

I am trying to make my first GUI app in python, and am very new to this. I want to make something for my wife (teacher) such that she can enter the number of "Growth Points" a student earns on a Standardized Test and spits out the number of "Gotchas" (in-class currency as incentives) the student receives.
The rules are: 3 gotchas for the first 6 growth points, then 5 gotchas for each subsequent growth point.
I was following a Guide from Geeksforgeeks to make the app, and can get the button to change text of a label already created but not output the Gotchas earned by the student... This is purely just to learn how to do it, so things like the Menu option is not necessary, just included as I learned.
Here is the code I have tried:
# Import Module
from tkinter import *
# create root window
root = Tk()
# root window title and dimension
root.title("Welcome to my first App")
# Set geometry (widthxheight)
root.geometry('450x300')
# all widgets will be here
# Determine the number of Growth Points
lbl = Label(root, text="How many Growth Points did the Student Earn?")
lbl.grid()
# Gather the number of Growth Points from the User
growth_points = Entry(root, width=10)
growth_points.grid(column=1, row=0)
menu = Menu(root)
item = Menu(menu)
item.add_command(label='New')
menu.add_cascade(label='File', menu=item)
root.config(menu=menu)
# Function for when the button is clicked
def clicked():
lbl.configure(text = "Clicked!") # Just to check whether the button does something
growth_points = int(growth_points)
if growth_points <= 6:
lbl_test = Label(root, text="Under 6") # Test to see if the if statement works
lbl_test.grid(column=0,row=2) # Output for the if statement (Doesn't work?)
num_gotcha = growth_points*3 # Gives the number of Gotchas for the first 6 growth points
num_gotcha = str(num_gotcha) # Converts into a String for Printing
gp_lbl = Label(root, text=num_gotcha) # Labels and inserts after clicking button
gp_lbl.grid(column=0,row=3)
elif growth_points > 6:
over_gotcha = growth_points - 6 # Gets the amount of Growth Points over the first 6
num_gotcha = over_gotcha * 5 + 18 # Finds the Gotchas for the GP's over 6, then adds the GPs for the first 6
num_gotcha = str(num_gotcha)
gp_lbl2 = Label(root, text="Student gets" + " " + num_gotcha + " " + "Gotchas") # Another way of trying to display the value
gp_lbl2.grid(column=0, row=3)
# Adding a button to begin the program
btn = Button(root, text = "Enter" , command=clicked)
btn.grid(column=2, row=0)
# Execute Tkinter
root.mainloop()
I can get the button to change the text, so it seems like the button works but it won't go through the If statements.. How should this work? Thanks for any help!
Didn't meddle with the "Gothcas" logic. Just added global reference to entry widget and renamed the variable for entered growth points:
# Function for when the button is clicked
def clicked():
global growth_points
lbl.configure(text="Clicked!") # Just to check whether the button does something
growth_points_number = int(growth_points.get())
if growth_points_number <= 6:
lbl_test = Label(root, text="Under 6") # Test to see if the if statement works
lbl_test.grid(column=0, row=2) # Output for the if statement (Doesn't work?)
num_gotcha = growth_points_number * 3 # Gives the number of Gotchas for the first 6 growth points
num_gotcha = str(num_gotcha) # Converts into a String for Printing
gp_lbl = Label(root, text=num_gotcha) # Labels and inserts after clicking button
gp_lbl.grid(column=0, row=3)
elif growth_points_number > 6:
over_gotcha = growth_points_number - 6 # Gets the amount of Growth Points over the first 6
num_gotcha = over_gotcha * 5 + 18 # Finds the Gotchas for the GP's over 6, then adds the GPs for the first 6
num_gotcha = str(num_gotcha)
gp_lbl2 = Label(root,
text="Student gets" + " " + num_gotcha + " " + "Gotchas") # Another way of trying to display the value
gp_lbl2.grid(column=0, row=3)
That should work.

tkinter: checkbox doesn't update in for-loop [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 1 year ago.
I'm stuck on the following problem. With a for-loop, I want to make a few checkboxes that automatically update a label stating whether the checkbox is ticked or not. However, it gives the wrong results (it always says that the checkboxes are ticked, whether this is the case or not; noteworthy is the fact that the checkboxes are unticked by default), see here how the GUI looks like (including error). The IntVars corresponding with the checkboxes are working correctly, as can be seen when ticking at least one of the checkboxes and pressing a button whose function is to read the checkboxes. See also the following code:
import tkinter as tk
top = tk.Tk()
n_passes = 3
checkbox_var = [0] * n_passes
checkbox = [0] * n_passes
def tick_passes(i): # update label saying if checkboxes are ticked
if checkbox_var[i].get == 0:
label = tk.Label(top, text = f"pass #{i} not ticked")
else:
label = tk.Label(top, text = f"pass #{i} ticked")
label.grid(row = 1, column = i)
def check_checkbox_var(): # check whether checkbox_var[i] is updated
for i in range(n_passes):
print(f"checkbox_var[i].get() = {checkbox_var[i].get()}")
for i in range(n_passes):
checkbox_var[i] = tk.IntVar() # turn on/off certain passes
print(f"checkbox_var[i].get() = {checkbox_var[i].get()}")
checkbox[i] = tk.Checkbutton(top, text = f"Tick pass {i}", variable =
checkbox_var[i], command = tick_passes(i))
checkbox[i].grid(row = 0, column = i, sticky=tk.W)
var_button = tk.Button(top, text = "Check checkbox_var", command =
check_checkbox_var).grid(row = 2, column = 0) # check whether checkbox_var[i] is updated
top.mainloop()
Could somebody help me with updating the labels? If there is another way to fix this issue, e.g. with buttons to be pressed instead of checkbuttons to be ticked, that would also work for mee.
i is always 2 because you're actually not running any loop after mainloop is started.
The following kind of works but you need to change something about the labels, because right now all labels are just added on top of each other. You should create them once and then just update the text but I'll leave that part for you.
import tkinter as tk
top = tk.Tk()
n_passes = 3
checkbox_var = [0] * n_passes
checkbox = [0] * n_passes
def tick_passes(): # update label saying if checkboxes are ticked
for i in range(n_passes):
if checkbox_var[i].get() == 0:
label = tk.Label(top, text = f"pass #{i} not ticked")
else:
label = tk.Label(top, text = f"pass #{i} ticked")
label.grid(row = 1, column = i)
def check_checkbox_var(): # check whether checkbox_var[i] is updated
for i in range(n_passes):
print(f"checkbox_var[i].get() = {checkbox_var[i].get()}")
for i in range(n_passes):
print(i)
checkbox_var[i] = tk.IntVar() # turn on/off certain passes
print(f"checkbox_var[i].get() = {checkbox_var[i].get()}")
checkbox[i] = tk.Checkbutton(top, text = f"Tick pass {i}", variable =
checkbox_var[i], command = tick_passes)
checkbox[i].grid(row = 0, column = i, sticky=tk.W)
var_button = tk.Button(top, text = "Check checkbox_var", command =
check_checkbox_var).grid(row = 2, column = 0) # check whether checkbox_var[i] is updated
top.mainloop()

Why can't I specific the default selected radiobutton?

I am making a simple GUI using Python's tkinter module, and I'm having a lot of trouble with radiobuttons. I wish to have the first selected by default, but the other two are selected at the start. Additionally, when I just pass the cursor over the window, the first one becomes checked (I do not click) so all 3 show as selected. My code:
import tkinter as tk
class openGUI(object):
def __init__(self):
# title of window
window.title("DUNE LArTPC Simulator")
# label for choices
self.question = tk.Label(window, text = "Do you want to create new or analyse existing data?")
self.question.grid(row = 0, column = 0, columnspan = 3)
# buttons corresponding to choices
self.createBtn = tk.Button(window, text = "Create", command = self.createData)
self.analyseBtn = tk.Button(window, text = "Analyse", command = self.analyseData)
self.createBtn.grid(row = 1, column = 0)
self.analyseBtn.grid(row = 1, column = 2)
def analyseData(self):
"""
Not implemented yet.
"""
pass
def createData(self):
# edit window to display new widgets (irritating to have lots of windows open!)
window.title("Select variable")
self.question.destroy()
self.createBtn.destroy()
self.analyseBtn.destroy()
# text in window
variableQ = tk.Label(window, text = "Please select Independent variable for dataset:")
variableQ.grid(row = 0, column = 0, columnspan = 3)
# radioselect variable
selection = tk.StringVar()
selection.set("lifetime")
# radioselect buttons
lifetimeBtn = tk.Radiobutton(window, variable = selection, value = "lifetime", text = "Lifetime")
elecNoiseBtn = tk.Radiobutton(window, variable = selection, value = "electronic", text = "Electronic Noise")
radioactivityBtn = tk.Radiobutton(window, variable = selection, value = "radioactive", text = "Radioactivity")
lifetimeBtn.grid(row = 1, column = 0)
elecNoiseBtn.grid(row = 1, column = 1)
radioactivityBtn.grid(row = 1, column = 2)
# create window
window = tk.Tk()
# create class object with methods to populate
# window with widgets
initWin = openGUI()
# enter mainloop
window.mainloop()
Running the above gives me:
I have tried using lifetimeBtn.select() method instead of setting the StringVar(), but this does not seem to work either. What have I missed?
EDIT: added rest of code to show how I am using class and functions to manipulate the window.
It is because selection is a local variable inside createData() function and it will be garbage collected after function completes.
Change selection to instance variable self.selection.

The GUI part works, why am i getting "y = x["main"] KeyError: 'main' python"

My main goal is to write a python scrypt that outputs the temperature by inputing your current city.
I made one and im getting this y = x["main"] KeyError: 'main' python. This is using a gui. The gui part works.
I blocked out my api key by the way.
Here is the code i have so far:
# import all functions from the tkinter
#from tkinter import *
#from tkinter import messagebox *
import tkinter
from tkinter import messagebox
from tkinter import Label
from tkinter import Entry
from tkinter import Button
from tkinter import END
messagebox.showinfo("Title", "a Tk MessageBox")
# hide main window
root = tkinter.Tk()
root.withdraw()
# message box display
messagebox.showerror("Error", "Error message")
messagebox.showwarning("Warning","Warning message")
messagebox.showinfo("Information","Informative message")
# function to find weather details
# of any city using openweathermap api
def tell_weather() :
# import required modules
import requests
# enter your api key here
api_key = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
# base_url variable to store url
base_url = 'http://api.openweathermap.org/data/2.5/weather?'
# take a city name from city_field entry box
city_name = city_field.get()
# complete_url variable to store complete url address
complete_url = (base_url + "appid =" + api_key
+ "&q =" + city_name)
# get method of requests module
# return response object
response = requests.get(complete_url)
# json method of response object convert
# json format data into python format data
x = response.json()
print(x)
# now x contains list of nested dictionaries
# we know dictionary contains key value pair
# check the value of "cod" key is equal to "404"
# or not if not that means city is found
# otherwise city is not found
if x["cod"] != "404" :
# store the value of "main" key in variable y
#if __main__ == '__response.json() __':
y = x['main']
# store the value corresponding to the "temp" key of y
current_temperature = y["temp"]
# store the value corresponding to the "pressure" key of y
current_pressure = y["pressure"]
# store the value corresponding to the "humidity" key of y
current_humidiy = y["humidity"]
# store the value of "weather" key in variable z
z = x["weather"]
# store the value corresponding to the "description" key
# at the 0th index of z
weather_description = z[0]["description"]
# insert method inserting the
# value in the text entry box.
temp_field.insert(15, str(current_temperature) + " Kelvin")
atm_field.insert(10, str(current_pressure) + " hPa")
humid_field.insert(15, str(current_humidiy) + " %")
desc_field.insert(10, str(weather_description) )
# if city is not found
else :
# message dialog box appear which
# shows given Error meassgae
messagebox.showerror("Error", "City Not Found \n"
"Please enter valid city name")
# clear the content of city_field entry box
city_field.delete(0, END)
# Function for clearing the
# contents of all text entry boxes
def clear_all() :
city_field.delete(0, END)
temp_field.delete(0, END)
atm_field.delete(0, END)
humid_field.delete(0, END)
desc_field.delete(0, END)
# set focus on the city_field entry box
city_field.focus_set()
# Driver code
if __name__ == "__main__" :
# Create a GUI window
root = tkinter.Tk()
# set the name of tkinter GUI window
root.title("Gui Application")
# Set the background colour of GUI window
root.configure(background = "light green")
# Set the configuration of GUI window
root.geometry("425x175")
# Create a Weather Gui Application label
headlabel = Label(root, text = "Weather Gui Application",
fg = 'black', bg = 'red')
# Create a City name : label
label1 = Label(root, text = "City name : ",
fg = 'black', bg = 'dark green')
# Create a City name : label
label2 = Label(root, text = "Temperature :",
fg = 'black', bg = 'dark green')
# Create a atm pressure : label
label3 = Label(root, text = "atm pressure :",
fg = 'black', bg = 'dark green')
# Create a humidity : label
label4 = Label(root, text = "humidity :",
fg = 'black', bg = 'dark green')
# Create a description :label
label5 = Label(root, text = "description :",
fg = 'black', bg = 'dark green')
# grid method is used for placing
# the widgets at respective positions
# in table like structure .
headlabel.grid(row = 0, column = 1)
label1.grid(row = 1, column = 0, sticky ="E")
label2.grid(row = 3, column = 0, sticky ="E")
label3.grid(row = 4, column = 0, sticky ="E")
label4.grid(row = 5, column = 0, sticky ="E")
label5.grid(row = 6, column = 0, sticky ="E")
# Create a text entry box
# for filling or typing the information.
city_field = Entry(root)
temp_field = Entry(root)
atm_field = Entry(root)
humid_field = Entry(root)
desc_field = Entry(root)
# grid method is used for placing
# the widgets at respective positions
# in table like structure .
# ipadx keyword argument set width of entry space .
city_field.grid(row = 1, column = 1, ipadx ="100")
temp_field.grid(row = 3, column = 1, ipadx ="100")
atm_field.grid(row = 4, column = 1, ipadx ="100")
humid_field.grid(row = 5, column = 1, ipadx ="100")
desc_field.grid(row = 6, column = 1, ipadx ="100")
# Create a Submit Button and attached
# to tell_weather function
button1 = Button(root, text = "Submit", bg = "red",
fg = "black", command = tell_weather)
# Create a Clear Button and attached
# to clear_all function
button2 = Button(root, text = "Clear", bg = "red",
fg = "black", command = clear_all)
# grid method is used for placing
# the widgets at respective positions
# in table like structure .
button1.grid(row = 2, column = 1)
button2.grid(row = 7, column = 1)
# Start the GUI
root.mainloop()
Im also getting this :
{cod 401, message Invalid API key. Please see http://openweathermap.org/ faq #error401 for more info.} Exception in Tki
I Know i am using the correct api key. maybe i am missing something.
Excuse my formatting of the code. This is the first time I use stackoverflow.
This is python language btw.
I faced the same problem earlier on , but then i realised it was just a bone headed mistake
In this line ,
....
complete_url = (base_url + "appid =" + api_key
+ "&q =" + city_name)
....
there should be no spaces between any of the characters , otherwise %20 will be inserted automatically by the browser to fill the gap , thus messing with api key . So change it to:
....
complete_url = (base_url + "appid=" + api_key
+ "&q=" + city_name) ↑
.... ↑
The only changes I've made is removed the extra spaces
(The arrows indicate the changes made .)
Hope it helped !
The error message is fairly clear. It is saying that in this bit of code:
if x["cod"] != "404" :
# store the value of "main" key in variable y
#if __main__ == '__response.json() __':
y = x['main']
You try to look up the key 'main' in the dictionary x but that key is not in the dictionary x.

Trying to put drop down list on a code using Tkinter

I'm tring to put some drop down list on a graphic interface I'm building.
I've found the following code for a drop down list, but I'm not able to adapt it to my code.
from Tkinter import *
def print_it(event):
print var.get()
root = Tk()
var = StringVar()
var.set("a")
OptionMenu(root, var, "a","b","c", command=print_it).pack()
root.mainloop()
This is my code, it's quite simple what I've done so far. A menu shows up, it asks for how many (n) components does the users want to enter, and it shows n options to entry. The code above shows 'blank' entrys after you put the desired number of components. I want to replace those three blank entrys with three drop down list.
It's marked when I want to put those dropdown lists.
from Tkinter import *
import Image
import ImageTk
import tkFileDialog
class Planificador:
def __init__(self,master):
master.title("Planificador")
self.frameOne = Frame(master)
self.frameOne.grid(row=0,column=0)
# Logo
self.imgLabel = Label(self.frameOne, image = None)
self.imgLabel.grid(row=0,column=0)
self.img = ImageTk.PhotoImage(file = "logo.png")
self.imgLabel["image"] = self.img
self.botones()
def botones(self):
self.piezastext = Label(self.frameOne, text = " number of components ", justify="center")
self.piezastext.grid(row=1, column=0)
self.entrypiezas = Entry(self.frameOne,width=5)
self.entrypiezas.grid(row=2, column=0)
self.aceptarnumpiezas = Button(self.frameOne,text="Aceptar", command=self.aceptar_piezas,width=8)
self.aceptarnumpiezas.grid(row=6, column=0)
def aceptar_piezas(self):
num_piezas = self.entrypiezas.get()
print num_piezas
self.piezastext.grid_remove()
self.entrypiezas.grid_remove()
self.aceptarnumpiezas.grid_remove()
n = 1;
while n <= int(num_piezas):
self.textopieza = Label(self.frameOne, text = "Pieza", justify="left")
self.textopieza.grid(row=n, column=0)
// INSTEAD THESE 'n' BLANK ENTRYS, I WANT TO PUT 'n' DROP DOWN LISTS
self.entrypiezas = Entry(self.frameOne,width=5)
self.entrypiezas.grid(row=n, column=1)
self.aceptarpiezas = Button(self.frameOne,text="Aceptar",width=8)
self.aceptarpiezas.grid(row=int(num_piezas)+1, column=0)
n += 1
# Main
if __name__ == "__main__":
# create interfacE
root = Tk()
movieApp = Planificador(root)
root.mainloop()
So I want to know how can I put that drop down list on a given frame, frameOnein my case, instead of a full window. Thanks in advance.
I modified your aceptar_piezas function to do what I think you want:
def aceptar_piezas(self):
num_piezas = self.entrypiezas.get()
print num_piezas
self.piezastext.grid_remove()
self.entrypiezas.grid_remove()
self.aceptarnumpiezas.grid_remove()
# Create a list of tuples to hold the dynamically created Optionmenus
# The first item in the tuple is the menu, the second is its variable
self.optionmenus = list()
n = 1
while n <= int(num_piezas):
self.textopieza = Label(self.frameOne, text = "Pieza", justify="left")
self.textopieza.grid(row=n, column=0)
# Variable for the Optionmenu
var = StringVar()
# The menu
menu = OptionMenu(self.frameOne, var, "a","b","c")
menu.grid(row=n, column=1)
# Set the variable to "a" as default
var.set("a")
# Add the menu to the list of Optionmenus
self.optionmenus.append((menu, var))
n += 1
def clicked():
"""This function was made just to demonstrate. It is hooked up to the button"""
for optionmenu in self.optionmenus:
print optionmenu[1].get()
print self.optionmenus
# This button doesn't need to be in the while loop
self.aceptarpiezas = Button(self.frameOne, text="Aceptar", command=clicked, width=8)
self.aceptarpiezas.grid(row=int(num_piezas)+1, column=0)
The tuples in the list are in the order that the Optionmenus were created. So, the first tuple contains the data for the first Optionmenu, the second for the second, and so forth.

Categories

Resources