Hey Guys I have a problem with checkboxen in tkinter. Can someone say where my fault is ?
def edit_contact_gui(self):
"""GUI to edit the created contacts."""
self.edit_contact_wd = tk.Tk()
self.edit_contact_wd.title('Edit Contacts of the Phonebook:"%s"'\
% self.book)
self.button_edit = tk.Button(self.edit_contact_wd, text = 'Edit',\
command = self.edit_contact)
try:
with open('%s.txt' % self.book, 'rb') as file:
book = pickle.load(file)
x = 1
self.var_lst = []
for i in book:
var = tk.IntVar()
tk.Label(self.edit_contact_wd, text = i).grid(row = x, \
column = 0)
tk.Checkbutton(self.edit_contact_wd, text = 'edit', \
variable = var).grid(row = x, column = 1)
self.var_lst.append(var.get())
x += 1
self.button_edit.grid(row = x+1, column = 1)
except FileNotFoundError:
tk.Label(self.edit_contact_wd, text = 'The phonebook has no entrys!', fg = 'red').grid(row = 1, column = 0)
self.edit_contact_wd.mainloop()
def edit_contact(self):
print(self.var_lst)
My GUI output works, but the programm return me a List [0,0,0,0,0] full of zeros. In my opinion the Checkbox who is marked has return a 1 but it doesnt to it. Why? Can you help me ?
You have to keep IntVar (var) on list, not value from IntVar (var.get())
self.var_lst.append(var) # without .get()
and in edit_contact() you have to use get()
for var in self.var_lst:
print(var.get())
Related
In this simple calculator GUI, I'm creating a frame template using classes. The frame has 2 labels, 2 entry boxes, and a button. I'd like the button to run a specific command depending on the function_call variable passed when initializing - but this doesn't work. The two_points function should be called for the first object, and one_point should be called for the second. How do I dynamically change which command is called based on which object I'm using? Thank you for taking the time to read this.
from tkinter import *
root = Tk()
root.title("Simple Slope Calculator")
class Slope_Calc:
# Variable info that changes within the frame
def __init__(self, master, num_1, num_2, frame_name, label_1_name, label_2_name, function_call):
self.num_1 = int(num_1)
self.num_2 = int(num_2)
self.frame_name = frame_name
self.label_1_name = label_1_name
self.label_2_name = label_2_name
self.function_call = function_call
# Frame template
self.frame_1 = LabelFrame(master, text = self.frame_name, padx = 5, pady = 5)
self.frame_1.grid(row = self.num_1, column = self.num_2, padx = 10, pady = 10)
self.label_1 = Label(self.frame_1, text = self.label_1_name)
self.label_1.grid(row = 0, column = 0)
self.entry_1 = Entry(self.frame_1)
self.entry_1.grid(row = 0, column = 1)
self.label_2 = Label(self.frame_1, text = self.label_2_name)
self.label_2.grid(row = 1, column = 0)
self.entry_2 = Entry(self.frame_1)
self.entry_2.grid(row = 1, column = 1)
self.calc_button = Button(self.frame_1, text = "Calculate", command = self.function_call) # This is what doesn't work
self.calc_button.grid(row = 1, column = 2, padx = 5)
# Strips string of spaces and parentheses
# Returns a list of relevant ordered pair
def strip_string(self, entry_num):
ordered_pair = entry_num.get().split(", ")
ordered_pair[0] = ordered_pair[0].replace("(", "")
ordered_pair[1] = ordered_pair[1].replace(")", "")
return(ordered_pair)
# Calculates slope based on one point and y-intercept
def one_point(self):
pair_1 = self.strip_string(self.entry_1)
b = int(self.entry_2.get())
m = (int(pair_1[1]) - b)/(float(pair_1[1]))
label_3 = Label(self.frame_1, text = "SLOPE-INTERCEPT EQUATION: y = " + str(m) + "x + " + str(b))
label_3.grid(row = 2, column = 0, columnspan = 2)
# Calculates slope based on two points given
def two_points(self):
pair_1 = self.strip_string(self.entry_1)
pair_2 = self.strip_string(self.entry_2)
m = (int(pair_2[1]) - int(pair_1[1]))/float(int(pair_2[0]) - int(pair_1[0]))
b = (int(pair_1[1])) - (m*int(pair_1[0]))
label_3 = Label(self.frame_1, text = "SLOPE-INTERCEPT EQUATION: y = " + str(m) + "x + " + str(b))
label_3.grid(row = 2, column = 0, columnspan = 2)
# Calling each object
two_p = Slope_Calc(root, 0, 0, "Two Points", "First Ordered Pair", "Second Ordered Pair", "two_points")
one_p = Slope_Calc(root, 0, 1, "One Point and Y-Intercept", "Ordered Pair", "Y-intercept", "one_point")
root.mainloop()
The command keyword argument of the Button constructor is supposed to be a function.
Here you give it instead a string which is the name of the method of self that should be called. So you must first get this method using setattr to be able to call it. This should do it:
def call():
method = getattr(self, self.function_call)
method()
self.calc_button = Button(
self.frame_1,
text = "Calculate",
command = call)
You then have an error in strip_string but that's another story.
making an email slicer,
some errors I'm getting are:
AttributeError: 'bool' object has no attribute 'index'
ValueError: substring not found
now, with this specific code, I'm getting no result at all, it just doesn't do anything when I click the button
root = Tk()
e = Entry(root)
e.grid(row = 6, column = 6)
s = Label(root)
s.grid(row = 1, column = 1)
wel = Label(root, text = "whats your email")
wel.grid(row = 1, column = 5)
inp = Entry(root)
inp.grid(row = 3, column = 5)
def callback(re = inp.get()):
us = re[:re.startswith("#")]
uss = re[re.startswith("#")+1:]
var = StringVar()
var.set(us + uss)
sub = Button(root, text = "submit", command = lambda:callback())
sub.grid(row = 5, column = 5)
final = Label(root, textvariable = var)
final.grid(row = 5, column = 6)
root.mainloop()
You need to
call inp.get() inside callback(), not as default value of argument
use find() instead of startswith()
call var.set(...) inside the function as well
def callback():
re = inp.get()
pos = re.find("#")
if pos >= 0:
user = re[:pos]
domain = re[pos+1:]
var.set(user+","+domain)
else:
var.set("Invalid email")
Note that above is not enough to check whether the input email is valid or not, for example two "#" in the input.
I have the following code (it's partly in Dutch but I don't think that'll be an issue):
from tkinter import *
root = Tk()
woorden_en = ["mouse", "armadillo", "caterpillar", "buffalo", "dragonfly", "eel", "monkey", "lark", "manatee", "squid"]
woorden_nl = ["muis", "gordeldier", "rups", "buffel", "libelle", "paling", "aap", "leeuwerik", "zeekoe", "inktvis"]
nummer = IntVar()
nlWoord = StringVar()
enWoord = StringVar()
goedfout = StringVar()
def vorige():
nummer -= 1
def volgende():
nummer += 1
def controleer():
print("Correct!")
secondGrid = Frame(root)
secondGrid.grid(row = 2, column = 1, columnspan = 2)
labelVertaling = Label(root, text="vertaling")
textVertaling = Entry(root, width=30, textvariable = nlWoord)
runVorige = Button(secondGrid, text="vorige", command = vorige)
runVolgende = Button(secondGrid, text="volgende", command = volgende)
runControleer = Button(secondGrid, text="controleer", command = controleer)
labelWoord = Label(root, text="woord")
labelWoordEn = Label(root, textvariable = enWoord)
labelNo = Label(root, textvariable = nummer)
Correct = Label(root, textvariable = goedfout)
Correct.grid(row = 2, column = 0)
labelNo.grid(row = 0, column = 0)
labelWoord.grid(row = 0, column = 1)
labelWoordEn.grid(row = 1, column = 1)
labelVertaling.grid(row = 0, column = 2)
textVertaling.grid(row = 1, column = 2)
runVorige.grid(row = 0, column = 0, sticky = "W")
runVolgende.grid(row = 0, column = 1, sticky = "W")
runControleer.grid(row = 0, column = 2, sticky = "W")
nummer.set(1)
enWoord.set(woorden_en[0])
root.mainloop()
The start value of 'nummer' is 1, as set in the 3rd to last line. This value needs to be changed with either -1 or +1 when clicking buttons 'vorige' (previous) or 'volgende' (next). The current code in the functions give me erros. Apparently I need to use set/get functions, but I cannot find out how to make it work. Any input or help would be appreciated.
Just change your function to:
def vorige():
nummer_val = nummer.get()
nummer_val -= 1
nummer.set(nummer_val)
def volgende():
nummer_val = nummer.get()
nummer_val += 1
nummer.set(nummer_val)
This is because nummer is an IntVar() and you have to get the value of the variable using get() method. After that you have to assign it to a variable and then reduce/increase its value by 1. The first error you were getting was because the nummer was not globalized inside the function, but that was not the approach you should have taken, anyway this should fix your errors.
I'm trying to use an Entry widget to get the user's data and then print it.
Why is Tkinter Entry's get function returning nothing?
This didn't help me.
This is my code
message = ''
# start_chatting function
def start_chatting ():
global message
master2 = tk.Tk()
master2.geometry("1280x720")
master2.title("Messenger")
label = tk.Label(master2, text = "Messenger!!!",bg = '#1e00ff',fg ='yellow',width = 35, height = 5).place(x = 500, y = 0)
username_label = tk.Label(master2,text = usernames[position_counter],bg = '#91806d',fg ='white',width = 10, height = 2).place(x = 0, y = 100)
v = StringVar()
L1 = Label(master2, text = "Type your message : ").place(x=0, y = 680)
e = Entry(master2,textvariable = v)
e.insert(END, '')
e.pack()
e.place(x = 115, y = 680)
submit_button = Button(master2,text = "Submit",command = submit_f).place(x = 200, y = 680)
message = message+ v.get()
master2.mainloop()
#submit_f function
def submit_f ():
global message
print(message)
Keep in mind that this is a part of my code and not all of it.
Thanks in advance!
The function prints nothing beacause you have changed the message value in the current function where the entry box is defined.
So, when you write v.get(), it generally returns an empty text.The message variable needs to call every time when submit button is pressed. Hence, message variable should be changed inside submit_f() function.
Here's the Solution,
import tkinter
from tkinter import *
message = ''
# start_chatting function
def start_chatting ():
global v
master2 = Tk()
master2.geometry("1280x720")
master2.title("Messenger")
label = Label(master2, text = "Messenger!!!",bg = '#1e00ff',fg ='yellow',width = 35, height = 5).place(x = 500, y = 0)
username_label = Label(master2,text = usernames[position_counter],bg = '#91806d',fg ='white',width = 10, height = 2).place(x = 0, y = 100)
L1 = Label(master2, text = "Type your message : ").place(x=0, y = 680)
v = StringVar()
e = Entry(master2,textvariable = v)
e.insert(END, '')
e.pack()
e.place(x = 115, y = 680)
submit_button = Button(master2,text = "Submit",command = submit_f).place(x = 200, y = 680)
master2.mainloop()
#submit_f function
def submit_f ():
global message
message = message + " " + v.get()
print(message)
start_chatting()
I want to show the current moon phase in tkinter for today or a specific date. When I run the code I get the Error: "NameError: name 'imgpath' is not defined". I understand that I have to press the button first. How can I set the variable "imgpath" to an global variable.
I want to change the picture when I choose another date.
from tkinter import *
import ephem
from datetime import date, datetime
fenster = Tk()
def button_action():
station = ephem.Observer()
dates = dateeingabe.get()
if (dates == ""):
station.date = datetime.utcnow()
else:
station.date = dateeingabe.get()
#Mondphase
Moon = ephem.Moon()
Moon.compute(station)
drei = round(Moon.phase, 0)
eins = ephem.next_full_moon(station.date)
zwei = ephem.next_new_moon (station.date)
if drei == 0:
phasen = int(0)
elif drei == 100:
phasen = int(100)
elif (ephem.next_full_moon(station.date) > ephem.next_new_moon(station.date)):
phasen = int(100-drei+100)
else:
phasen = int(drei)
imgpath = str("/home/user/moon/"+str(phasen)+".png")
pic = PhotoImage(file=imgpath)
picz = Label(fenster, image=pic)
dateeingabe = Entry(fenster, bd=5, width=40)
start_button = Button(fenster, text="Start", command=button_action)
dateeingabe.grid(row = 1, column = 1)
start_button.grid(row = 2, column = 1)
picz.grid(row = 3, column = 1)
fenster.mainloop()
Your program executes top to bottom, so when you try to set the path to imgpath in
pic = PhotoImage(file=imgpath)
It throws an error because imgpath is defined once you call button_action in this code, two lines below:
start_button = Button(fenster, text="Start", command=button_action)
To convert imgpath to a global variable you can declare it as so :
global imgpath
Although that will not solve your problem as you're calling the PhotoImage before you're calling button_action.
Maybe try shifting that code below the Button code?
Hope this helps!