How to import variable from another function to other function - python

I was trying to make a simple Simple Interest calculator using Pycharm and tkinter.
There is my code
It is showing that x is not defined
I already tried to put variable as global.
Also I cant call that function in my finalProgram function because it makes it as endless loop
from tkinter import *
def mainWindow():
label = Label(frame, text = "What do you want to do")
label.pack()
but1 = Button(frame, text = "SI", command = SimpleInterest)
but1.pack()
def SimpleInterest():
global x
frame.destroy()
label5 = Label(frame2,text="Please enter principal amount" )
label5.pack()
p = Entry(frame2 )
p.pack()
label6 = Label(frame3,text="Please ROI")
label6.pack()
r = Entry(frame3, text="Please enter rate of interest")
r.pack()
label7 = Label(frame4, text="Please enter time")
label7.pack()
t = Entry(frame4, text="Please enter time")
t.pack()
buttonmain = Button(frame4, text = "Finlise", command = finalProgram)
buttonmain.pack()
global x
x =(p*r*t)/100
def finalProgram():
frame2.destroy()
frame3.destroy()
frame4.destroy()
global x
newlabel = Label(frame5, text = x)
root = Tk()
frame = Frame(root)
frame.grid(row=0,columnspan = 2)
mainWindow()
frame2 = Frame(root)
frame2.grid(row = 0, columnspan =2)
frame3 = Frame(root)
frame3.grid(row =1, columnspan =2)
frame4 = Frame(root)
frame4.grid(row=2, columnspan =2)
frame5 = Frame(root)
frame5.grid(row=0)
root.mainloop()

There is only one modification to your code. In the lower section one line is added:
x = 0.0
This is to ensure you have a variable x in global scope. With that variable in global scope you are then able to use (read and write) it within your functions (after you declared it as global with global x)
from tkinter import *
def mainWindow():
label = Label(frame, text = "What do you want to do")
label.pack()
but1 = Button(frame, text = "SI", command = SimpleInterest)
but1.pack()
def SimpleInterest():
global x
frame.destroy()
label5 = Label(frame2,text="Please enter principal amount" )
label5.pack()
p = Entry(frame2 )
p.pack()
label6 = Label(frame3,text="Please ROI")
label6.pack()
r = Entry(frame3, text="Please enter rate of interest")
r.pack()
label7 = Label(frame4, text="Please enter time")
label7.pack()
t = Entry(frame4, text="Please enter time")
t.pack()
buttonmain = Button(frame4, text = "Finlise", command = finalProgram)
buttonmain.pack()
global x
x =(p*r*t)/100
def finalProgram():
frame2.destroy()
frame3.destroy()
frame4.destroy()
global x
newlabel = Label(frame5, text = x)
x = 0.0
root = Tk()
frame = Frame(root)
frame.grid(row=0,columnspan = 2)
mainWindow()
frame2 = Frame(root)
frame2.grid(row = 0, columnspan =2)
frame3 = Frame(root)
frame3.grid(row =1, columnspan =2)
frame4 = Frame(root)
frame4.grid(row=2, columnspan =2)
frame5 = Frame(root)
frame5.grid(row=0)
root.mainloop()
Please note, that this is only a quick fix for the problem you asked. The general structure of you code is not really good and you should consider learning concepts like classes and/or how you pass arguments into functions.

Related

Values not stored in Tkinter Variables

