Tkinter autoreload function spawns new loop each time it's called












2















I have a program that pulls and displays several updating values. I have a button that manually reloads the necessary information. My end goal is to have a text field where I can type in a value, and have the program reload every x seconds. My issue arises in setting the new loop interval value.



The following is a basic example of the issue I'm having:



import tkinter as tk
import datetime

class MainApplication(tk.Frame):
def __init__(self, parent, *args, **kwargs):
tk.Frame.__init__(self, parent, *args, **kwargs)
self.parent = parent
reloadTimer=tk.Entry(root)
reloadTimer.pack(side=tk.LEFT)
reloadTimer.insert(10,10)

def masterReload():
print("LOADING " + str(datetime.datetime.now()))
parent.after(int(reloadTimer.get())*1000, masterReload)

masterReloadButton = tk.Button(root, text='Set', command=lambda:masterReload())
masterReloadButton.pack()

masterReload()

if __name__ == "__main__":
root = tk.Tk()
MainApplication(root).pack()
root.mainloop()




My issue is that everytime I press the masterReloadButton, a new "reload-loop" is started.



For example:



This is the output before I press any buttons. Loop intervals are ~10 seconds apart.



Properly working Loop, ~10 seconds intervals



This is the output after I press my masterReloadButton, roughly 5 seconds into the loop. There are now two loops occurring concurrently, with about a 5 second offset. It does grab the new loop value, but it also spawns a new loop entirely.



Concurrent loops: unwanted result





I need the "set" button because otherwise the new timer value is only retrieved upon a reload. If someone enters a very large number, it would take a very long amount of time before the program would accept a new value.



To me, it seems like a new masterReload() process is created every time I hit my button. I need to either destroy the process each time, or reorganize my code so that it doesn't happen, but I'm unsure of how to do either.



Thanks in advance.










share|improve this question

























  • @stovfl I don't understand, could you clarify exactly what I should be disabling, and how I should go about doing it?

    – Emilio Garcia
    Jan 2 at 20:38











  • @stovfl I still want to be able to click the button and grab new values after the program has started.

    – Emilio Garcia
    Jan 2 at 20:44











  • @stovfl Yes, but I want to be able to inject new interval values. If someone enters 100000, they must wait 100000 seconds before being able to enter a different value. I want the button to be able to force a new interval, but I don't know how to do that without re-calling the function itself

    – Emilio Garcia
    Jan 2 at 20:58
















2















I have a program that pulls and displays several updating values. I have a button that manually reloads the necessary information. My end goal is to have a text field where I can type in a value, and have the program reload every x seconds. My issue arises in setting the new loop interval value.



The following is a basic example of the issue I'm having:



import tkinter as tk
import datetime

class MainApplication(tk.Frame):
def __init__(self, parent, *args, **kwargs):
tk.Frame.__init__(self, parent, *args, **kwargs)
self.parent = parent
reloadTimer=tk.Entry(root)
reloadTimer.pack(side=tk.LEFT)
reloadTimer.insert(10,10)

def masterReload():
print("LOADING " + str(datetime.datetime.now()))
parent.after(int(reloadTimer.get())*1000, masterReload)

masterReloadButton = tk.Button(root, text='Set', command=lambda:masterReload())
masterReloadButton.pack()

masterReload()

if __name__ == "__main__":
root = tk.Tk()
MainApplication(root).pack()
root.mainloop()




My issue is that everytime I press the masterReloadButton, a new "reload-loop" is started.



For example:



This is the output before I press any buttons. Loop intervals are ~10 seconds apart.



Properly working Loop, ~10 seconds intervals



This is the output after I press my masterReloadButton, roughly 5 seconds into the loop. There are now two loops occurring concurrently, with about a 5 second offset. It does grab the new loop value, but it also spawns a new loop entirely.



Concurrent loops: unwanted result





