Tkinter: Passing StringVar from one window to another

Tkinter: Passing StringVar from one window to another



So I have two python files that each contain two tkinter windows. One is a Root Tk instance and the other is a Toplevel Tk instance. I am trying to get two string variables in the Toplevel instance from the Root instance, called self.taskhours, and self.taskminutes in the Root instance, once the Toplevel instance is opened. I am fairly certain that I am not passing the Root instance to the Toplevel instance properly. Can anyone assist?



Here is the first file, named "timex.py":


import tkinter as tk
from tkinter import ttk

class TimeX(tk.Frame):
def __init__(self,master):
# INIT WINDOW
import datetime
tk.Frame.__init__(self,master=master)
self.pack()

self.master.title("TimeX") # Add title to main window
# TOP MENU #
self.master.menu = tk.Menu(master)
# TOP MENU # FILE MENU #
self.master.filemenu = tk.Menu(self.master.menu)
self.master.menu.add_cascade(label="File",menu=self.master.filemenu)
self.master.menu.add_command(label="New File",command=self.new_file)

self.frames = [
tk.Frame(self), # TASKITEM
tk.Frame(self), # TIME INPUT
tk.Frame(self), # INIT BUTTON
# tk.Frame(self), # SHOWS 00:00:00 until INIT BUTTON PRESSED

]
# START FRAME 0
frame = self.frames[0]
self.taskitem = tk.StringVar(self,"TaskItem") # Entry
# self.taskplan = tk.StringVar(self) # Listbox
# self.taskdesc = tk.StringVar(self) # Textbox
frame.entries = [
tk.Entry(frame,textvariable=self.taskitem),
]
for i,entry in enumerate(frame.entries):
entry.grid(row=0,column=i)
frame = self.frames[1]
# THE REAL
# self.taskhours = tk.StringVar(self,"Hours")
# self.taskminutes = tk.StringVar(self,"Minutes")
# THE FOO
self.taskhours = tk.StringVar(self,"1")
self.taskminutes = tk.StringVar(self,"30")
frame.labels = [
tk.Label(frame,text="Estimated Duration")
]
frame.entries = [
tk.Entry(frame,textvariable=self.taskhours),
tk.Entry(frame,textvariable=self.taskminutes)
]
# frame.menubuttons = [
# tk.Menubutton(frame,text="Hour(s)",textvariable=self.taskhours),
# tk.Menubutton(frame,text="Minute(s)",textvariable=self.taskminutes)
# ]
# self.tasktime = [int(self.taskhours.get()),int(self.taskminutes.get())]
# frame.items = frame.labels + frame.menubuttons
frame.items = frame.labels + frame.entries
for i,item in enumerate(frame.items):
item.grid(row=0,column=i)
frame = self.frames[2]
frame.buttons = [
tk.Button(frame,text="Start Task",command=self.start_timer).pack()
]
# for i,button in enumerate(frame.buttons):
# button.grid(row=0,column=i)

for frame in self.frames:
for child in frame.winfo_children():
child.grid_configure(padx=5,pady=5)
frame.pack(padx=10,pady=10,anchor="w")

def start_timer(self):
import timer
timer.run()

def new_file(self):
# import new_file
# new_file.run()
pass

def run():
root = tk.Tk()
app = TimeX(root)
app.mainloop()

run()



and here is the second file, named "timer.py":


import tkinter as tk
# import time
from datetime import datetime
# timeVar : MM
class Window(tk.Frame):
def __init__(self,master):
tk.Frame.__init__(self,master=master)
self.pack()
self.master.title("Timer")
self.time = tk.StringVar(self,"00:00:00")
self.label = tk.Label(self,text=self.time.get()).pack()
self.totalseconds = self.tasktime_to_total_seconds(self.taskhours.get(),self.taskminutes.get())

self.countdown(totalseconds)

def tasktime_to_total_seconds(taskhours,taskminutes):
taskhours = int(taskhours)
taskminutes = int(taskminutes)
totalseconds = taskhours * 3600 + taskminutes * 60
return totalseconds

def countdown(totalseconds):
if totalseconds == 1:
self.label.configure(text="On to the next!")
tk.Button(self,text="Close Window",command=self.quit)
totalseconds = totalseconds - 1
stdtime = total_seconds_to_standard(totalseconds)
self.time.set(stdtime)
self.label.configure(text=self.time)
self.master.after(1000,self.countdown)

def total_seconds_to_standard(total_seconds):
seconds = total_seconds
hoursec = seconds - seconds % 3600
hours = int(hoursec/3600)
seconds = seconds - hoursec

minutesec = seconds - seconds % 60
minutes = int(minutesec/60)
seconds = seconds - minutesec

standard = str(hours) + ":" + str(minutes) + ":" + str(seconds)

return standard

def run():
top = tk.Toplevel()
window = Window(top)



and the error that I am getting when I open the second window via pressing the "Start Task" button, is,



"AttributeError: 'Window' object has no attribute 'taskhours'"



It's clearly a matter of passing the root object to the toplevel object properly, but I am unsure on the exact implementation! Thanks in advance for any assistance!



To get it working, I was just going to store the variables in a file but that doesn't seem to be the bestest way to do it so I figured I'd see what the interwebz had to say about the matter.





Well, that Window doesn't have a taskhours attribute, or a taskminutes, but in its __init__ method you call both self.taskhours.get() and self.taskminutes.get().
– PM 2Ring
Aug 25 at 20:14


Window


taskhours


taskminutes


__init__


self.taskhours.get()


self.taskminutes.get()




1 Answer
1



if you have two python files you would need to import them as modules to use their
functions and objects.



take a look at circular dependent imports here:
https://stackabuse.com/python-circular-imports/






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

How do I collapse sections of code in Visual Studio Code for Windows?

Node.js puppeteer - Use values from array in a loop to cycle through pages