Goal: Display variable across classes
Issue: Updating labels, specifically line 99
Errors: Logical only
Environment: Python 3.6.9, Tk 8.6.8, OS Ubuntu 18.04
Write up:
I am trying to display variable pPanelSettings.cutLength
in the pViewSettings
class on line 99 of the included code, however I can not get it to update/refresh. Including textvariable
in any of my labels makes it display blank, even though I give them an initial value. In the included attempt, I left in a non-functioning refresh command (line 106) as well as a non-functioning attempt to trace (line 107). Other attempts have included:
update_idletasks
,
creating an additional string variable that simply reformatted the integer variable just to confirm that wasn't the issue,
referencing pViewSettings
and pPanelSettings
inside of each other (caused a loop),
as well as a few others that I am forgetting at this point.
I am most interested in finding out the "why" of whatever I am missing as I will be repeating this process again in the future. Sorry to fill up the forums with another newbie Label question, but I'm just at a loss at this point on my own. I am confident it is a simple fix that I am just completely missing.
Ideally I'd like to understand where I'm going wrong with textvariable
, as that seems most likely to be the simple solution, but comparing to examples online I am still not seeing where I am wrong.
Me:
I was not planning on doing GUI learning until early next year, however my timeline for this project was accelerated so I am having to dive in quick.
Posts I've gone through:
What are the arguments to Tkinter variable trace method callbacks?
Update Tkinter Label from variable
https://yagisanatode.com/2018/02/26/how-to-display-and-entry-in-a-label-tkinter-python-3/
Many others, but just lost all my bookmarks.
Code:
import tkinter as tk
import time as time
import math as math
#create main window
root = tk.Tk()
root.title('machine')
#create main container
mainFrame = tk.Frame(root)
#layout main container, grow with window size
mainFrame.pack(fill=tk.BOTH, expand=True)
#create globals
inchesInFeet = tk.IntVar()
answerReset = tk.IntVar()
#set globals
answerReset.set(0)
#create classes
class Page(tk.Frame):
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
def show(self):
self.lift()
class pPanelSettings(Page):
def __init__(self, *args, **kwargs):
Page.__init__(self, *args, **kwargs)
#create variables
self.cutFeet = tk.IntVar()
self.cutInches = tk.IntVar()
self.cutLength = tk.IntVar()
self.panelCutConfirm = tk.BooleanVar()
#set variables
self.cutFeet.set(0)
self.cutInches.set(0)
self.cutLength.set(0)
self.panelCutConfirm.set(0)
#widgets
self.pageTitle = tk.Label(self, text='PANEL SETTINGS')
self.panelBlock = tk.LabelFrame(self, padx=5, pady=5)
self.panelLabel = tk.Label(self.panelBlock, text='CURRENT PANEL SET LENGTH')
self.panelSetting = tk.Label(self.panelBlock, text=self.cutLength.get())
self.messageDisplay = tk.Label(self, text='Set cut length (feet):')
self.wYesNo = tk.LabelFrame(self, padx=5, pady=5)
self.bYes = tk.Button(self.wYesNo, text='ENTER', command=self.setCutFeet, height=4, activebackground='green1', background='green2')
self.response = tk.Entry(self, justify='center')
#layout
self.pageTitle.pack(side='top', fill='x')
self.panelBlock.pack(side='top', fill='x', pady=5)
self.panelLabel.pack(side='left', fill='x', padx=50)
self.panelSetting.pack(side='right', fill='x')
self.messageDisplay.pack(side='top', fill='x', pady=60)
self.wYesNo.pack(side='bottom', fill='x', padx=20, pady=20, expand=True)
self.bYes.pack(side='left', fill='both', padx=10, expand=True)
self.response.pack(side='bottom', fill='x', padx=20, pady=60)
#settings
self.response.focus_set()
def clearText(self):
self.response.delete(0, 'end')
def transition(self):
self.after(2000, self.pageReset)
def pageReset(self): #resets widgets to initial view
self.response.delete(0, 'end')
self.messageDisplay.config(text='Set cut length (feet):')
self.response.pack(side='bottom', fill='x', padx=20, pady=60)
self.wYesNo.pack(side='bottom', fill='x', padx=20, pady=20, expand=True)
self.bYes.config(command=self.setCutFeet)
self.panelSetting.pack(side='right', fill='x')
def setCutFeet(self):
self.cutFeet.set(int(self.response.get()))
self.setCutConfirm()
def setCutConfirm(self):
self.panelCutConfirm.set(True)
self.cutLength.set(self.cutFeet.get())
self.panelSetting.config(text=self.cutLength.get())
print(self.cutLength.get()) ##verification test point using shell
self.messageDisplay.config(text='Panel cut length set.')
self.wYesNo.pack_forget()
self.transition()
class pViewSettings(Page): ##this page needs auto update/refresh to display current settings from other pages
def __init__(self, *args, **kwargs):
Page.__init__(self, *args, **kwargs)
#pages to objects
oPanelSettings = pPanelSettings(self)
#widgets
self.pageTitle = tk.Label(self, text='VIEW SETTINGS')
self.panelBlock = tk.LabelFrame(self, padx=5, pady=5)
self.panelLabel = tk.Label(self.panelBlock, text='PANEL LENGTH')
self.panelSetting = tk.Label(self.panelBlock, text=oPanelSettings.cutLength.get())
#layout
self.pageTitle.pack(side='top', fill='x')
self.panelBlock.pack(side='top', fill='x', pady=5)
self.panelLabel.pack(side='left', fill='x', padx=50)
self.panelSetting.pack(side='right', fill='x')
#actions
self.refreshSelf() ##i know that this doesn't work, but i do not understand why
oPanelSettings.cutLength.trace('r', self.refreshSelf) ##i really feel like this should work though
def refreshSelf(self):
#pages to objects
oPanelSettings = pPanelSettings(self)
#action
self.after(1000, self.refreshSelf)
self.panelSetting.config(text=oPanelSettings.cutLength.get())
class pMainView(tk.Frame):
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
#pages to objects
oPanelSettings = pPanelSettings(self)
oViewSettings = pViewSettings(self)
#create menu and view windows
buttonFrame = tk.Frame(self)
container = tk.Frame(self)
buttonFrame.pack(side='left', fill='both', expand=False) #menu column
container.pack(side='right', fill='both', expand=True) #main view window
#place page objects into main view window
oPanelSettings.place(in_=container, x=0, y=0, relwidth=1, relheight=1)
oViewSettings.place(in_=container, x=0, y=0, relwidth=1, relheight=1)
#create menu buttons
bPanelSettings = tk.Button(buttonFrame, text='Panel Settings', command=oPanelSettings.lift)
bViewSettings = tk.Button(buttonFrame, text='View Settings', command=oViewSettings.lift)
#menu layout
bPanelSettings.pack(side='top', fill='both', expand=True)
bViewSettings.pack(side='top', fill='both', expand=True)
#startup display page
oViewSettings.show()
if __name__ == '__main__':
root = tk.Tk()
oMainView = pMainView(root)
oMainView.pack(side='top', fill='both', expand=True)
root.wm_geometry('1024x600')
root.mainloop()
Any and all help is greatly appreciated. Someone call Bryan Oakley to save me! :) :)
EDIT #1: Shortened code towards minimal reproduction.