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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
import justpy as jp
import asyncio
import matplotlib.pyplot as plt
button_classes = 'bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-full'
label_div_classes = 'py-2 px-4'
checkbox_classed = label_div_classes
labelnames_classes = 'font-bold'
panel_div_classes = 'space-x-4 border'
controls_div_classes = 'flex space-x-4 border'
controls_group_classes = 'flex space-x-4'
input_classes = "m-2 bg-gray-200 border-2 border-gray-200 rounded w-20 text-gray-700 focus:outline-none focus:bg-white focus:border-purple-500"
class QOLPushButton(jp.Button):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.set_classes('bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-full')
class QOLPushButtonNoUndo(QOLPushButton):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.set_classes('bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded-full')
class QOLParamHeader(jp.Div):
def __init__(self, label='NameNotSet', **kwargs):
super().__init__(**kwargs)
root = self
root.label=label
root.set_classes(label_div_classes)
root.data[label]=None
jp.Span(text=f'{label}: ', classes=labelnames_classes, a=root)
def getValue(self):
return self.data[self.label]
def setValue(self, val):
self.data[self.label]=val
class QOLParamReadOnly(QOLParamHeader):
""" Read Only from the web point of view """
def __init__(self, label='NameNotSet', **kwargs):
super().__init__(label=label, **kwargs)
root = self
jp.Span(model=[root, label], a=root)
class QOLParamReadWrite(QOLParamHeader):
def __init__(self, label='NameNotSet', **kwargs):
super().__init__(label=label, **kwargs)
root = self
self.input=jp.Input(classes=input_classes, model=[root, label], a=root, spellcheck="false")
class QOLCheckbox(jp.Label):
def __init__(self, label='NameNotSet', **kwargs):
super().__init__(**kwargs)
root = self
root.data['checked'] = False
root.label=label
root.set_classes(checkbox_classed)
checkbox = jp.Input(type='checkbox', model=[root, 'checked'], classes='form-checkbox', a=root)
caption = jp.Span(text=label, a=root)
def getValue(self):
return self.data['checked']
def setValue(self, val):
self.data['checked'] = val
class QOLTimeLog(jp.Div):
def __init__(self, **kwargs):
super().__init__(**kwargs)
root = self
root.traces = None; # log must have 'plot' and 'clear_data' methods
root.set_classes(panel_div_classes)
dcontrols = jp.Div(a=root)
dcontrols.set_classes(controls_div_classes)
bclear = QOLPushButtonNoUndo(a=dcontrols, text='Clear log', click=self._clear_data)
breplot = QOLPushButton(a=dcontrols, text='Replot', click=self._replot)
save_controls = QOLSaveControls(a=dcontrols)
self.chart = jp.Matplotlib(a=root)
self.plot()
def _clear_data(self, msg):
self.clear_data()
def clear_data(self):
traces = self.traces
if traces is not None:
traces.clear_data()
self.plot()
async def _replot(self, msg):
self.plot()
await self.update()
async def update_loop(self, update_interval=4):
update_interval=5
while True:
self.plot()
await self.update()
await asyncio.sleep(update_interval)
def plot(self):
traces = self.traces
f = plt.figure()
if traces is None:
plt.title('Log data is unavailable')
else:
traces.plot()
self.chart.set_figure(f)
plt.close(f)
class QOLSaveControls(jp.Div):
def __init__(self, **kwargs):
super().__init__(**kwargs)
root = self
root.set_classes(controls_group_classes)
root.save=QOLPushButton(a=root, text='Save', name='Save', click=self._save)
root.next_file=QOLPushButton(a=root, text='Next file', name='NextFile', click=self._next_file)
self.autosave=QOLCheckbox(label='autosave', a=root )
self.file_name=QOLParamReadOnly(label='FileName', a=root)
def _save(self, msg):
""" This is place holder: user should assign 'save' with a callback """
print('Warning: `save` callback is not set')
pass
def _next_file(self, msg):
""" This is place holder: user should assign 'next_file' with a callback """
print('Warning: `next_file` callback is not set')
pass
def gui_test():
return wp
if __name__ == '__main__':
wp = jp.WebPage(delete_flag=False)
rw = QOLParamReadWrite(label='ReadWriteParam', a=wp)
rw.setValue(12345)
log = QOLTimeLog(a=wp)
def test(self, msg):
print(rw.getValue())
QOLPushButtonNoUndo(text='Danger', a=wp, onclick=test)
# sc = QOLSaveControls(a=wp)
jp.justpy(gui_test)
|