WindowView API
What is the WindowView API
The WindowView API is a framework for developing custom simulator subwindows using PySide6.
The simulator windows run in a separate process as the robot code, requiring the use of I/O queues for handling live data between the robot code and the simulator.
Info
The WindowView API requires the usage of PySide6 .
PySide6 versions not installed as a dependency of KevinbotLib, or other Python Qt bindings are not officially supported, and may not function properly.
Creating and Registering a WindowView
examples/simulator/windowview_register.py 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 from PySide6.QtWidgets import QLabel , QWidget
from kevinbotlib.robot import BaseRobot
from kevinbotlib.simulator.windowview import WindowView , register_window_view
@register_window_view ( "test.mywindowview" )
class MyWindowView ( WindowView ):
def __init__ ( self ):
super () . __init__ ()
@property
def title ( self ):
return "My Awesome WindowView"
def generate ( self ) -> QWidget :
return QLabel ( "Hello World!" )
class DemoRobot ( BaseRobot ):
def __init__ ( self ):
super () . __init__ (
[ "Test" ],
enable_stderr_logger = True ,
)
if BaseRobot . IS_SIM :
self . simulator . add_window ( "test.mywindowview" , MyWindowView )
self . telemetry . info ( f "Registered WindowViews: { self . simulator . windows } " )
if __name__ == "__main__" :
DemoRobot () . run ()
Tip
Each WindowView must have a different registered Window ID (in this case, test.mywindowview
).
It is recommended to use reverse domain name notation (e.g., com.example.myproduct.mywindowview
).
Do not use Window IDs starting with kevinbotlib
or com.meowmeowahr.kevinbotlib
Working with Payloads
examples/simulator/windowview_payload.py 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
60
61
62
63
64
65
66
67 from typing import Any
from PySide6.QtWidgets import QLabel , QPushButton , QVBoxLayout , QWidget
from kevinbotlib.robot import BaseRobot
from kevinbotlib.simulator.windowview import WindowView , WindowViewOutputPayload , register_window_view
class ResetPayload ( WindowViewOutputPayload ):
def payload ( self ) -> Any :
return "reset"
@register_window_view ( "test.mywindowview" )
class MyWindowView ( WindowView ):
def __init__ ( self ):
super () . __init__ ()
self . widget = QWidget ()
self . layout = QVBoxLayout ()
self . widget . setLayout ( self . layout )
self . label = QLabel ( "Robot Cycles: ?" )
self . layout . addWidget ( self . label )
self . button = QPushButton ( "Reset" )
self . button . clicked . connect ( lambda : self . send_payload ( ResetPayload ()))
self . layout . addWidget ( self . button )
@property
def title ( self ):
return "My Awesome WindowView"
def generate ( self ) -> QWidget :
return self . widget
def update ( self , payload : Any ) -> None :
self . label . setText ( f "Robot Cycles: { payload } " )
class DemoRobot ( BaseRobot ):
def __init__ ( self ):
super () . __init__ (
[ "Test" ],
enable_stderr_logger = True ,
)
self . cycles = 0
if BaseRobot . IS_SIM :
self . simulator . add_window ( "test.mywindowview" , MyWindowView )
def reset_cycles ( payload : WindowViewOutputPayload ):
if payload . payload () == "reset" :
self . cycles = 0
self . simulator . add_payload_callback ( ResetPayload , reset_cycles )
def robot_periodic ( self , opmode : str , enabled : bool ):
super () . robot_periodic ( opmode , enabled )
self . cycles += 1
self . simulator . send_to_window ( "test.mywindowview" , self . cycles )
if __name__ == "__main__" :
DemoRobot () . run ()