> (For good reasons, attachments are dropped when messages are
distributed
> on the forum.)

For whom who can not get the attachment:-)

###a simplified version of "Programming Python 4ed, Example 10-20.
import _thread as thread
import queue
threadQueue = queue.Queue(maxsize=0)

def queueChecker(widget, delayMsecs=100):
    try:
        (callback, args) = threadQueue.get(block=False)
    except queue.Empty:
        pass
    else:
        callback(*args)

    widget.after(delayMsecs,
        lambda: queueChecker(widget, delayMsecs)) # back to event loop

def threaded(action, args, context, onExit, onProgress):
    def progress(*any):
        threadQueue.put((onProgress, any + context))  # <--line 18
    action(progress=progress, *args)
    threadQueue.put((onExit, context))

def startThread(action, args, context, onExit, onProgress):
    thread.start_new_thread(
        threaded, (action, args, context, onExit, onProgress))

if __name__ == '__main__':
    import time
    import tkinter as tk

    def onEvent(i):  # code that spawns thread
        myname = 'thread-%s' % i
        startThread(
            action     = threadaction,
            args       = (i, 3),
            context    = (myname,),  # <-- line 35
            onExit     = threadexit,
            onProgress = threadprogress)

    # thread's main action
    def threadaction(id, reps, progress):
        for i in range(reps):
            time.sleep(1)
            progress(i)  # <--line 43, progress callback: queued

    # thread exit/progress callbacks: dispatched off queue in main thread
    def threadexit(myname):
        print('%s\texit' % myname)

    def threadfail(exc_info, myname):
        print('%s\tfail\t%s' % (myname, exc_info[0]))

    def threadprogress(count, myname):
        print('%s\tprog\t%s' % (myname, count))

    # make enclosing GUI and start timer loop in main thread
    # spawn batch of worker threads on each mouse click: may overlap
    root = tk.Tk()
    queueChecker(root)
    root.bind('<Button-1>',   # 3.x need list for map, range ok
              lambda event: list(map(onEvent, range(2))) )
    root.mainloop()


Ben Finney 於 2018/6/3 上午 11:57 寫道:
Jach Fong <jf...@ms4.hinet.net> writes:

The attached is a script

Thanks for making an example script. Instead of attaching it, please
post it along with your message so that everyone can read it. You can
make scripts suitable for posting in your message, by keeping them short
and simple <URL:http://sscce.org/>.

(For good reasons, attachments are dropped when messages are distributed
on the forum.)

One thing make me puzzled is that the "any + context" at line
18. The "any" was passed as an integer from line 43 and the "context"
was defined as a tuple at line 35. This concatenation works! how?

If the values are actually as you say, then Python should raise a
TypeError. For example::

     >>> 1 + ("foo", "bar")
     Traceback (most recent call last):
       File "<stdin>", line 1, in <module>
     TypeError: unsupported operand type(s) for +: 'int' and 'tuple'

What makes me suspect that's different from your code, is that you say
“defined as a tuple”. Names in Python have no defined type; only an
object has a type, and operations (like ‘+’ only take effect on the
object, not the name.


---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus

--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to