In my code, I have tried to get the user input through text fields, store them in variables and finally print them in a tabular form.
The problem I am facing is that none of the values I enter through the text fields get displayed; when I try printing the variables, they come up empty.
Here's part of my code:
# SPASC
from tkinter import *
import tkinter as tk
import tkinter.ttk as tktrv
root = tk.Tk()
root.title("SPASC")
root.geometry("410x400")
lb1 = Label(root, text="SPASC \n Welcomes You !!!", fg="red", bg="sky blue"
, font=('Arial Black', 20), width=22, anchor=CENTER)
lb2 = Label(root, text="What would you like to compare?",
font=('Arial', 18), anchor=CENTER)
space1 = Label(root, text="\n\n")
lb1.grid(row=0)
lb2.grid(row=5)
space1.grid(row=1)
hpw, mil = StringVar(), StringVar()
def bt_cars():
w1 = Toplevel()
w1.title("Choose Features")
w1.geometry("430x200")
lb3 = Label(w1, text="Choose features for comparison", bg="yellow"
, font=('Arial Black', 18), width=25)
lb4 = Label(w1, text=" ", anchor=CENTER)
fr1 = LabelFrame(w1, width=20, padx=100)
hpw_cb = Checkbutton(fr1, text="Horsepower", variable=hpw, anchor='w', onvalue="Horsepower", offvalue="")
hpw_cb.grid()
hpw_cb.deselect()
mil_cb = Checkbutton(fr1, text="Mileage", variable=mil, anchor='w', onvalue="Mileage", offvalue="")
mil_cb.grid()
mil_cb.deselect()
var_stor = [hpw, mil]
print(hpw)
print(mil)
var_fill = []
for itr1 in var_stor:
if itr1 != "":
var_fill.append(itr1)
print(var_fill)
def car_1():
name1 = StringVar()
c1 = Toplevel()
c1.title("Car 1")
c1.geometry("430x200")
car1_lb1 = Label(c1, text="Car Name:")
name1_ifl = Entry(c1)
name1 = name1_ifl.get()
elm_var_fill = len(var_fill)
ct1 = 0
car1_val = []
for itr2 in var_fill:
if ct1 == elm_var_fill:
break
lb5 = Label(c1, text=itr2.get())
#Creating text field
ftr1_ifl = Entry(c1)
car1_ftr = ftr1_ifl.get()
car1_val.append(car1_ftr)
car1_ftr = None
lb5.grid(row=ct1 + 2, column=1)
ftr1_ifl.grid(row=ct1 + 2, column=2)
ct1 += 1
print(car1_val)
def display():
dp = Toplevel()
dp.title("Results")
dp.geometry("500x200")
car1_pt = 0
car2_pt = 0
car_tree = tktrv.Treeview(dp)
car_tree["columns"] = ("car1col")
car_tree.column("#0", width=120, minwidth=30)
car_tree.column("car1col", width=120, minwidth=30)
car_tree.heading("#0", text="Features" )
car_tree.heading("car1col", text=str(name1))
car_tree.pack()
c1.withdraw()
print(var_fill)
done1_bt = Button(c1, text="Continue", command=display)
name1_ifl.grid(row=0, column=2)
car1_lb1.grid(row=0, column=1)
done1_bt.grid(row=5,column=1)
w1.withdraw()
done_bt = Button(w1, text="Done", command=car_1)
done_bt.grid(row=3, column=1)
lb3.grid(row=0, column=1)
lb4.grid(row=1, column=1)
fr1.grid(row=2, column=1)
root.withdraw()
bt1 = Button(root, text="CARS", width=5, font=('Calibri', 15), command=bt_cars)
bt1.grid(row=7)
space2 = Label(root, text="\n\n")
space2.grid(row=6)
root.mainloop()
I am facing trouble with the variables named: hpw, mil, name1.
Any help would be welcome.
NOTE:- Please excuse the amount of code; I wanted others to replicate the error and see it for themselves
For the variables hpw and mil, these variables are empty strings that's why you are not getting any value from those checkboxes. To get values from the checkboxes replace these lines of code:
var_stor = [hpw, mil]
with
var_stor = [hpw_cb.cget('onvalue'), mil_cb.cget('onvalue')]
since you want the onvalue then you must use cget() method to access those values.
also, replace
lb5 = Label(c1, text=itr2.get())
with
lb5 = Label(c1, text=itr2)
because now you have required values (not objects) in a list, so just need to access those values.
For the variable name1 you can use #BokiX's method.
The problem is you are using get() wrong. You cannot use get() right after Entry() because as soon as entry is created it's getting the input before the user can even input something.
Use this code:
def get_input(text):
print(text)
e = Entry(root)
e.pack()
b = Button(root, text="Print input", command=lambda: get_input(e.get()))
b.pack()
Now get() method will not be executed before you click the button.

Tkinter Text widget returns ".!frame3.!frame3.!frame.!text" instead of appropriate values

