I am developing a Python Tkinter app which can open multiple instances of a toplevel window.
The following extract tests if an instance of the toplevel class is running and if not, runs a new instance. If it does exist, it brings it to the foreground.
if (ConsoleGui.winlog[pcs] is not None):
try:
ConsoleGui.winlog[pcs].lift()
except:
ConsoleGui.winlog[pcs] = ClassEpsL.CreateEspLog(Console, pcs)
else:
ConsoleGui.winlog[pcs] = ClassEpsL.CreateEspLog(Console, pcs)
This works nicley.
My problem is the each instance of the toplevel window, has a function which runs in an "after" loop to update a text widget eg
def CreateEspLog(self, pcs):
espLWin = Toplevel(self)
...
text = Text(espLWin, wrap="none", width=600, height=400)
...
def refreshEspL(self):
print("pcsNode: {}".format(ClassEpsL.pcsNode))
if MQTT.BrokerConnected:
ClassEpsL.espLogUpdate(self)
espLWin.after(200, refreshEspL, self)
espLWin.after(200, refreshEspL, self)
return espLWin
The latest instance of the toplevel
window takes over the running of this loop from the older ones which no longer update.
I haven't been able to find a solution to either:
create instances which are somehow uniquely identified for the line:
espLWin.after(200, refreshEspL, self)
Or can I somehow call my toplevel
window function refreshEspL
from my root window eg
ConsoleGui.winlog[pcs].refreshEspL(self)
I managed to solve this with help from: How do I create a class to make multiple toplevels of one main window in tkinter?
I am new to Python and Tkinter, but this might help someone else new.
By creating my instance as a class with variable names like this:
class ClassEspL(Toplevel):
def __init__(self, top_level, textWW, pcsNode):
super().__init__()
self.top_level = top_level
self.title("ESP Logging WIN: {} - {}".format(pcsNode, Site.PCSList[pcsNode].eui64))
self.textW = textWW
textW = Text(self, wrap="none", width=70 , height=20, bg="black")
textW.pack()
self.updateF(pcsNode, textW)
def updateF(self, pcsNode, textW):
print("pcsNode: {}".format(pcsNode))
textW.insert(END, line, tag)
textW.see(END)
self.after(1000, self.updateF, pcsNode, textW)
and calling it from my root window like this:
def callback_ESPLogger(self, pcs):
def createShowLoggerWindow(self, pcs):
if (ConsoleGui.winlog[pcs] is not None):
try:
ConsoleGui.winlog[pcs].lift()
except:
ConsoleGui.winlog[pcs] = ClassEspL("top_level{}".format(pcs), "textW{}".format(pcs), pcs)
else:
ConsoleGui.winlog[pcs] = ClassEspL("top_level{}".format(pcs), "textW{}".format(pcs), pcs)
if pcs == 99: # create multiple instance
for pcs in range(0, Site.Config.numberofpcs):
createShowLoggerWindow(self, pcs)
else:
createShowLoggerWindow(self, pcs) # create 1 instance
... each instance of my ClassEspL has a unique name and handle and my updateF functions don't take over each other.