3

I'm making a wxPython app that I need to update a value from the internet every 15 seconds. Is there any way I can have a function to set the value, and make it run in the background at this interval, without interrupting the program?

EDIT: Here's what I'm trying:

import thread

class UpdateThread(Thread):
    def __init__(self):
        self.stopped = False
        UpdateThread.__init__(self)
    def run(self):
        while not self.stopped:
            downloadValue()
            time.sleep(15)
def downloadValue():
    print x

UpdateThread.__init__()
Y__
  • 1,687
  • 2
  • 11
  • 23
tkbx
  • 15,602
  • 32
  • 87
  • 122

3 Answers3

2

What you want is to add a thread that runs your task at a specified pace.

You may have a look at this great answer here : https://stackoverflow.com/a/12435256/667433 to help you achieve this.

EDIT : Here is the code that should work for you :

import time
from threading import Thread # This is the right package name

class UpdateThread(Thread):
    def __init__(self):
        self.stopped = False
        Thread.__init__(self) # Call the super construcor (Thread's one)
    def run(self):
        while not self.stopped:
            self.downloadValue()
            time.sleep(15)
    def downloadValue(self):
        print "Hello"

myThread = UpdateThread()
myThread.start()

for i in range(10):
    print "MainThread"
    time.sleep(2)

Hope it helps

Community
  • 1
  • 1
Y__
  • 1,687
  • 2
  • 11
  • 23
  • So I've got the class made, then how to you start it? I'm getting `NameError: name 'Thread' is not defined` when I start it. – tkbx Mar 05 '13 at 13:56
  • Got it working. So, once it's started, it runs on it's own, in the same terminal, but separate from the main flow of the script? – tkbx Mar 05 '13 at 14:19
  • Yes, exactly. To convince yourself of that, you can add a piece of code after the `myThread.start()` line (as shown in the answer) – Y__ Mar 05 '13 at 14:22
  • it's working well, but the thread keeps going after the program should have ended. Any way to make it die with the main thread? – tkbx Mar 06 '13 at 18:06
  • 1
    Yes, just set `myThread.stopped` to `True` and it will end after at most 15 secs. You can know it by calling `myThread.join()` function in your main thread that will block until the thread is done. – Y__ Mar 06 '13 at 19:00
  • so since I'm using wxPython, just put myThread.stopped outside of MainLoop? – tkbx Mar 06 '13 at 21:05
  • 1
    Yes exactly, or you can also put it in your `OnExit` event handler. – Y__ Mar 07 '13 at 08:56
0

I have made something similar to this:

-you need a thread to run in the background .

-And a define a 'custom' event , so that the tread can notify the UI when needed

Create the custom WX event

(MyEVENT_CHECKSERVER, EVT_MYEVENT_CHECKSERVER) = wx.lib.newevent.NewEvent()

on UI "init" you can bind the event , and start the thread

    #  bind the custom event 
    self.Bind(EVT_MYEVENT_CHECKSERVER, self.foo)
    # and start the worker thread
    checkServerThread = threading.Thread(target=worker_checkServerStatus
                                        ,args=(self,) )
    checkServerThread.daemon = True
    checkServerThread.start()

the worker thread can be something like this ,ps. caller is the UI instance

def worker_checkServerStatus(caller):

   while True:    
       # check the internet code here
       evt = MyEVENT_CHECKSERVER(status='Some internet Status' ) #make a new event
       wx.PostEvent(caller, evt) # send the event to the UI
       time.sleep(15) #ZZZzz for a bit

Edit: miss read the question...

Community
  • 1
  • 1
andsoa
  • 500
  • 1
  • 6
  • 11
0

Another way to do that is with a timer:

import threading
stopNow = 0
def downloadValue():
    print("Running downloadValue")
    if not stopNow: threading.Timer(15,downloadValue).start()

downloadValue()

This is a classic pattern for repeating a function: the function itself adds a timed call to itself. To start the cycle, call the function (it returns immediately). To break the cycle set stopNow to 1.

jeanl
  • 11
  • 4