I'm currently working on a project where you scan bar codes and it implements the result into an excel file. I am using tkinter to make my GUI, however, when I try to get the values from a text widget it returns the value ".!frame3.!frame3.!frame.!text". how can I fix this to get the appropriate values?
here is my code so far
import tkinter as tk
from tkinter import *
root = tk.Tk(className = "Tool Manager")
root.configure(bg='#C4C4C4')
root.title('Main Screen')
root.geometry("800x600")
main = Frame(root, bg='#C4C4C4', width = 800, height = 600)
#This is the contents of the Main Frame (screen 1)
frame_pad1 = Frame(main, bg='#C4C4C4')
frame_1 = Frame(main,bg='#C4C4C4')
frame_2 = Frame(main, bg='#C4C4C4')
frame_3 = Frame(main, bg='#C4C4C4')
min = Frame(root, bg = 'GREEN')
#mout stuffs
mout = Frame(root, bg = '#C4C4C4')
outframe_pad1 = Frame(mout, bg='#C4C4C4')
outframe_1 = Frame(mout, bg='#C4C4C4')
outframe_2 = Frame(mout, bg='#C4C4C4')
outframe_3 = Frame(mout, bg='#C4C4C4')
#code for changing screens
def raise_frame(frame):
frame.tkraise()
for frame in (main, min, mout):
frame.grid(row=1, column=1, sticky='news')
#sets frame weight for 3 rows (centers frames)
rows = 0
while rows < 3:
root.rowconfigure(rows, weight=1)
root.columnconfigure(rows,weight=1)
rows += 1
def commit_to_file():
ID = name.get()
out_list.get('1.0', 'end-1c')
print(out_list) #<----- THIS IS WHERE I'M RETURNING VALUES TO THE TERMINAL
def on_every_keyboard_input(event):
update_char_length(out_list)
#updating Line Length Information
def update_char_length(out_list):
string_in_text = out_list.get('1.0', '1.0 lineend')
string_length = len(string_in_text)
print(string_length)
if (string_length == 4):
out_list.insert(0.0, '\n')
out_list.mark_set("insert", "%d.%d" % (0,0))
#main screen formatting
area = PhotoImage(file="test.png")
areaLabel = Label(frame_1, image=area, bg='#C4C4C4')
areaLabel.pack(side=RIGHT)
mwLabel = Label(frame_2,text="this is only a test", font=("Airel", 20), bg='#C4C4C4')
mwLabel.pack(side=RIGHT)
out_button = Button(frame_3, text="Check Out", command=lambda:raise_frame(mout) , height=5, width=20, font=("Airel", 15))
out_button.pack(side=RIGHT, padx=20, pady = 4)
in_button = Button(frame_3, text="Check In", command=lambda:raise_frame(min), height=5, width=20, font=("Airel", 15))
in_button.pack(side=LEFT, padx=20, pady = 4)
#out screen formatting
name = Entry(outframe_1, font=("Airel", 15))
name.pack(side=RIGHT)
name_lbl = Label(outframe_1, text="ID Number", bg='#C4C4C4', font=("Airel", 15))
name_lbl.pack(side=LEFT)
outlist = Frame(outframe_2, bd=1, relief=SUNKEN)
outlist.pack(side=LEFT)
out_list = Text(outlist, height=30, width=40)
out_list.pack(side=RIGHT)
done_btn = Button(outframe_3, text="Done", command=commit_to_file, font=("Ariel", 15))
done_btn.pack(side=RIGHT, padx=20, pady=4)
#init to main screen
raise_frame(main)
#drawing objects for main screen
frame_pad1.pack(padx=1, pady=25)
frame_1.pack(padx=1,pady=1)
frame_2.pack(padx=10,pady=1)
frame_3.pack(padx=1, pady=80)
#drawing out screen
outframe_1.pack(padx=1, pady=1)
outframe_2.pack(padx=1,pady=1)
outframe_3.pack(padx=1, pady=1)
#calls line info update out screen
out_list.bind('<KeyRelease>', on_every_keyboard_input)
root.mainloop()
You are printing the command and not the value of it. Put the command in a variable and then print the variable.
Example: myVar = out_list.get("1.0", "end-1c") and then print(myVar)

Tkinter Grid Alignment Issue