I need the "set" button because otherwise the new timer value is only retrieved upon a reload. If someone enters a very large number, it would take a very long amount of time before the program would accept a new value.



To me, it seems like a new masterReload() process is created every time I hit my button. I need to either destroy the process each time, or reorganize my code so that it doesn't happen, but I'm unsure of how to do either.



Thanks in advance.










share|improve this question

























  • @stovfl I don't understand, could you clarify exactly what I should be disabling, and how I should go about doing it?

    – Emilio Garcia
    Jan 2 at 20:38











  • @stovfl I still want to be able to click the button and grab new values after the program has started.

    – Emilio Garcia
    Jan 2 at 20:44











  • @stovfl Yes, but I want to be able to inject new interval values. If someone enters 100000, they must wait 100000 seconds before being able to enter a different value. I want the button to be able to force a new interval, but I don't know how to do that without re-calling the function itself

    – Emilio Garcia
    Jan 2 at 20:58














2












2








2








I have a program that pulls and displays several updating values. I have a button that manually reloads the necessary information. My end goal is to have a text field where I can type in a value, and have the program reload every x seconds. My issue arises in setting the new loop interval value.



The following is a basic example of the issue I'm having:



import tkinter as tk
import datetime

class MainApplication(tk.Frame):
def __init__(self, parent, *args, **kwargs):
tk.Frame.__init__(self, parent, *args, **kwargs)
self.parent = parent
reloadTimer=tk.Entry(root)
reloadTimer.pack(side=tk.LEFT)
reloadTimer.insert(10,10)

def masterReload():
print("LOADING " + str(datetime.datetime.now()))
parent.after(int(reloadTimer.get())*1000, masterReload)

masterReloadButton = tk.Button(root, text='Set', command=lambda:masterReload())
masterReloadButton.pack()

masterReload()

if __name__ == "__main__":
root = tk.Tk()
MainApplication(root).pack()
root.mainloop()




My issue is that everytime I press the masterReloadButton, a new "reload-loop" is started.



For example:



This is the output before I press any buttons. Loop intervals are ~10 seconds apart.



Properly working Loop, ~10 seconds intervals



This is the output after I press my masterReloadButton, roughly 5 seconds into the loop. There are now two loops occurring concurrently, with about a 5 second offset. It does grab the new loop value, but it also spawns a new loop entirely.



Concurrent loops: unwanted result





I need the "set" button because otherwise the new timer value is only retrieved upon a reload. If someone enters a very large number, it would take a very long amount of time before the program would accept a new value.



To me, it seems like a new masterReload() process is created every time I hit my button. I need to either destroy the process each time, or reorganize my code so that it doesn't happen, but I'm unsure of how to do either.



Thanks in advance.










share|improve this question
















I have a program that pulls and displays several updating values. I have a button that manually reloads the necessary information. My end goal is to have a text field where I can type in a value, and have the program reload every x seconds. My issue arises in setting the new loop interval value.



The following is a basic example of the issue I'm having:



import tkinter as tk
import datetime

class MainApplication(tk.Frame):
def __init__(self, parent, *args, **kwargs):
tk.Frame.__init__(self, parent, *args, **kwargs)
self.parent = parent
reloadTimer=tk.Entry(root)
reloadTimer.pack(side=tk.LEFT)
reloadTimer.insert(10,10)

def masterReload():
print("LOADING " + str(datetime.datetime.now()))
parent.after(int(reloadTimer.get())*1000, masterReload)

masterReloadButton = tk.Button(root, text='Set', command=lambda:masterReload())
masterReloadButton.pack()

masterReload()

if __name__ == "__main__":
root = tk.Tk()
MainApplication(root).pack()
root.mainloop()




My issue is that everytime I press the masterReloadButton, a new "reload-loop" is started.



For example:



This is the output before I press any buttons. Loop intervals are ~10 seconds apart.



Properly working Loop, ~10 seconds intervals



