Tkinter autoreload function spawns new loop each time it's called
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.
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.
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
add a comment |
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.
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.
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
@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
add a comment |
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.
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.
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
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.
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.
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
python tkinter
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
add a comment |
@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
add a comment |
2 Answers
2
active
oldest
votes
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.
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
|
show 1 more comment
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(...
onButton
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())
lambda:masterReload()
is overkill. Best to change that tomasterReload
– Mike - SMT
Jan 2 at 21:17
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
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
|
show 1 more comment
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.
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
|
show 1 more comment
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.
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.
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
|
show 1 more comment
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
|
show 1 more comment
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(...
onButton
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())
lambda:masterReload()
is overkill. Best to change that tomasterReload
– Mike - SMT
Jan 2 at 21:17
add a comment |
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(...
onButton
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())
lambda:masterReload()
is overkill. Best to change that tomasterReload
– Mike - SMT
Jan 2 at 21:17
add a comment |
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(...
onButton
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())
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(...
onButton
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())
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 tomasterReload
– Mike - SMT
Jan 2 at 21:17
add a comment |
lambda:masterReload()
is overkill. Best to change that tomasterReload
– 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
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
@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