I'm pretty new with tkinter and I can't figure why the q is not aligned near the Entry.
# String
self.user_p = StringVar()
self.user_q = StringVar()
self.user_r = StringVar()
self.user_result = StringVar()
# Label
self.description = Label(self.root, text="!p v (q ^ r)")
self.pLabel = Label(self.root, text="p")
self.qLabel = Label(self.root, text="q")
self.rLabel = Label(self.root, text="r")
self.resultLabel = Label(self.root, text="Result")
# Entry
self.p = Entry(self.root, textvariable = self.user_p, width = 10)
self.q = Entry(self.root, textvariable = self.user_q, width = 10)
self.r = Entry(self.root, textvariable = self.user_r, width = 10)
self.result = Entry(self.root, bg = "white", state=DISABLED, text = "")
# Grid
# Labels
self.description.grid(row = 0, column = 3, sticky = N)
self.pLabel.grid(row = 1, column = 0, sticky = E)
self.qLabel.grid(row = 1, column = 2, sticky = E)
self.rLabel.grid(row = 1, column = 4, sticky = E)
# Entry
self.p.grid(row=1, column=1)
self.q.grid(row = 1, column = 3)
self.r.grid(row=1, column=5)
(with or without the sticky it's still the same)
Here's a picture: http://imgur.com/a/wrOGa
The first part in the picture is what I'm getting right now. And the second part is what I want it to look like
Am I doing something wrong?
Welcome. I have taken the liberty to attach an example of a test code (see below). Please remember to do that in your post as mine can be different to yours. I did not encounter the issue you described. See attached picture. I am using python3.5 on Ubuntu 16.04.
One other thing, you can be more explicit by adding the option justify=RIGHT in your label widget commands to alight the label text to right.
from tkinter import *
class App(Frame):
def __init__(self, parent):
Frame.__init__(self, parent, background='pink')
# String
self.user_p = StringVar()
self.user_q = StringVar()
self.user_r = StringVar()
self.user_result = StringVar()
# Label
self.description = Label(self, text="!p v (q ^ r)")
self.pLabel = Label(self, text="p")
self.qLabel = Label(self, text="q")
self.rLabel = Label(self, text="r")
self.resultLabel = Label(self, text="Result")
# Entry
self.p=Entry(self, textvariable=self.user_p, width=10)
self.q=Entry(self, textvariable=self.user_q, width=10)
self.r=Entry(self, textvariable=self.user_r, width=10)
self.result=Entry(self, bg="white", state=DISABLED, text="")
# Grid
# Labels
self.description.grid(row=0, column=3, sticky=N)
self.pLabel.grid(row=1, column=0, sticky=E)
self.qLabel.grid(row=1, column=2, sticky=E)
self.rLabel.grid(row=1, column=4, sticky=E)
# Entry
self.p.grid(row=1, column=1)
self.q.grid(row=1, column=3)
self.r.grid(row=1, column=5)
if __name__ == '__main__':
root=Tk()
root.geometry("300x50")
app=App(root)
app.pack(fill="both", expand=True)
app.mainloop()

Tkinter - How to display image when clicking a button?

First time here so forgive me as this is my FIRST attempt at making a silly GUI game (if you want to call it that). I'm trying to get the user to click a button and the image of their selection pops up. I can't seem to figure out how to get the image to pop up though.
Image does show if I run it separately.
My code:
from Tkinter import *
root = Tk()
class PokemonClass(object):
def __init__(self, master):
frame = Frame(master)
frame.pack()
self.WelcomeLabel = Label(root, text="Welcome! Pick your Pokemon!",
bg="Black", fg="White")
self.WelcomeLabel.pack(fill=X)
self.CharButton = Button(root, text="Charmander", bg="RED", fg="White",
command=self.CharClick)
self.CharButton.pack(side=LEFT, fill=X)
self.SquirtButton = Button(root, text="Squirtle", bg="Blue", fg="White")
self.SquirtButton.pack(side=LEFT, fill=X)
self.BulbButton = Button(root, text="Bulbasaur", bg="Dark Green",
fg="White")
self.BulbButton.pack(side=LEFT, fill=X)
def CharClick(self):
print "You like Charmander!"
global CharSwitch
CharSwitch = 'Yes'
CharSwitch = 'No'
if CharSwitch == 'Yes':
CharPhoto = PhotoImage(file="Charmander.gif")
ChLabel = Label(root, image=CharPhoto)
ChLabel.pack()
k = PokemonClass(root)
root.mainloop()
This works, but the actual image no longer shows, if I keep the PhotoImage OUT of the class it will print but I want to have it print IF they click the specific button:
from Tkinter import *
root = Tk()
class PokemonClass(object):
def __init__(self, master):
frame = Frame(master)
frame.pack()
self.WelcomeLabel = Label(root, text = "Welcome! Pick your Pokemon!", bg = "Black", fg = "White")
self.WelcomeLabel.pack(fill = X)
self.CharButton = Button(root, text = "Charmander", bg = "RED", fg = "White", command = CharClick)
self.CharButton.pack(side = LEFT, fill = X)
self.SquirtButton = Button(root, text = "Squirtle", bg = "Blue", fg = "White")
self.SquirtButton.pack(side = LEFT, fill = X)
self.BulbButton = Button(root, text = "Bulbasaur", bg = "Dark Green", fg = "White")
self.BulbButton.pack(side = LEFT, fill = X)
def CharClick():
print "You like Charmander!"
CharPhoto = PhotoImage(file = "Charmander.gif")
ChLabel = Label(root, image = CharPhoto)
ChLabel.pack()
k = PokemonClass(root)
root.mainloop()
You need to maintain a reference to your PhotoImage object. Unfortunately there is an inconsistency in tkinter in that attaching a Button to a parent widget increments the reference count, but adding an image to a widget does not increment the reference count. As a consequence at the moment the CharPhoto variable goes out of scope at the end of the function CharClick, the number of reference to the PhotoImage falls to zero and the object is made available for garbage collection.
If you keep a reference to the image somewhere, it will appear. When you kept it globally it remained in scope for the entire script and hence appeared.
You can keep a reference to it in the PokemonClass object or in the Label widget.
Below is the later of those options
from Tkinter import *
root = Tk()
class PokemonClass(object):
def __init__(self, master):
frame = Frame(master)
frame.pack()
self.WelcomeLabel = Label(root, text="Welcome! Pick your Pokemon!",
bg="Black", fg="White")
self.WelcomeLabel.pack(fill=X)
self.CharButton = Button(root, text="Charmander", bg="RED", fg="White",
command=self.CharClick)
self.CharButton.pack(side=LEFT, fill=X)
self.SquirtButton = Button(root, text="Squirtle", bg="Blue", fg="White")
self.SquirtButton.pack(side=LEFT, fill=X)
self.BulbButton = Button(root, text="Bulbasaur", bg="Dark Green",
fg="White")
self.BulbButton.pack(side=LEFT, fill=X)
def CharClick(self):
print "You like Charmander!"
global CharSwitch
CharSwitch = 'Yes'
CharPhoto = PhotoImage(file="Charmander.gif")
ChLabel = Label(root, image=CharPhoto)
ChLabel.img = CharPhoto
ChLabel.pack()
CharSwitch = 'No'
k = PokemonClass(root)
root.mainloop()
The solution which helped me is just simply declaring all the image variables on the next line after 'root = Tk()'. Doing so won't spoil your code or anything.

get previous Entry

I am trying to make a tkinter widget that will remember the previous entry. The problem I am having is the that the button method I made erases the previous entry every time its pressed.
from Tkinter import *
class step1():
def __init__(self):
pass
def getTextbook(self):
temp = str(textbook.get())
textbook.delete(0, END)
x = " "
x += temp
print x
def equal_button(self):
print getTextbook(self)
root = Tk()
root.title("step1")
root.geometry("600x600")
s = step1()
app = Frame(root)
app.grid()
label = Label(app, text = "step1")
label.grid()
textbook = Entry(app, justify=RIGHT)
textbook.grid(row=0, column = 0, columnspan = 3, pady = 5)
textbook2 = Entry(app, justify=RIGHT)
textbook2.grid(row=1, column = 0, columnspan = 3, pady = 5)
button1 = Button(app, text = "Return", command = lambda: s.getTextbook())
button1.grid()
button2 = Button(app, text="Equal")
button2.grid()
root.mainloop()
The variable X in your getTextbook() is being overwritten every time you set it to " ". Try a list instead, and append each entry to the list when the button is pressed:
from Tkinter import *
root = Tk()
textbookList = []
def getTextbook():
textbookList.append(textbook.get())
textbook.delete(0,END)
print textbookList
textbook = Entry(root)
textbook.pack()
btn1 = Button(root, text='Return', command=getTextbook)
btn1.pack()
root.mainloop()

Categories

Resources