This is the output after I press my masterReloadButton, roughly 5 seconds into the loop. There are now two loops occurring concurrently, with about a 5 second offset. It does grab the new loop value, but it also spawns a new loop entirely.



Concurrent loops: unwanted result





I need the "set" button because otherwise the new timer value is only retrieved upon a reload. If someone enters a very large number, it would take a very long amount of time before the program would accept a new value.



To me, it seems like a new masterReload() process is created every time I hit my button. I need to either destroy the process each time, or reorganize my code so that it doesn't happen, but I'm unsure of how to do either.



Thanks in advance.







python tkinter






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 2 at 19:29







Emilio Garcia

















asked Jan 2 at 19:17









Emilio GarciaEmilio Garcia

107113




107113













  • @stovfl I don't understand, could you clarify exactly what I should be disabling, and how I should go about doing it?

    – Emilio Garcia
    Jan 2 at 20:38











  • @stovfl I still want to be able to click the button and grab new values after the program has started.

    – Emilio Garcia
    Jan 2 at 20:44











  • @stovfl Yes, but I want to be able to inject new interval values. If someone enters 100000, they must wait 100000 seconds before being able to enter a different value. I want the button to be able to force a new interval, but I don't know how to do that without re-calling the function itself

    – Emilio Garcia
    Jan 2 at 20:58



















  • @stovfl I don't understand, could you clarify exactly what I should be disabling, and how I should go about doing it?

    – Emilio Garcia
    Jan 2 at 20:38











  • @stovfl I still want to be able to click the button and grab new values after the program has started.

    – Emilio Garcia
    Jan 2 at 20:44











  • @stovfl Yes, but I want to be able to inject new interval values. If someone enters 100000, they must wait 100000 seconds before being able to enter a different value. I want the button to be able to force a new interval, but I don't know how to do that without re-calling the function itself

    – Emilio Garcia
    Jan 2 at 20:58

















@stovfl I don't understand, could you clarify exactly what I should be disabling, and how I should go about doing it?

– Emilio Garcia
Jan 2 at 20:38





@stovfl I don't understand, could you clarify exactly what I should be disabling, and how I should go about doing it?

– Emilio Garcia
Jan 2 at 20:38













@stovfl I still want to be able to click the button and grab new values after the program has started.

– Emilio Garcia
Jan 2 at 20:44





@stovfl I still want to be able to click the button and grab new values after the program has started.

– Emilio Garcia
Jan 2 at 20:44













@stovfl Yes, but I want to be able to inject new interval values. If someone enters 100000, they must wait 100000 seconds before being able to enter a different value. I want the button to be able to force a new interval, but I don't know how to do that without re-calling the function itself

– Emilio Garcia
Jan 2 at 20:58





@stovfl Yes, but I want to be able to inject new interval values. If someone enters 100000, they must wait 100000 seconds before being able to enter a different value. I want the button to be able to force a new interval, but I don't know how to do that without re-calling the function itself

– Emilio Garcia
Jan 2 at 20:58












2 Answers
2






active

oldest

votes


















1














One way to prevent the issue you are seeing is to disable the button after its been pressed.



We can start the master_reload loop and disable the button at the same time with a lambda expression.



Here is your code cleaned up a little with the button set to disabled after first press.



Update: Now updates after loop right away instead of waiting for last loop to finish.



import tkinter as tk
import datetime


class MainApplication(tk.Tk):
def __init__(self):
super().__init__()
self.reload_timer = tk.Entry(self)
self.reload_timer.pack(side='left')
self.reload_timer.insert(10, 10)
self.active_after = None
self.time_tracker = None
self.btn = tk.Button(self, text='Set', command=self.set_time_tracker)
self.btn.pack()

def master_reload(self):
print("LOADING {}".format(datetime.datetime.now()))
self.active_after = self.after(self.time_tracker*1000, self.master_reload)

