I am trying to create a simple Tkinter user registration app and have run into a problem. I want to get the input from an Entry to another function.
My code as of now:
from Tkinter import *
def addUsr():
username = sv.get() #here
password = sv1.get() #here
page = open("Users.txt", 'r+')
contents = page.read()
page.write("--->")
page.write("\n")
page.write("username: " + username)
page.write("\n")
page.write("password: " + password)
page.write("\n")
page.write("<---")
page.write("\n")
page.close()
print contents
def reg():
usrs = Tk()
usrs.title("Text")
usrs.geometry('450x300+200+200')
sv = StringVar()
sv1 = StringVar()
ent1 = Entry(usrs, textvariable=sv).pack()
ent2 = Entry(uses, textvariable=sv1).pack
button1 = Button(usrs, text="submit", command=addUsr).pack(side='bottom', padx=15, pady=15)
usrs.mainloop()
I want to get the sv and sv1 into the addUsr function, but this code returns the error message:
username = sv.get()
NameError: global name 'sv' is not defined
When the code is built up so that the second function is not a function this code works. I just want to find a way to get the same result but using this structure. How do you suppose I do this?
I think this is a structural problem. You normally would use a class to create the application and put everything under that class. Then accessing functions and variables from anywhere is straightforward. I have created a simple example because I do not have time to rewrite all of your code!
from Tkinter import *
class Application(Frame): # create a class to hold the application within
def __init__(self, master): # boot it up
""" Initialize the frame. """
Frame.__init__(self, master)
self.grid()
self.create_widgets()
self.var1 = "var1"
self.var2 = "var2"
def create_widgets(self): # create the GUI interface
self.lbl = Label(self, text = "xxxx")
self.lbl.grid(row = 0, column = 0, columnspan = 2, sticky = W, pady = 4)
self.input = Text(self, width = 35, height = 5, wrap = WORD)
self.input.grid(row = 1, column = 0, columnspan = 2, sticky = W)
self.submit_button = Button(self, text = "submit", command = self.functionX)
self.submit_button.grid(row = 2, column = 0, columnspan = 2, sticky = W)
def functionX(self):
print "do some stuff"
self.var3 = "yet another variable" # create a variable in one function for access in another
self.functionY() # call one function from another function
def functionY(self):
print "do something else"
print self.var1 # access some class variables
print self.var2
print self.var3
root = Tk()
root.title("xxxxxxxxxxxx")
root.geometry("330x310")
app = Application(root)
I hope this helps, it is pretty self explanatory when you run the code and read it to understand what is going on. (by the way I ended up using PyQt/Pyside with QtDesigner instead of Tkinter, you may want to check that out if you don't know about it already).
Related
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()
The is going to work like this:
Launcher with buttons to run different functions on other scripts. However when I try launching the "New Account" a new window pops up as it should but the entry field prints blank.
Launcher:
import Setup as s
import Stock as t
from tkinter import *
import os
root = Tk()
root.title("SWM Launcher")
welcome = Label(root, text = "Welcome to the Stock and Wastage Manager Launcher")
welcome.grid(row = 0, column =1, columnspan =3)
l1 = Label (root, text = "Please choose from the options below")
l1.grid(row = 1, column =1, columnspan =3)
submit = Button(root, text = "Open Account", command = lambda: program())
submit.grid(row = 3, column =1)
submit = Button(root, text = "New Account", command = lambda: s.setep())
submit.grid(row = 3, column =2)
What I'm trying to get to work from the setup script
class App:
def __init__(self, window):
window.title("SWM Account Maker")
window.config(bg = "grey")
window.geometry("800x900")
self.searched = StringVar()
name = Entry(window, width = 50, borderwidth = 5,textvariable=self.searched).grid(row = 2, column =1, columnspan =3)
submit = Button(window, text = "Submit", command = lambda: self.name()).grid(row = 3, column =2)
def name (self):
works = self.searched.get()
print(works)
def setep():
root = Tk()
app = App(root)
root.mainloop()
The output i get from the print statement is blank yet if I run setup separately it works fine.I feel like I have miss understood something and no solution's I have found online work. also its my first project working with classes and Tkinter.
It is because you have used multiple instances of Tk(). Either change Tk() to Toplevel() inside setep() function or change self.searched = StringVar() to self.searched = StringVar(window) inside App.init()
I was wondering how to calculate stuff using tkinter buttons. I'm making a simple program to calculate seconds to hours:minutes:seconds. The user inputs an integer using the entry widget on the seconds box and when they press calculate, they get the result via the converted time line. I'm confused on how to start calculating it. I know you get the integer via .get, but I'm stuck on how to do that and calculate it in a h:m:s format. This is my code so far.
import tkinter
from tkinter import *
class TimeConverterUI():
def __init__(self):
self.root_window = Tk()
self.root_window.geometry('400x150')
self.root_window.title('Seconds Converter')
self.text()
self.calculate_button()
self.quit_button()
self.root_window.wait_window()
def text(self):
row_label = tkinter.Label(
master = self.root_window, text = 'Seconds: ')
row_label.grid( row = 0, column = 0, columnspan=2, padx=10, pady=10,
sticky = tkinter.W)
secondsEntry = Entry(master = self.root_window)
secondsEntry.grid(row = 0, column = 1)
row_label = tkinter.Label(
master = self.root_window, text = 'Converted Time(H:M:S): ').grid(row=1)
def calculate_button(self):
quit = Button(self.root_window, text = "Calculate", command = self.calculate)
quit.grid(row = 3, column = 0, columnspan = 3, pady=20,
sticky = tkinter.W)
def calculate(self):
pass
def quit_button(self):
quit = Button(self.root_window, text = "Quit", command = self.quit)
quit.grid(row = 3, column = 3, columnspan = 3, pady=20,
sticky = tkinter.E)
def quit(self) -> bool:
self.root_window.destroy()
return True
if __name__ == '__main__':
convert=TimeConverterUI()
First break this code below into 2 lines if you ever want to use row_label later because this will return NoneType. You should define it first then use .grid on it (just like your button).
row_label = tkinter.Label(
master = self.root_window, text = 'Converted Time(H:M:S): ').grid(row=1)
Now you can create another label to show the result. Remember to put self. before its name so you can use it in the calculate function. Also change secondsEntry to self.secondsEntry for the same reason.Now you just use int(self.secondsEntry.get()) in that function and do the required calculations. Then set the result to that result label with .configure(text=str(result))
I really need help with some code. I don't expect you to write it for me, since it is a school project, but I am just really lost and need help.
The code I am writing is some sort of production system.
It doesn't need to actually be able to send a task anywhere, since this is just an imagined scenario.
The code has to consist of three files: data.py, model.py and gui.py.
Gui can access the two other files
Data can only access model
Model can't access either of the other two.
My teacher had written some of the code witch I have continued on. Some of the text is in danish, but most comments are in English.
The code is as follows.
data.py
from model import *
class Data(object):
def __init__(self):
self.units = []
self.finished_tasks = []
def __str__(self):
result = "These tasks have been finished: "
for i in self.finished_tasks:
result += str(i)
return result
def task_done(self, unit):
done_task = unit.task_done()
if done_task != None:
#TODO: add to list of finished tasks
pass
def add_task(self, name, amount, unit):
s = Springroll_task(name, amount)
unit.add_to_queue(s)
def read_from_database(self):#doesn't actually read from db..
self.units.append(Production_unit("maskine1"))
self.units.append(Production_unit("maskine2"))
self.add_task("Miniruller", 100, self.units[0])
self.add_task("Maxiruller", 200, self.units[0])
self.add_task("HowIRoll", 3000, self.units[0])
self.add_task("RulleMarie", 40, self.units[1])
self.add_task("Rullesten", 500, self.units[1])
self.add_task("Toiletpapirsruller", 6000, self.units[1])
model.py
class Springroll_task(object):
def __init__(self, name, amount):
self.name = name
self.amount = amount
def __str__(self):
return self.name + " " + str(self.amount)
class Production_unit(object):
def __init__(self, amount={}, name={},):
#name of the production unit
self.name = name
self.amount = amount
#the current task
self.current_task = None
#the tasks in the queue
self.springroll_queue = []
#the size of the queue
self.queue_size = 0
def __str__(self):
#TODO
return self.name + " " + str(self.amount)
def add_to_queue(self, task={}):
if self.current_task == None:
self.current_task = task
else:
self.springroll_queue.append(task)
self.queue_size += 1
#remember to update queue_size
pass
def task_done(self):
#TODO: remember the old current task.
#Set the current task to be the first in the queue (and remove from queue)
# - if there is a task in the queue.
#return the old current task.
#remember to update queue_size
self.queue_size -= 1
pass
gui.py
from tkinter import *
from model import *
from data import Data
class Application(Frame):
def __init__(self, master, unit):
self.mod = Production_unit()
super(Application, self).__init__(master)
self.grid()
self.unit = unit
self.create_widgets()
def create_widgets(self):
self.unit_name_lbl = Label(self, text = self.unit.name)
self.unit_name_lbl.grid(row = 0, column = 0, columnspan = 2, sticky = W)
self.cur_prod_lbl = Label(self, text = "produktion nu: ")
self.cur_prod_lbl.grid(row = 1, column = 0, columnspan = 2, sticky = W)
self.prod_lbl = Label(self, text = "produkt")
self.prod_lbl.grid(row = 2, column = 0, sticky = W)
self.amount_lbl = Label(self, text = "antal")
self.amount_lbl.grid(row = 2, column = 1, sticky = W)
#Label for production now
self.amount1_lbl = Label(self, text = " ", bg ="red")
self.amount1_lbl.grid(row = 3, column = 0, sticky = W)
self.amount2_lbl = Label(self, text = " ", bg ="red")
self.amount2_lbl.grid(row = 3, column = 1, sticky = W)
#Button for task finished
self.finished_but = Button(self, text = "Opgave afsluttet", bg ="pink", command=self.mod.task_done)
self.finished_but.grid(row = 3, column = 2, sticky = W)
#Label for queue
self.queue_lbl = Label(self, text = "Kø")
self.queue_lbl.grid(row = 4, column = 0, sticky = W)
#Label for production queue
for i in range(0,3):
self.name_lbl =Label(self, text = self.mod.springroll_queue, bg="red", width= 6)
self.name_lbl.grid(row = 5+i, sticky = W)
for j in range(0,3):
self.qt_lbl =Label(self, text = self.mod.springroll_queue, bg="red", width= 4)
self.qt_lbl.grid(row = 5+j, column = 1)
self.new_lbl = Label(self, text = "Ny")
self.new_lbl.grid(row = 10, column = 0, sticky = W)
#Entry for entries
self.eq1_ent = Entry(self, text = "", width=6)
self.entry_name = self.eq1_ent.get()
self.eq1_ent.grid(row = 11, sticky = W)
self.ea1_ent = Entry(self, text = "", width=4)
self.ea1_ent.grid(row = 11, column = 1, sticky = W)
#Button for add to queue
self.add_but = Button(self, text = "Tilføj til kø", bg ="pink", command=self.mod.add_to_queue(self.ea1_ent.get()))
self.add_but.grid(row = 11, column = 2, sticky = W)
def done(self):
d.task_done(self.unit)
self.redraw()
def add(self):
n = "Nyt navn" #read from gui
a = "Nyt antal" #read from gui
d.add_task(n, a, unit)
self.redraw()
def redraw(self):
#TODO
pass
# main
root = Tk()
root.title("Daloon")
root.geometry("300x300")
d = Data()
d.read_from_database()
p = d.units[0]
app = Application(root, p)
root.mainloop()
So it currently looks like this:
What I need to be able to do is to take an input in the bottom two entry widgets and put them in one of the 4 label widgets above, beginning from the top and then in the queue afterwards, this should happen when I press the button add_but, which seems to be gone currently.
After that I need the task stored in the data file when the "Opgave afsluttet" button is pressed.
I really hope someone is able to help me!
I edited it with some suggestions, and am calling the right self.eq1_ent.get() now, I think. I dont get any error any longer, now I just don't really know how to make it do what I want.
Edit 2: I am slowly getting some stuff, so i have made changes in the model.py and gui.py...
It looks like this now:
self.eq1 is not defined. you have self.q1_lbl and self.eq1_ent.
To access the label use self.q1_lbl.
To be able to set text to your label create them as following:
self.var = StringVar()
self.unit_name_lbl = Label(self, textvariable=self.var)
For example, from redraw() you can set 'text' to self.unit_name_lbl like this : self.var.set('text').
Check if you missed self in d.add_task(n, a, unit)
When you do command=mod.add_to_queue(self.ea1_ent.get()) the mod.add_to_queue function will be called directly, if you want to pass argument to this function when user press the button, you can use lambda:
command=lambda: mod.add_to_queue(self.ea1_ent.get)
I wrote a simple program importing Tkinter just to play with Radio Buttons. I find that I'm getting errors in very, very weird places.
from Tkinter import *
class Application (Frame):
def __init__(self, master):
Frame.__init__(self, master)
self.grid()
self.create_widgets()
def create_widgets(self):
Label(self, text = "Select the last book you read.").grid (row = 0, column = 0, sticky = W)
self.choice = StringVar()
Radiobutton (self,text = "Nausea by Jean-Paul Sartre",variable = self.choice,
value = "Wake up. This is a dream. This is all only a test of the emergency broadcasting system.",
command = self.update_text).grid (row = 2, column = 1, sticky = W)
Radiobutton (self,
text = "Infinite Jest by David Foster Wallace",
variable = self.choice,
value = "Because an adult borne without the volition to choose the thoughts that he thinks, is going to get hosed ;)",
command = self.update_text).grid (row = 3, column = 1, sticky = W)
Radiobutton (self,
text = "Cat's Cradle by Kurt Vonnegut",
variable = self.choice,
value = " \"Here we are, trapped in the amber of the moment. There is no why!\" ",
command = self.update_text.grid (row = 4, column = 1, sticky = W)
self.txt_display = Text (self, width = 40, height = 5, wrap = WORD)
self.txt_display.grid (row = 6, column = 0, sticky = W)
#There is only one choice value - self.choice. That can be "printed."
def update_text(self):
message = self.choice.get()
self.txt_display.delete (0.0, END)
self.txt_display.insert (0.0, message)
# The Main
root = Tk()
root.title ("The Book Critic One")
root.geometry ("400x400")
app = Application (root)
root.mainloop()
I seem to be getting errors in very odd places. One came in the "=" sign in the Label attribution and when I changed it to == when i was playing around, the next one came in the variable part of the RadioButton attributes.
Any help would be greatly appreciated. Won't be able to respond immediately as I have to leave to work in a bit, but if you do spot where the bugs are, please let me know.
There are a lot of things going on here. I'll just point out the few that I've found quickly looking at this.
For your Label you shouldn't have = before your parameters...
Label = (self, text = "Select the last book you read.").grid (row = 0, column = 0, sticky = W)
to:
Label(self, text = "Select the last book you read.").grid (row = 0, column = 0, sticky = W)
Change all instances of RadioButton to Radiobutton as that is the actual name of the class in Tkinter.
choice1, choice2, and choice3 do not exist in Application.
More Stuff:
def create_widgets() is missing the self parameter: def create_widgets(self)
Your update_text() function isn't working because you're referencing self.text_display, I believe you want this to be self.txt_display since that is how you defined it previously.