How to pass value of Entry from one class to another class? - python

Target / Goal:
My goal is to pass an Entry widget from one class Window1 to another class Window2?
Code:
Here's my current code:
from tkinter import *
import tkinter.ttk as ttk
def main():
root = Tk()
app = Window1(root)
root.mainloop()
class Window1:
def __init__(self,master):
self.master = master
self.master.geometry('400x150')
self.frame = Frame(self.master)
self.frame.pack(fill="both", expand=True)
self.label_username = Label(self.frame, text="Username: ",font=("bold",16))
self.entry_username = Entry(self.frame, font = ("bold", 14))#pass this into Window 2 as label
self.label_username.pack()
self.entry_username.pack()
self.logbtn = Button(self.frame, text="Login", font = ("bold", 10), command=self._login_btn_clicked)
self.logbtn.pack()
def _login_btn_clicked(self):
# print("Clicked")
username = self.entry_username.get()
if username == 'test':
self.master.withdraw()
self.newWindow = Toplevel(self.master)
self.app = Window2(self.newWindow)
else:
self.entry_username.delete(0,"end")
class Window2:
def __init__(self,master):
notebook = ttk.Notebook(master)
notebook.pack(expand = 1, fill = "both")
#Frames
main = ttk.Frame(notebook)
notebook.add(main, text='Main-Screen')
self.output = Label(main, text = )#OUTPUT HERE
self.output.pack()
if __name__ == '__main__':
main()
What I have tried:
Here, at Window2 code:
self.output = Label(main, text = )#OUTPUT HERE
self.output.pack()
Text is currently empty, but I am trying to return the value from Window1 at widget name: self.entry_username but not sure how to do it.
This is what I have tried:
self.output = Label(main, text = Window1().entry_username.get())#OUTPUTHERE
self.output.pack()
Error:
But this is the error:
self.output = Label(main, text = Window1().entry_username.get())#OUTPUT HERE
TypeError: __init__() missing 1 required positional argument: 'master'

This really has nothing to do with tkinter, you use the same technique whether it's plain python or tkinter or anything else. To access an attribute of an object, you need to have a reference to the object.
For example, if you want Window2 to have access to data in Window1, you can pass the instance of Window1 to Window2:
def _login_btn_clicked(self):
...
self.newWindow = Toplevel(self.master)
self.app = Window2(self.newWindow, window1=self)
...
class Window2:
def __init__(self,master, window1):
self.window1=window1
...
username = self.window1.entry_username.get()
self.output = Label(main, text=username)

Related

Python Tkinter - Unable to obtain entry value after widgets in window are destroyed

I'm writing a program using Tkinter that prompts the user to enter their name as a value, then displays it after the contents of the window are cleared. However, I'm unable to retrieve this value. I'd like to know how I could fix this.
Below is my code:
import tkinter
class Window:
def __init__(self):
self.main_window = tkinter.Tk()
self.main_window.title("Window Title")
self.main_window.geometry("300x100")
self.frame = tkinter.Frame(self.main_window)
self.label1 = tkinter.Label(self.frame,
text="Enter name:")
self.label1.pack(pady=5)
self.name_entry = tkinter.Entry(self.frame,
width=20)
self.name_entry.pack(pady=5)
self.name = tkinter.StringVar()
self.name_label = tkinter.Label(self.frame,
textvariable=self.name)
def frame2():
for widget in self.frame.winfo_children():
widget.destroy()
self.frame.pack_forget()
self.frame2.pack(pady=20)
self.name_enter = tkinter.Button(self.frame,
text="Confirm",
command=lambda:
[self.getname(),frame2()])
self.name_enter.pack(pady=5)
self.frame.pack()
self.frame2 = tkinter.Frame(self.main_window)
self.label2 = tkinter.Label(self.frame2,
text="Your name is " +
str(self.name.get()) +
".")
self.label2.pack(pady=5)
tkinter.mainloop()
def getname(self):
nameget = str(self.name_entry.get())
self.name.set(nameget)
if __name__ == '__main__':
window = Window()
Using the suggestion from jasonharper I edit the code for a possible fix. I added another label above your label that takes in the StringVar() and then changed the label parameters to textvariable=self.name which gets the input.
import tkinter
class Window:
def __init__(self):
self.main_window = tkinter.Tk()
self.main_window.title("Window Title")
self.main_window.geometry("300x100")
self.frame = tkinter.Frame(self.main_window)
self.label1 = tkinter.Label(self.frame,
text="Enter name:")
self.label1.pack(pady=5)
self.name_entry = tkinter.Entry(self.frame,
width=20)
self.name_entry.pack(pady=5)
self.name = tkinter.StringVar()
self.name_label = tkinter.Label(self.frame,
textvariable=self.name)
def frame2():
for widget in self.frame.winfo_children():
widget.destroy()
self.frame.pack_forget()
self.frame2.pack(pady=20)
self.name_enter = tkinter.Button(self.frame,
text="Confirm",
command=lambda:
[self.getname(),frame2()])
self.name_enter.pack(pady=5)
self.frame.pack()
self.frame2 = tkinter.Frame(self.main_window)
self.labelx = tkinter.Label(self.frame2, text="Your name is")
self.labelx.pack()
self.label2 = tkinter.Label(self.frame2, textvariable=self.name)
self.label2.pack(pady=5)
tkinter.mainloop()
def getname(self):
nameget = str(self.name_entry.get())
self.name.set(nameget)
if __name__ == '__main__':
window = Window()

