File: blocking.md

package info (click to toggle)
python-guizero 1.1.1%2Bdfsg1-3
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 2,676 kB
  • sloc: python: 6,286; makefile: 28; sh: 17
file content (59 lines) | stat: -rw-r--r-- 2,392 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
## Loops and sleeping

You may be used to writing programs which contain loops or make use of the `sleep()` command, but find when you try to use these with guizero they cause your GUI to freeze. This is because guizero (in common with almost all GUIs) operates an **event driven** model of programming which may be different to the one you are familiar with.

Your first guizero program might look a bit like this:

```python
from guizero import App
app = App("Hello world")
app.display()
```

The line of code `app.display()` doesn't just display the app - it enters an **infinite event loop** which is watching and waiting for events to happen on the GUI. Events include things like the user clicking on a button, moving a slider, typing in a text box etc. No code written after this line will ever execute because the event loop is infinite.

### Example

Suppose you want a counter on your GUI to start counting up by 1 every second. You might be tempted to write a program like this:

```python
from guizero import App, Text
from time import sleep

app = App("Hello world")
text = Text(app, text="1")
while True:
    text.value = int(text.value) + 1
    sleep(1)
app.display()
```

If you run this program, you'll see that this does not have the desired effect - your program crashes! This is because you have blocked the updating of your GUI in two ways:

1. The `sleep()` command - whilst your program is sleeping, the GUI will not update and you will not be able to click on anything.

2. The `while` loop - once you enter this loop, your GUI will never update ever again and will probably crash.


### Solution

**This behaviour is not a bug within guizero or tkinter.**

You must write GUI based programs in a different way to the one you may be used to. If you want to repeatedly perform an action you would do it like this:

1. Write a function which performs the desired action (in this example `counter()`)

2. Set a **callback** to that function. You can either schedule the same callback to occur repeatedly after a given number of milliseconds (in this example `1000`), or you can schedule it only once.

```python
from guizero import App, Text

# Action you would like to perform
def counter():
    text.value = int(text.value) + 1

app = App("Hello world")
text = Text(app, text="1")
text.repeat(1000, counter)  # Schedule call to counter() every 1000ms
app.display()
```