def set_time_tracker(self):
x = self.reload_timer.get()
if x.isdigit():
if int(x) > 0:
if self.active_after is not None:
self.after_cancel(self.active_after)
self.active_after = None
self.time_tracker = int(x)
self.master_reload()
else:
self.time_tracker = int(x)
self.master_reload()
else:
self.after_cancel(self.active_after)
self.active_after = None
else:
if self.active_after is not None:
self.after_cancel(self.active_after)
self.active_after = None


if __name__ == "__main__":
MainApplication().mainloop()


The benefit here is you can change the time any time you want without causing duplicate loops and even stop the loop by typing a zero 0 or any letters and pressing set.






share|improve this answer


























  • Thank you Mike, the second bit of code is exactly what I was looking for - being able to edit the interval at any point. +1

    – Emilio Garcia
    Jan 2 at 21:19











  • @EmilioGarcia I am getting ready to add a method to the class that will let you cancel the existing after timer so you do not need to wait for it to elapse before new timer is set.

    – Mike - SMT
    Jan 2 at 21:23











  • When I first tested your code I thought I was able to do that. Hmm. (When I first tested, the timer value was reprinted in the console, but I don't see it now, or in your posts edit history. I readded print(x) for testing). However, now when I retest, I seem to be coming across the same issue I had initially, where after re-setting the timer variable, a double loop starts. See here: i.imgur.com/6wUcsIb.png

    – Emilio Garcia
    Jan 2 at 21:34











  • I have updated my code so it will update the after loop right away.

    – Mike - SMT
    Jan 2 at 21:37











  • The new code seems to work perfectly. I've re-marked as resolved. Thank you again.

    – Emilio Garcia
    Jan 2 at 21:38



















1















Question: I want the button to be able to force a new interval




The new interval is computed using



int(reloadTimer.get())*1000


therefore no Button click are required.





To force a new interval, you have to cancel the current running reload_after() loop and start a new one.



Use, two functions, masterReload(), cancel/start reload_after() on Button click.

The other, reload_after(), shows the values by looping.




Cancel .after(... on Button click:




    self.after_id = None

def masterReload():
# New intervall

# Cancel previous reload_after() loop
if self.after_id:
self.after_cancel(self.after_id)
self.after_id = None

# Start new reload_after() loop
parent.after(0, reload_after)

def reload_after():
print("LOADING " + str(datetime.datetime.now()))
self.after_id = parent.after(int(reloadTimer.get())*1000, reload_after)

masterReloadButton = tk.Button(root, text='Set', command=lambda:masterReload())





share|improve this answer


























  • lambda:masterReload() is overkill. Best to change that to masterReload

    – Mike - SMT
    Jan 2 at 21:17











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54011977%2ftkinter-autoreload-function-spawns-new-loop-each-time-its-called%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














One way to prevent the issue you are seeing is to disable the button after its been pressed.



We can start the master_reload loop and disable the button at the same time with a lambda expression.



Here is your code cleaned up a little with the button set to disabled after first press.



Update: Now updates after loop right away instead of waiting for last loop to finish.



import tkinter as tk
import datetime


class MainApplication(tk.Tk):
def __init__(self):
super().__init__()
self.reload_timer = tk.Entry(self)
self.reload_timer.pack(side='left')
self.reload_timer.insert(10, 10)
self.active_after = None
self.time_tracker = None
self.btn = tk.Button(self, text='Set', command=self.set_time_tracker)
self.btn.pack()

def master_reload(self):
print("LOADING {}".format(datetime.datetime.now()))
self.active_after = self.after(self.time_tracker*1000, self.master_reload)

def set_time_tracker(self):
x = self.reload_timer.get()
if x.isdigit():
if int(x) > 0:
if self.active_after is not None:
self.after_cancel(self.active_after)
self.active_after = None
self.time_tracker = int(x)
self.master_reload()
else:
self.time_tracker = int(x)
self.master_reload()
else:
self.after_cancel(self.active_after)
self.active_after = None
else:
if self.active_after is not None:
self.after_cancel(self.active_after)
self.active_after = None


if __name__ == "__main__":
MainApplication().mainloop()


The benefit here is you can change the time any time you want without causing duplicate loops and even stop the loop by typing a zero 0 or any letters and pressing set.






share|improve this answer


























  • Thank you Mike, the second bit of code is exactly what I was looking for - being able to edit the interval at any point. +1

    – Emilio Garcia
    Jan 2 at 21:19











  • @EmilioGarcia I am getting ready to add a method to the class that will let you cancel the existing after timer so you do not need to wait for it to elapse before new timer is set.

    – Mike - SMT
    Jan 2 at 21:23











  • When I first tested your code I thought I was able to do that. Hmm. (When I first tested, the timer value was reprinted in the console, but I don't see it now, or in your posts edit history. I readded print(x) for testing). However, now when I retest, I seem to be coming across the same issue I had initially, where after re-setting the timer variable, a double loop starts. See here: i.imgur.com/6wUcsIb.png

    – Emilio Garcia
    Jan 2 at 21:34











  • I have updated my code so it will update the after loop right away.

    – Mike - SMT
    Jan 2 at 21:37











  • The new code seems to work perfectly. I've re-marked as resolved. Thank you again.

    – Emilio Garcia
    Jan 2 at 21:38
















1














One way to prevent the issue you are seeing is to disable the button after its been pressed.



We can start the master_reload loop and disable the button at the same time with a lambda expression.



Here is your code cleaned up a little with the button set to disabled after first press.



Update: Now updates after loop right away instead of waiting for last loop to finish.



import tkinter as tk
import datetime


class MainApplication(tk.Tk):
def __init__(self):
super().__init__()
self.reload_timer = tk.Entry(self)
self.reload_timer.pack(side='left')
self.reload_timer.insert(10, 10)
self.active_after = None
self.time_tracker = None
self.btn = tk.Button(self, text='Set', command=self.set_time_tracker)
self.btn.pack()

def master_reload(self):
print("LOADING {}".format(datetime.datetime.now()))
self.active_after = self.after(self.time_tracker*1000, self.master_reload)

def set_time_tracker(self):
x = self.reload_timer.get()
if x.isdigit():
if int(x) > 0:
if self.active_after is not None:
self.after_cancel(self.active_after)
self.active_after = None
self.time_tracker = int(x)
self.master_reload()
else:
self.time_tracker = int(x)
self.master_reload()
else:
self.after_cancel(self.active_after)
self.active_after = None
else:
if self.active_after is not None:
self.after_cancel(self.active_after)
self.active_after = None


if __name__ == "__main__":
MainApplication().mainloop()


The benefit here is you can change the time any time you want without causing duplicate loops and even stop the loop by typing a zero 0 or any letters and pressing set.






share|improve this answer


























  • Thank you Mike, the second bit of code is exactly what I was looking for - being able to edit the interval at any point. +1

    – Emilio Garcia
    Jan 2 at 21:19











  • @EmilioGarcia I am getting ready to add a method to the class that will let you cancel the existing after timer so you do not need to wait for it to elapse before new timer is set.

    – Mike - SMT
    Jan 2 at 21:23











  • When I first tested your code I thought I was able to do that. Hmm. (When I first tested, the timer value was reprinted in the console, but I don't see it now, or in your posts edit history. I readded print(x) for testing). However, now when I retest, I seem to be coming across the same issue I had initially, where after re-setting the timer variable, a double loop starts. See here: i.imgur.com/6wUcsIb.png

    – Emilio Garcia
    Jan 2 at 21:34











  • I have updated my code so it will update the after loop right away.

    – Mike - SMT
    Jan 2 at 21:37











  • The new code seems to work perfectly. I've re-marked as resolved. Thank you again.

    – Emilio Garcia
    Jan 2 at 21:38














1












1








1







One way to prevent the issue you are seeing is to disable the button after its been pressed.



We can start the master_reload loop and disable the button at the same time with a lambda expression.



Here is your code cleaned up a little with the button set to disabled after first press.



Update: Now updates after loop right away instead of waiting for last loop to finish.



import tkinter as tk
import datetime


class MainApplication(tk.Tk):
def __init__(self):
super().__init__()
self.reload_timer = tk.Entry(self)
self.reload_timer.pack(side='left')
self.reload_timer.insert(10, 10)
self.active_after = None
self.time_tracker = None
self.btn = tk.Button(self, text='Set', command=self.set_time_tracker)
self.btn.pack()

def master_reload(self):
print("LOADING {}".format(datetime.datetime.now()))
self.active_after = self.after(self.time_tracker*1000, self.master_reload)

def set_time_tracker(self):
x = self.reload_timer.get()
if x.isdigit():
if int(x) > 0:
if self.active_after is not None:
self.after_cancel(self.active_after)
self.active_after = None
self.time_tracker = int(x)
self.master_reload()
else:
self.time_tracker = int(x)
self.master_reload()
else:
self.after_cancel(self.active_after)
self.active_after = None
else:
if self.active_after is not None:
self.after_cancel(self.active_after)
self.active_after = None


if __name__ == "__main__":
MainApplication().mainloop()


The benefit here is you can change the time any time you want without causing duplicate loops and even stop the loop by typing a zero 0 or any letters and pressing set.






share|improve this answer















One way to prevent the issue you are seeing is to disable the button after its been pressed.



We can start the master_reload loop and disable the button at the same time with a lambda expression.



Here is your code cleaned up a little with the button set to disabled after first press.



Update: Now updates after loop right away instead of waiting for last loop to finish.



import tkinter as tk
import datetime


class MainApplication(tk.Tk):
def __init__(self):
super().__init__()
self.reload_timer = tk.Entry(self)
self.reload_timer.pack(side='left')
self.reload_timer.insert(10, 10)
self.active_after = None
self.time_tracker = None
self.btn = tk.Button(self, text='Set', command=self.set_time_tracker)
self.btn.pack()

def master_reload(self):
print("LOADING {}".format(datetime.datetime.now()))
self.active_after = self.after(self.time_tracker*1000, self.master_reload)

def set_time_tracker(self):
x = self.reload_timer.get()
if x.isdigit():
if int(x) > 0:
if self.active_after is not None:
self.after_cancel(self.active_after)
self.active_after = None
self.time_tracker = int(x)
self.master_reload()
else:
self.time_tracker = int(x)
self.master_reload()
else:
self.after_cancel(self.active_after)
self.active_after = None
else:
if self.active_after is not None:
self.after_cancel(self.active_after)
self.active_after = None


if __name__ == "__main__":
MainApplication().mainloop()


The benefit here is you can change the time any time you want without causing duplicate loops and even stop the loop by typing a zero 0 or any letters and pressing set.







share|improve this answer














share|improve this answer



share|improve this answer








edited Jan 2 at 21:36

























answered Jan 2 at 21:07









Mike - SMTMike - SMT

9,70121535




9,70121535













  • Thank you Mike, the second bit of code is exactly what I was looking for - being able to edit the interval at any point. +1

    – Emilio Garcia
    Jan 2 at 21:19











  • @EmilioGarcia I am getting ready to add a method to the class that will let you cancel the existing after timer so you do not need to wait for it to elapse before new timer is set.

    – Mike - SMT
    Jan 2 at 21:23











  • When I first tested your code I thought I was able to do that. Hmm. (When I first tested, the timer value was reprinted in the console, but I don't see it now, or in your posts edit history. I readded print(x) for testing). However, now when I retest, I seem to be coming across the same issue I had initially, where after re-setting the timer variable, a double loop starts. See here: i.imgur.com/6wUcsIb.png

    – Emilio Garcia
    Jan 2 at 21:34











  • I have updated my code so it will update the after loop right away.

    – Mike - SMT
    Jan 2 at 21:37











  • The new code seems to work perfectly. I've re-marked as resolved. Thank you again.

    – Emilio Garcia
    Jan 2 at 21:38



















  • Thank you Mike, the second bit of code is exactly what I was looking for - being able to edit the interval at any point. +1

    – Emilio Garcia
    Jan 2 at 21:19











  • @EmilioGarcia I am getting ready to add a method to the class that will let you cancel the existing after timer so you do not need to wait for it to elapse before new timer is set.

    – Mike - SMT
    Jan 2 at 21:23











  • When I first tested your code I thought I was able to do that. Hmm. (When I first tested, the timer value was reprinted in the console, but I don't see it now, or in your posts edit history. I readded print(x) for testing). However, now when I retest, I seem to be coming across the same issue I had initially, where after re-setting the timer variable, a double loop starts. See here: i.imgur.com/6wUcsIb.png

    – Emilio Garcia
    Jan 2 at 21:34











  • I have updated my code so it will update the after loop right away.

    – Mike - SMT
    Jan 2 at 21:37











  • The new code seems to work perfectly. I've re-marked as resolved. Thank you again.

    – Emilio Garcia
    Jan 2 at 21:38

















Thank you Mike, the second bit of code is exactly what I was looking for - being able to edit the interval at any point. +1

– Emilio Garcia
Jan 2 at 21:19





Thank you Mike, the second bit of code is exactly what I was looking for - being able to edit the interval at any point. +1

– Emilio Garcia
Jan 2 at 21:19













@EmilioGarcia I am getting ready to add a method to the class that will let you cancel the existing after timer so you do not need to wait for it to elapse before new timer is set.

– Mike - SMT
Jan 2 at 21:23





@EmilioGarcia I am getting ready to add a method to the class that will let you cancel the existing after timer so you do not need to wait for it to elapse before new timer is set.

– Mike - SMT
Jan 2 at 21:23













When I first tested your code I thought I was able to do that. Hmm. (When I first tested, the timer value was reprinted in the console, but I don't see it now, or in your posts edit history. I readded print(x) for testing). However, now when I retest, I seem to be coming across the same issue I had initially, where after re-setting the timer variable, a double loop starts. See here: i.imgur.com/6wUcsIb.png

– Emilio Garcia
Jan 2 at 21:34





When I first tested your code I thought I was able to do that. Hmm. (When I first tested, the timer value was reprinted in the console, but I don't see it now, or in your posts edit history. I readded print(x) for testing). However, now when I retest, I seem to be coming across the same issue I had initially, where after re-setting the timer variable, a double loop starts. See here: i.imgur.com/6wUcsIb.png

– Emilio Garcia
Jan 2 at 21:34













I have updated my code so it will update the after loop right away.

– Mike - SMT
Jan 2 at 21:37





I have updated my code so it will update the after loop right away.

– Mike - SMT
Jan 2 at 21:37













The new code seems to work perfectly. I've re-marked as resolved. Thank you again.

– Emilio Garcia
Jan 2 at 21:38





The new code seems to work perfectly. I've re-marked as resolved. Thank you again.

– Emilio Garcia
Jan 2 at 21:38













1















Question: I want the button to be able to force a new interval




The new interval is computed using



int(reloadTimer.get())*1000


therefore no Button click are required.





To force a new interval, you have to cancel the current running reload_after() loop and start a new one.



Use, two functions, masterReload(), cancel/start reload_after() on Button click.

The other, reload_after(), shows the values by looping.




Cancel .after(... on Button click:




    self.after_id = None

def masterReload():
# New intervall

# Cancel previous reload_after() loop
if self.after_id:
self.after_cancel(self.after_id)
self.after_id = None

# Start new reload_after() loop
parent.after(0, reload_after)

def reload_after():
print("LOADING " + str(datetime.datetime.now()))
self.after_id = parent.after(int(reloadTimer.get())*1000, reload_after)

masterReloadButton = tk.Button(root, text='Set', command=lambda:masterReload())





share|improve this answer


























  • lambda:masterReload() is overkill. Best to change that to masterReload

    – Mike - SMT
    Jan 2 at 21:17
















1















Question: I want the button to be able to force a new interval




The new interval is computed using



int(reloadTimer.get())*1000


therefore no Button click are required.





To force a new interval, you have to cancel the current running reload_after() loop and start a new one.



Use, two functions, masterReload(), cancel/start reload_after() on Button click.

The other, reload_after(), shows the values by looping.




Cancel .after(... on Button click:




    self.after_id = None

def masterReload():
# New intervall

# Cancel previous reload_after() loop
if self.after_id:
self.after_cancel(self.after_id)
self.after_id = None

# Start new reload_after() loop
parent.after(0, reload_after)

def reload_after():
print("LOADING " + str(datetime.datetime.now()))
self.after_id = parent.after(int(reloadTimer.get())*1000, reload_after)

masterReloadButton = tk.Button(root, text='Set', command=lambda:masterReload())





share|improve this answer


























  • lambda:masterReload() is overkill. Best to change that to masterReload

    – Mike - SMT
    Jan 2 at 21:17














1












1








1








Question: I want the button to be able to force a new interval




The new interval is computed using



int(reloadTimer.get())*1000


therefore no Button click are required.





To force a new interval, you have to cancel the current running reload_after() loop and start a new one.



Use, two functions, masterReload(), cancel/start reload_after() on Button click.

The other, reload_after(), shows the values by looping.




Cancel .after(... on Button click:




    self.after_id = None

def masterReload():
# New intervall

# Cancel previous reload_after() loop
if self.after_id:
self.after_cancel(self.after_id)
self.after_id = None

# Start new reload_after() loop
parent.after(0, reload_after)

def reload_after():
print("LOADING " + str(datetime.datetime.now()))
self.after_id = parent.after(int(reloadTimer.get())*1000, reload_after)

masterReloadButton = tk.Button(root, text='Set', command=lambda:masterReload())





share|improve this answer
















Question: I want the button to be able to force a new interval




The new interval is computed using



int(reloadTimer.get())*1000


therefore no Button click are required.





To force a new interval, you have to cancel the current running reload_after() loop and start a new one.



Use, two functions, masterReload(), cancel/start reload_after() on Button click.

The other, reload_after(), shows the values by looping.




Cancel .after(... on Button click:




    self.after_id = None

def masterReload():
# New intervall

# Cancel previous reload_after() loop
if self.after_id:
self.after_cancel(self.after_id)
self.after_id = None

# Start new reload_after() loop
parent.after(0, reload_after)

def reload_after():
print("LOADING " + str(datetime.datetime.now()))
self.after_id = parent.after(int(reloadTimer.get())*1000, reload_after)

masterReloadButton = tk.Button(root, text='Set', command=lambda:masterReload())






share|improve this answer














share|improve this answer



share|improve this answer








edited Jan 3 at 15:03

























answered Jan 2 at 21:09









stovflstovfl

8,25741133




8,25741133













  • lambda:masterReload() is overkill. Best to change that to masterReload

    – Mike - SMT
    Jan 2 at 21:17



















  • lambda:masterReload() is overkill. Best to change that to masterReload

    – Mike - SMT
    Jan 2 at 21:17

















lambda:masterReload() is overkill. Best to change that to masterReload

– Mike - SMT
Jan 2 at 21:17





lambda:masterReload() is overkill. Best to change that to masterReload

– Mike - SMT
Jan 2 at 21:17


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54011977%2ftkinter-autoreload-function-spawns-new-loop-each-time-its-called%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Monofisismo

Angular Downloading a file using contenturl with Basic Authentication

Olmecas