For event processing, VPython also provides controls such as command buttons (button), radio buttons (radio), multiple selection options (checkbox and menu), and sliders (slider).
For each event, a function must be defined to perform the relevant action. Events are always implemented according to the following schema:
control(bind=function, ...)
The control identifier can be the name of a control, such as a button, slider, checkbox, or radio button. To enable the controlelement method to trigger an event, a custom function must be passed to it as a parameter. This function is assigned to the bind property. The parentheses of the custom function must be omitted. All other parameters depend on the type of control. The code below shows how to use the slider() method to change the rotational frequency of a voltage pointer. The checkbox() method enables the activation of a power pointer that rotates with double frequency. The button() method can be used to pause and restart the animation.
01 #20_event-processing.py
02 from vpython import *
03 scene.title="<h2>Rotating voltage and power pointer</h2>"
04 scene.width=scene.height=600
05 scene.background=color.white
06
07 runs = True
08 col=color.yellow
09
10 def start(b):
11 global runs
12 runs = not runs
13 if runs: b.text = "Pause"
14 else: b.text = "Start"
15
16 def omega(s):
17 txtA.text = "{:1.2f}".format(s.value)
18
19 def visibleP(b):
20 if b.checked:
21 p.visible = True
22 else:
23 p.visible = False
24
25 u_s=2.
26 p_s=1.5
27 d=0.025
28 scene.range = 1.2*u_s
29 u=arrow(pos=vec(0,0,0),axis=vec(0,u_s,0),color=color.blue)
30 p=arrow(pos=vec(0,0,0),axis=vec(p_s,0,0),color=col)
31 p.visible=False
32 u.shaftwidth=d
33 p.shaftwidth=d
34 button(text="Pause",pos=scene.title_anchor,bind=start)
35 scene.append_to_caption("\n\n")
36 scene.caption="\n Change frequency:\n\n"
37 sldF=slider(min=0,max=6.28,value=1,length=300,bind=omega,right=4)
38 txtA=wtext(text="{:1.2f}".format(sldF.value))
39 scene.append_to_caption(" rad/s\n\n")
40 checkbox(bind=visibleP, text="Show power pointer\n\n")
41 dt=0.01
42 w=1.
43 while True:
44 rate(1/dt)
45 if runs:
46 w=sldF.value
47 u.rotate(angle=w*dt,axis=vec(0,0,1))
48 p.rotate(angle=2.0*w*dt,axis=vec(0,0,1))
Output: A snapshot of the resulting rotating pointers animation is shown below.
Analysis: If the value of the global runs variable (lines 07 and 11) is True, the animation is executed within the while loop (lines 43 to 48). If you want to pause the animation, you must click the Pause button. Then, the label of the button changes to Start. In this case, the button() method from line 34 calls the custom start(b) function from lines 10 to 14. The command button is placed above the scene in the upper-left corner. The start(b) function is called via bind=start. The parentheses of the function definition and the function argument b must be omitted.
In line 37, the slider() method calls the custom bind=omega function from lines 16 and 17. The set values are stored in the sldF object and displayed in the txtA text field in line 38. In line 46, the change of the rotation frequency is performed using the w=sldF.value assignment.
The checkbox(bind=visible,...) method in line 40 calls the custom function visible( b) from lines 19 to 23. If you activate the checkbox control, the power pointer will be switched on.
Exercise: Test the Python program with all settings. Comment out line 11. Restart the program and click the Pause button. Analyze the error message.
Editor’s note: This post has been adapted from a section of the book Python for Engineering and Scientific Computing by Veit Steinkamp.