Tkinter class module reference exception

I'm having some trouble calling a module(updateUI) within a class (Eventsim).
The line Sim = EventSim() throws an exception because it's missing an argument (parent). I can't figure out how to fix this / reference the parent object.
This is my first attempt wit Tkinter and my python knowledge is also rather limited (for now).
from Tkinter import *
class EventSim(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
def updateUI(self,IP_Address,Port_Number,Events_Directory):
self.parent.title('ECP Event Simulator')
self.parent.resizable(0, 0)
self.pack(fill=BOTH, expand=True)
frame1 = Frame(self)
frame1.pack(fill=X)
frame2 = Frame(self)
frame2.pack(fill=X)
frame3 = Frame(self)
frame3.pack(fill=X)
frame4 = Frame(self)
frame4.pack(fill=X)
frame5 = Frame(self)
frame5.pack(fill=X)
frame6 = Frame(self)
frame6.pack(fill=X,pady=(10,30))
frame7 = Frame(self)
frame7.pack(fill=X)
frame8 = Frame(self)
frame8.pack(fill=X,pady=(10,0))
Main_Label = Label(frame1,text='ECP EventSim')
Main_Label.pack(side=LEFT,padx=100)
IP_Label = Label(frame2,text='IP Address:')
IP_Label.pack(side=LEFT,padx=10)
Port_Label = Label(frame2,text='Port:')
Port_Label.pack(side=RIGHT,padx=70)
IP_Text = Entry(frame3)
IP_Text.pack(fill=X,side=LEFT,padx=10)
IP_Text = Entry(frame3)
IP_Text.pack(fill=X,side=RIGHT,padx=10)
Dir_Label = Label(frame4,text='Events Directory:')
Dir_Label.pack(side=LEFT,padx=10)
Dir_Text = Entry(frame5)
Dir_Text.pack(fill=X,side=LEFT,padx=10,expand=True)
Save_Button = Button(frame6,text='Save Config')
Save_Button.pack(fill=X,side=LEFT,padx=10,expand=True)
Con_Button = Button(frame7,text='Connect')
Con_Button.pack(fill=X,side=LEFT,padx=10,expand=True)
Send_Button = Button(frame8,text='Start Sending Events')
Send_Button.pack(fill=X,side=LEFT,padx=10,expand=True)
def main():
root = Tk()
root.geometry("300x300+750+300")
app = EventSim(root)
root.mainloop()
Sim = EventSim()
Sim.updateUI('1','1','1')
main()
The parent should be root. So, replacing:
def main():
root = Tk()
root.geometry("300x300+750+300")
app = EventSim(root)
root.mainloop()
Sim = EventSim()
Sim.updateUI('1','1','1')
main()
with:
root = Tk()
root.geometry("300x300+750+300")
Sim = EventSim(root)
Sim.updateUI('1','1','1')
root.mainloop()
brings up the desired window. The updateUI method requires work to populate the entry fields but you can remove its parent parameter since you already have the parent instance variable.
Remove Sim = EventSim() and move Sim.updateUI('1','1','1') to main:
def main():
root = Tk()
root.geometry("300x300+750+300")
app = EventSim(root)
app.updateUI('1','1','1')
root.mainloop()
main()

Returning the value of button from a class using Tkinter

Here I'm trying to select a value using the button. How do I return the value of 'option' from the class? Thanks
I would like to have something like my_gui_value=option_box(root).option
Thanks
from Tkinter import Tk, Label, Button
class option_box:
def __init__(self, master):
self.master = master
master.title("A simple GUI")
self.label = Label(master, text="This is our first GUI!")
self.label.pack()
self.train_button = Button(master,text="Training",command=self.train)
self.train_button.pack()
self.test_button = Button(master, text="Testing", command=self.test)
self.test_button.pack()
def train(self):
option=0
print option
def test(self):
option=1
print option
root = Tk()
my_gui = option_box(root)
root.mainloop()
Save it instead of returning it.
def train(self):
self.option = 0
print self.option
def test(self):
self.option = 1
print self.option

Python widgets and button

I'm trying to add a "Done" button to my program that will print the content of both Entry widgets to a new box. I can get the button to appear, but I can't get the information to show up in a new box. What am I doing wrong?
from Tkinter import *
class Application(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.grid()
self._name = StringVar()
self._name.set("Enter name here")
self._age = IntVar()
self._age.set("Enter age here")
top = self.winfo_toplevel() # find top-level window
top.title("Entry Example")
self._createWidgets()
self._button = Button(self,
text = "Done")
self._button.grid(row = 1, column = 0, columnspan = 2)
def _createWidgets(self):
textEntry = Entry(self, takefocus=1,
textvariable = self._name, width = 40)
textEntry.grid(row=0, sticky=E+W)
ageEntry = Entry(self, takefocus=1,
textvariable = self._age, width = 20)
ageEntry.grid(row=1, sticky=W)
def _widget(self):
tkMessageBox.showinfo
# end class Application
def main():
Application().mainloop()
You need to assign an action to your button using command: option.
To get what is written in Entry you need to use get() method.
showinfo you need two arguments, one is the title, the other one is what is going to be shown.
Also you need to import tkMessageBox.
Here is a working example.
import Tkinter as tk
import tkMessageBox
class Example(tk.Frame):
def __init__(self,root):
tk.Frame.__init__(self, root)
self.txt = tk.Entry(root)
self.age = tk.Entry(root)
self.btn = tk.Button(root, text="Done", command=self.message)
self.txt.pack()
self.age.pack()
self.btn.pack()
def message(self):
ent1 = self.txt.get()
ent2 = self.age.get()
tkMessageBox.showinfo("Title","Name: %s \nAge: %s" %(ent1,ent2))
if __name__=="__main__":
root = tk.Tk()
root.title("Example")
example = Example(root)
example.mainloop()

Update User interface when a button is pressed Tkinter

So basically i want the user interface to be updated when a user presses the start button, however when i call the maininit function it returns an error saying that root is not defined, is there any way i can get around this?
from PIL import Image, ImageTk
from Tkinter import Tk, Label, BOTH,W, N, E, S, Entry, Text, INSERT, Toplevel
from ttk import Frame, Style, Button, Label
import Tkinter
import Callingwordlist
class MainGameUI(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
self.initUI()
def initUI(self):
self.parent.title("Type!")
self.pack(fill=BOTH, expand=1)
style = Style()
style.configure("TFrame", background="black")
Type = Image.open("Type!.png")
Typet = ImageTk.PhotoImage(Type)
label3 = Label(self, image=Typet)
label3.image = Typet
label3.place(x=0, y=0)
self.pack(fill=BOTH, expand=1)
MenuButton = Button(self, text="Main Menu")
MenuButton.pack()
MenuButton.place(x=560,y=20,height = 80,width = 100)
QuitButton = Button(self,text="Quit",command=self.parent.destroy)
QuitButton.pack()
QuitButton.place(x=680,y=20,height = 80,width = 100)
StartButton = Button(self, text="Start",command=maininit)
StartButton.pack()
StartButton.place(x=440,y=20,height=80,width=100)
def maininit():
entry1 = Entry(root,font =("Courier",38), width = 22)
entry1.pack(ipady=10)
entry1.config(bg="#CEF6F5")
entry1.place(x=90,y=200)
entry2 = Entry(root,font =("Courier",38), width = 22)
entry2.pack(ipady=10)
entry2.config(bg="#CEF6F5")
entry2.place(x=90,y=350)
text1 = Text(root,width=23,height=1,font=("Courier",38))
text1.pack()
text1.config(bg="black",fg="white",bd=0)
text1.place(x=90,y=150)
text1.insert(INSERT,"Hello")
text2 = Text(root,width=23,height=1,font=("Courier",38))
text2.pack()
text2.config(bg="black",fg="white",bd=0)
text2.place(x=90,y=300)
text2.insert(INSERT,"Test")
dtext = Text(root,font=("Courier",28),width=10,height=1)
dtext.pack()
dtext.config(bg="black",fg="white",bd=0)
dtext.insert(INSERT,"Difficulty")
dtext.place(x=90,y=500)
atext = Text(root,font=("Courier",28),width=8,height=1)
atext.pack()
atext.config(bg="black",fg="white",bd=0)
atext.insert(INSERT,"Accuracy")
atext.place(x=595,y=500)
dentry = Text(root,font=("Courier",28),width=1,height=1)
dentry.pack()
dentry.config(bg="white",bd=0)
dentry.place(x=180,y=550)
dentry.insert(INSERT,"Test")
def main():
root = Tk()
root.geometry("860x640+300+300")
app = MainGameUI(root)
root.mainloop()
if __name__ == '__main__':
main()
In your application, root is a locally defined variable confined to main(). You need to somehow pass root as an argument to maininit. Here is one way to do this:
First, change maininit() so that it accepts a parameter root:
def maininit(root):
...
Now, change the callback on StartButton so it passes maininit() the root object:
class MainGameUI(Frame):
...
def initUI(self):
...
StartButton = Button(self, text="Start",command=lambda: maininit(self.parent))
...
You are defining root inside a function, whose calling namespace is not available to the maininit() function. If you omit the definition of main() and instead write
if __name__ == "__main__":
root = Tk()
root.geometry("860x640+300+300")
app = MainGameUI(root)
root.mainloop()
root will then be defined in the global module namespace, where it IS available to the code in the function.

Categories

Resources