Skip to content

Commit

Permalink
updated docs #286
Browse files Browse the repository at this point in the history
  • Loading branch information
jarvisteach committed Dec 10, 2017
1 parent 1223bce commit c092490
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 7 deletions.
52 changes: 45 additions & 7 deletions docs/mkdocs/docs/pythonThreads.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,61 @@
# Threads - for things that take a long time...
---
# Threads
*For things that take a long time...*

---

Looping is great for regularly updating the GUI, but if you want to call a function that might take a long time (such as downloading a file) you need to use a [thread](https://en.wikipedia.org/wiki/Thread_(computing)).
[Looping](/pythonLoopsAndSleeps) is great for regularly updating the GUI, but if you want to call a function that might take a long time (such as downloading a file) you need to use a [thread](https://en.wikipedia.org/wiki/Thread_(computing)).

Running your functions in threads allows the main GUI loop to keep running, so that the GUI won't hang.

Threads don't always work nicely with GUIs, so your thread shouldn't try to change the GUI, instead you will need to put any GUI updates in a Queue.
Threads don't always work nicely with GUIs, so your thread **mustn't** try to change the GUI, instead you will need to put any GUI updates in a Queue ([see below](/pythonThreads/#queueing)).

## Threading
---

* `.thread(function, *args, *kwargs)`
This allows you to run your own functions in a separate thread, so they doesn't cause the GUI to hang.
Simply pass the name of your function (with no brackets) and any arguments that it requires.
Pass the name of your function (with no brackets) and any arguments that it requires.
For example: `app.thread(myFunction, param1, param2)`

* `.threadCallback(func, callback, *args, **kwargs)`
Runs the specified function in a thread, with the passed in arguments.
Once the thread completes, call the callback function, passing in any return value from the original function.

``` python
def uploadFile(filename):
# this would upload the file to a server
pass

def uploader(btn=None):
filename = app.getEntry("file")
if filename != "":
app.setLabel("uploadStatus", "Uploading " + filename)

# call uploadFile(), with the contents of the "file" entry box
# when uploadFile() completes, its return value will be passed to uploadComplete()
app.threadCallback(uploadFile, uploadComplete, filename)

def uploadComplete(success):
if success:
message = "Upload complete"
else:
message = "Upload failed"

app.queueFunction(app.setLabel, "uploadStatus", message)

app.addLabel("uploadStatus", "No uploads")
app.addFileEntry("file")
app.addButton("UPLOAD", uploader)
```

## Queueing
---

* `.queueFunction(function, *args, **kwargs)`
You mustn't try to update the GUI directly from your threads.
Instead, use this function to queue any updates.
Pass the name of the GUI function (with no brackets) and any arguments that it requires.
For example: `app.queueFunction(app.updateLabel, "l1", "new label text")`
For example: `app.queueFunction(app.setLabel, "l1", "new label text")`

``` python
downloadCount = 0
Expand All @@ -37,4 +76,3 @@ def downloader():
# put the downloader function in its own thread
app.thread(downloader)
```
* `.threadCallback(func, callback, *atgs, **kwargs)`
1 change: 1 addition & 0 deletions docs/mkdocs/docs/whatsNew.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* [#290](https://github.com/jarvisteach/appJar/issues/290) - fixed issue showing [AutoEntries](/pythonWidgets/#entry) in [subWindows](/pythonSubWindows)
* [#289](https://github.com/jarvisteach/appJar/issues/289) - new functions to change list in [AutoEntries](/pythonWidgets/#entry)
* [#288](https://github.com/jarvisteach/appJar/issues/288) - fixed issue showing [dialogs](/pythonDialogs/#message-boxes) in [subWindows](/pythonSubWindows)
* [#286](https://github.com/jarvisteach/appJar/issues/286) - added new [threaded callback](/pythonThreads), contributed by [@mpmc](https://github.com/mpmc)
* [#284](https://github.com/jarvisteach/appJar/issues/284) - new [dialogs](/pythonDialogs/#message-boxes) for strings, integers & floats
* [#283](https://github.com/jarvisteach/appJar/issues/283) - [questionBox](/pythonDialogs/#question-boxes) now returns Booleans instead of yes/no
* [#281](https://github.com/jarvisteach/appJar/issues/281) - resolved issues with [threads](/pythonThreads)
Expand Down
32 changes: 32 additions & 0 deletions examples/issues/issue286.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import sys
sys.path.append("../../")
from appJar import gui
import time

def uploadFile(filename):
for i in range(50):
print(i, filename)
time.sleep(.2)
return True

def uploader(btn):
# call uploadFile(), with the contents of the "file" entry box
# when uploadFile() completes, its return value will be passed to uploadComplete()
filename = app.getEntry("file")
if filename != "":
app.setLabel("uploadStatus", "Starting upload")
app.threadCallback(uploadFile, uploadComplete, filename)

def uploadComplete(success):
if success:
message = "Upload complete"
else:
message = "Upload failed"

app.queueFunction(app.setLabel, "uploadStatus", message)

app=gui()
app.addLabel("uploadStatus", "No uploads")
app.addFileEntry("file")
app.addButton("UPLOAD", uploader)
app.go()

0 comments on commit c092490

Please sign in to comment.