difonlib 0.4.2__tar.gz → 0.4.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {difonlib-0.4.2 → difonlib-0.4.4}/PKG-INFO +1 -1
- {difonlib-0.4.2 → difonlib-0.4.4}/pyproject.toml +1 -1
- {difonlib-0.4.2 → difonlib-0.4.4}/src/difonlib/ng_lib.py +137 -5
- difonlib-0.4.4/src/difonlib/ng_lib_test3.py +148 -0
- {difonlib-0.4.2 → difonlib-0.4.4}/src/difonlib/tuya_devs.py +7 -1
- {difonlib-0.4.2 → difonlib-0.4.4}/src/difonlib.egg-info/PKG-INFO +1 -1
- difonlib-0.4.2/src/difonlib/ng_lib_test3.py +0 -77
- {difonlib-0.4.2 → difonlib-0.4.4}/README.md +0 -0
- {difonlib-0.4.2 → difonlib-0.4.4}/setup.cfg +0 -0
- {difonlib-0.4.2 → difonlib-0.4.4}/src/difonlib/__init__.py +0 -0
- {difonlib-0.4.2 → difonlib-0.4.4}/src/difonlib/bt_scanner.py +0 -0
- {difonlib-0.4.2 → difonlib-0.4.4}/src/difonlib/bt_utils.py +0 -0
- {difonlib-0.4.2 → difonlib-0.4.4}/src/difonlib/conn_kbd_devs.py +0 -0
- {difonlib-0.4.2 → difonlib-0.4.4}/src/difonlib/docker-android/get_tuya_preferences.py +0 -0
- {difonlib-0.4.2 → difonlib-0.4.4}/src/difonlib/input_devs.py +0 -0
- {difonlib-0.4.2 → difonlib-0.4.4}/src/difonlib/py.typed +0 -0
- {difonlib-0.4.2 → difonlib-0.4.4}/src/difonlib/remctrl.py +0 -0
- {difonlib-0.4.2 → difonlib-0.4.4}/src/difonlib/utils.py +0 -0
- {difonlib-0.4.2 → difonlib-0.4.4}/src/difonlib.egg-info/SOURCES.txt +0 -0
- {difonlib-0.4.2 → difonlib-0.4.4}/src/difonlib.egg-info/dependency_links.txt +0 -0
- {difonlib-0.4.2 → difonlib-0.4.4}/src/difonlib.egg-info/requires.txt +0 -0
- {difonlib-0.4.2 → difonlib-0.4.4}/src/difonlib.egg-info/top_level.txt +0 -0
- {difonlib-0.4.2 → difonlib-0.4.4}/tests/test_bt_utils.py +0 -0
- {difonlib-0.4.2 → difonlib-0.4.4}/tests/test_utils.py +0 -0
|
@@ -2,7 +2,7 @@ from nicegui import ui
|
|
|
2
2
|
import inspect
|
|
3
3
|
import asyncio
|
|
4
4
|
from typing import Any, Callable, Awaitable, Literal
|
|
5
|
-
|
|
5
|
+
import threading
|
|
6
6
|
from difonlib.utils import logdbg
|
|
7
7
|
|
|
8
8
|
dbg = logdbg
|
|
@@ -28,6 +28,103 @@ ui.add_css(
|
|
|
28
28
|
|
|
29
29
|
|
|
30
30
|
class DialogBox:
|
|
31
|
+
|
|
32
|
+
async def dialog_processing(
|
|
33
|
+
self,
|
|
34
|
+
proc: Callable,
|
|
35
|
+
proc_cancel_event: bool = False,
|
|
36
|
+
label_txt: str = "Processing...",
|
|
37
|
+
label_txt_color: str = "green",
|
|
38
|
+
timeout: int | None = None,
|
|
39
|
+
) -> tuple[Literal["Canceled", "Timeout"] | None, Any | None]:
|
|
40
|
+
"""
|
|
41
|
+
See examples in ng_lib_test3.py
|
|
42
|
+
def proc_dummy2(cancel_event: threading.Event) -> None:
|
|
43
|
+
for i in range(10, 0, -1):
|
|
44
|
+
if cancel_event.is_set():
|
|
45
|
+
print(f"Exit")
|
|
46
|
+
return
|
|
47
|
+
print(f"Remaining: {i}")
|
|
48
|
+
time.sleep(1)
|
|
49
|
+
async def aproc_dummy(cnt: int = 20):
|
|
50
|
+
for i in range(cnt, 0, -1):
|
|
51
|
+
print(f"aRemaining: {i}")
|
|
52
|
+
await asyncio.sleep(1)
|
|
53
|
+
return 125
|
|
54
|
+
|
|
55
|
+
async def proc_dialog():
|
|
56
|
+
err, result = await dialog_box.dialog_processing(
|
|
57
|
+
functools.partial(aproc_dummy, cnt=4), timeout=5
|
|
58
|
+
)
|
|
59
|
+
dbg(f"ERROR: {err}; Result: {result}") # //Dima
|
|
60
|
+
ui.button(
|
|
61
|
+
"Test processing dialog",
|
|
62
|
+
on_click=proc_dialog,
|
|
63
|
+
)
|
|
64
|
+
"""
|
|
65
|
+
task_proc: asyncio.Task | None = None
|
|
66
|
+
cancel_event = None
|
|
67
|
+
if proc_cancel_event:
|
|
68
|
+
cancel_event = threading.Event()
|
|
69
|
+
|
|
70
|
+
async def countdown(timeout: int, label: ui.label) -> None:
|
|
71
|
+
for counter in range(timeout, 0, -1):
|
|
72
|
+
label.text = f"{label_txt}{counter}"
|
|
73
|
+
await asyncio.sleep(1)
|
|
74
|
+
|
|
75
|
+
canceled = False
|
|
76
|
+
ret_value: Any | None = None
|
|
77
|
+
err: Literal["Canceled", "Timeout"] | None = None
|
|
78
|
+
|
|
79
|
+
async def on_cancel() -> None:
|
|
80
|
+
nonlocal canceled
|
|
81
|
+
canceled = True
|
|
82
|
+
if cancel_event:
|
|
83
|
+
cancel_event.set()
|
|
84
|
+
if task_proc:
|
|
85
|
+
task_proc.cancel()
|
|
86
|
+
dialog.close()
|
|
87
|
+
|
|
88
|
+
text_color = f"text-{label_txt_color}-500"
|
|
89
|
+
with (
|
|
90
|
+
ui.dialog().props("persistent") as dialog,
|
|
91
|
+
ui.card().classes("p-4 items-center justify-center"),
|
|
92
|
+
):
|
|
93
|
+
with ui.row().classes("items-center gap-3"):
|
|
94
|
+
ui.spinner(size="md")
|
|
95
|
+
label = ui.label(f"{label_txt}").classes(f"{text_color} text-2xl")
|
|
96
|
+
ui.button("Cancel", on_click=on_cancel)
|
|
97
|
+
dialog.open()
|
|
98
|
+
task_count: asyncio.Task | None = None
|
|
99
|
+
if timeout:
|
|
100
|
+
task_count = asyncio.create_task(countdown(timeout=timeout, label=label))
|
|
101
|
+
|
|
102
|
+
if proc_cancel_event:
|
|
103
|
+
if inspect.iscoroutinefunction(getattr(proc, "func", proc)):
|
|
104
|
+
task_proc = asyncio.create_task(proc(cancel_event))
|
|
105
|
+
else:
|
|
106
|
+
task_proc = asyncio.create_task(asyncio.to_thread(proc, cancel_event))
|
|
107
|
+
else:
|
|
108
|
+
if inspect.iscoroutinefunction(getattr(proc, "func", proc)):
|
|
109
|
+
task_proc = asyncio.create_task(proc())
|
|
110
|
+
else:
|
|
111
|
+
task_proc = asyncio.create_task(asyncio.to_thread(proc))
|
|
112
|
+
|
|
113
|
+
try:
|
|
114
|
+
ret_value = await asyncio.wait_for(task_proc, timeout=timeout)
|
|
115
|
+
except (asyncio.TimeoutError, asyncio.CancelledError):
|
|
116
|
+
if cancel_event:
|
|
117
|
+
cancel_event.set()
|
|
118
|
+
err = "Canceled" if canceled else "Timeout"
|
|
119
|
+
ui.notify(err)
|
|
120
|
+
|
|
121
|
+
finally:
|
|
122
|
+
if task_count and not task_count.cancelled():
|
|
123
|
+
task_count.cancel()
|
|
124
|
+
dialog.close()
|
|
125
|
+
|
|
126
|
+
return (err, ret_value)
|
|
127
|
+
|
|
31
128
|
async def dialog_ok(self, text: str = "Hello!)") -> None:
|
|
32
129
|
with ui.dialog().props("persistent") as dialog, ui.card():
|
|
33
130
|
ui.label(text=text)
|
|
@@ -80,7 +177,7 @@ class DialogBox:
|
|
|
80
177
|
|
|
81
178
|
|
|
82
179
|
class CardTable:
|
|
83
|
-
_current_yes_handler: Callable[[], None | Awaitable[None]] | None = None
|
|
180
|
+
# _current_yes_handler: Callable[[], None | Awaitable[None]] | None = None
|
|
84
181
|
|
|
85
182
|
def __init__(
|
|
86
183
|
self,
|
|
@@ -96,6 +193,8 @@ class CardTable:
|
|
|
96
193
|
self.buttons_on_row_select_changed: list = []
|
|
97
194
|
self.marked_text_color = marked_text_color
|
|
98
195
|
self.marked_field = marked_field
|
|
196
|
+
self.filter_value: str | bool = ""
|
|
197
|
+
self._current_yes_handler: Callable[[], None | Awaitable[None]] | None = None
|
|
99
198
|
|
|
100
199
|
with ui.card().classes("p-4 shadow-lg") as self.card:
|
|
101
200
|
with ui.row().classes("items-center justify-between w-full mb-2"):
|
|
@@ -153,10 +252,42 @@ class CardTable:
|
|
|
153
252
|
"""Add field 'name', needed for Quasar GUI"""
|
|
154
253
|
return [{**col, "name": col.get("name", col["field"])} for col in columns]
|
|
155
254
|
|
|
255
|
+
def set_row_display_filter(self, **field: str | bool) -> None:
|
|
256
|
+
"""
|
|
257
|
+
card_table.set_row_display_filter(id="123456")
|
|
258
|
+
card_table.set_row_display_filter(_marked=True)
|
|
259
|
+
"""
|
|
260
|
+
assert len(field) == 1, "❌ Exactly one field expected"
|
|
261
|
+
field_name, field_value = next(iter(field.items()))
|
|
262
|
+
if isinstance(field_value, bool):
|
|
263
|
+
self.filter_value = str(field_value).lower() # "true" / "false" для JS
|
|
264
|
+
else:
|
|
265
|
+
self.filter_value = f"\\'{field_value}\\'"
|
|
266
|
+
self.table.props(rf"""
|
|
267
|
+
:filter-method="(rows, terms) => !terms ? rows : rows.filter(r => r.{field_name} === terms)"
|
|
268
|
+
""")
|
|
269
|
+
|
|
270
|
+
def row_display_filter(self, state_on: bool = False) -> None:
|
|
271
|
+
"""
|
|
272
|
+
Show rows with field id='123456' :
|
|
273
|
+
card_table.set_row_display_filter(id="123456")
|
|
274
|
+
card_table.row_display_filter(state_on=True)
|
|
275
|
+
Show rows with field _marked=True :
|
|
276
|
+
card_table.set_row_display_filter(_marked=True)
|
|
277
|
+
card_table.row_display_filter(True)
|
|
278
|
+
Show all rows:
|
|
279
|
+
card_table.row_display_filter()
|
|
280
|
+
"""
|
|
281
|
+
if state_on:
|
|
282
|
+
self.table.props(f':filter="{self.filter_value}"')
|
|
283
|
+
else:
|
|
284
|
+
self.table.props(':filter=""')
|
|
285
|
+
self.table.update()
|
|
286
|
+
|
|
156
287
|
def mark_row(self, mark: bool = True, **kwrds: Any) -> list[dict[str, Any]]:
|
|
157
288
|
"""
|
|
158
|
-
card_table.mark_row(id="123456", name="
|
|
159
|
-
card_table.mark_row(ip="192.168.0.18", mark=False)
|
|
289
|
+
card_table.mark_row(id="123456", name="IRDevice.Lounge1")
|
|
290
|
+
card_table.mark_row(ip="192.168.0.18", mark=False) #Unmark
|
|
160
291
|
"""
|
|
161
292
|
found = []
|
|
162
293
|
for row in self.table.rows:
|
|
@@ -224,7 +355,8 @@ class CardTable:
|
|
|
224
355
|
else:
|
|
225
356
|
on_change(e.sender.value)
|
|
226
357
|
|
|
227
|
-
chbox.on("click", handle_change)
|
|
358
|
+
# chbox.on("click", handle_change)
|
|
359
|
+
chbox.on("update:model-value", handle_change)
|
|
228
360
|
setattr(self, f"chbox{chbox_txt.replace(' ', '_')}", chbox)
|
|
229
361
|
return chbox
|
|
230
362
|
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
from nicegui import ui
|
|
3
|
+
from ng_lib import CardTable, DialogBox
|
|
4
|
+
import functools
|
|
5
|
+
import threading
|
|
6
|
+
import time
|
|
7
|
+
|
|
8
|
+
from difonlib.bt_utils import logdbg
|
|
9
|
+
|
|
10
|
+
dbg = logdbg
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def proc_dummy2(cancel_event: threading.Event) -> None:
|
|
14
|
+
for i in range(10, 0, -1):
|
|
15
|
+
if cancel_event.is_set():
|
|
16
|
+
print("Exit")
|
|
17
|
+
return
|
|
18
|
+
print(f"Remaining: {i}")
|
|
19
|
+
time.sleep(1)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def proc_dummy(cnt: int = 20) -> None:
|
|
23
|
+
for i in range(cnt, 0, -1):
|
|
24
|
+
print(f"Remaining: {i}")
|
|
25
|
+
time.sleep(1)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
async def aproc_dummy(cnt: int = 20) -> int:
|
|
29
|
+
for i in range(cnt, 0, -1):
|
|
30
|
+
print(f"aRemaining: {i}")
|
|
31
|
+
await asyncio.sleep(1)
|
|
32
|
+
return 125
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@ui.page("/", dark=True)
|
|
36
|
+
def main() -> None:
|
|
37
|
+
|
|
38
|
+
card_table = CardTable(
|
|
39
|
+
title="Connected Devices",
|
|
40
|
+
columns=[
|
|
41
|
+
{"name": "id", "label": "id", "field": "id"},
|
|
42
|
+
{"name": "name", "label": "Name", "field": "name"},
|
|
43
|
+
{"name": "ip", "label": "IP Address", "field": "ip"},
|
|
44
|
+
],
|
|
45
|
+
selection="single",
|
|
46
|
+
rows=[
|
|
47
|
+
{"id": "123456", "name": "ANNNNN", "ip": "192.168.0.18"},
|
|
48
|
+
{"id": "987654", "name": "VNNNNN", "ip": "192.168.0.118"},
|
|
49
|
+
{"id": "123456", "name": "BNNNNN", "ip": "192.168.0.12"},
|
|
50
|
+
{"id": "003456", "name": "SNNNNN", "ip": "192.168.0.144"},
|
|
51
|
+
{"id": "129956", "name": "QNNNNN", "ip": "192.168.0.49"},
|
|
52
|
+
],
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
found = card_table.mark_row(id="123456", mark=True)
|
|
56
|
+
print(f"card_table.table.rows:{card_table.table.rows}") # //Dima
|
|
57
|
+
found = card_table.mark_row(id="123456", name="ANNNNN", mark=False)
|
|
58
|
+
found = card_table.mark_row(id="129956")
|
|
59
|
+
print(f" ==> found: {found}") # //Dima
|
|
60
|
+
|
|
61
|
+
card_table.set_row_display_filter(_marked=True)
|
|
62
|
+
# card_table.set_row_display_filter(id="123456")
|
|
63
|
+
|
|
64
|
+
# self.table.props(':filter="\'online\'"')
|
|
65
|
+
# self.table.update()
|
|
66
|
+
|
|
67
|
+
# def only_marked(mark: bool = False, def_value="\\'\\'") -> None:
|
|
68
|
+
# print(f"table rows: {card_table.table.rows}")
|
|
69
|
+
# field_value = def_value
|
|
70
|
+
# vv = "123456"
|
|
71
|
+
# vv = mark
|
|
72
|
+
# # vv = "true"
|
|
73
|
+
# if mark:
|
|
74
|
+
# dbg(f" === MARK ===") # //Dima
|
|
75
|
+
# if isinstance(vv, str):
|
|
76
|
+
# field_value = f"\\'{vv}\\'"
|
|
77
|
+
# else:
|
|
78
|
+
# field_value = mark
|
|
79
|
+
# else:
|
|
80
|
+
# dbg(f" === NOT MARK ===") # //Dima
|
|
81
|
+
# dbg(f" * field_value: {field_value}") # //Dima
|
|
82
|
+
# card_table.table.props(f':filter="{field_value}"')
|
|
83
|
+
# card_table.table.update()
|
|
84
|
+
|
|
85
|
+
# card_table.add_checkbox(chbox_txt="Used Only", on_change=lambda v: ui.notify(v))
|
|
86
|
+
# card_table.add_checkbox(chbox_txt="Used Only", on_change=lambda v: only_marked(v))
|
|
87
|
+
card_table.add_checkbox(
|
|
88
|
+
chbox_txt="Used Only",
|
|
89
|
+
on_change=lambda v: card_table.row_display_filter(v),
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
dialog_box = DialogBox()
|
|
93
|
+
|
|
94
|
+
def btnok() -> None:
|
|
95
|
+
ui.notify("You press OK")
|
|
96
|
+
|
|
97
|
+
def btncancel() -> None:
|
|
98
|
+
ui.notify("You press Cancel")
|
|
99
|
+
|
|
100
|
+
card_table.add_button(
|
|
101
|
+
"test_ok_cancel",
|
|
102
|
+
on_click=functools.partial(
|
|
103
|
+
dialog_box.dialog_ok_cancel,
|
|
104
|
+
text="OK or Cancel?",
|
|
105
|
+
on_click_ok=btnok,
|
|
106
|
+
on_click_cancel=btncancel,
|
|
107
|
+
),
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
async def confirm() -> None:
|
|
111
|
+
result = await dialog_box.dialog_confirm()
|
|
112
|
+
ui.notify(f"You chose {result}")
|
|
113
|
+
|
|
114
|
+
card_table.add_button(
|
|
115
|
+
"test_confirm",
|
|
116
|
+
on_click=confirm,
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
async def dialog_input() -> None:
|
|
120
|
+
inp = await dialog_box.dialog_input("Input IR_KEY_NAME", input_prefix="IR_KEY_")
|
|
121
|
+
ui.notify(f"Your input: {inp}")
|
|
122
|
+
|
|
123
|
+
card_table.add_button(
|
|
124
|
+
"test_input",
|
|
125
|
+
on_click=dialog_input,
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
async def proc_dialog() -> None:
|
|
129
|
+
err, result = await dialog_box.dialog_processing(
|
|
130
|
+
functools.partial(aproc_dummy, cnt=4), timeout=5
|
|
131
|
+
)
|
|
132
|
+
dbg(f"ERROR: {err}; Result: {result}") # //Dima
|
|
133
|
+
ui.notify(f"ERROR: {err}; Result: {result}")
|
|
134
|
+
|
|
135
|
+
ui.button(
|
|
136
|
+
"Test processing dialog",
|
|
137
|
+
on_click=proc_dialog,
|
|
138
|
+
# on_click=lambda: dialog_box.dialog_processing(proc_dummy, timeout=4),
|
|
139
|
+
# on_click=lambda: dialog_box.dialog_processing(
|
|
140
|
+
# functools.partial(aproc_dummy, cnt=5), timeout=6
|
|
141
|
+
# ),
|
|
142
|
+
# on_click=lambda: dialog_box.dialog_processing(
|
|
143
|
+
# proc_dummy2, proc_cancel_event=True, timeout=4
|
|
144
|
+
# ),
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
ui.run(port=1111)
|
|
@@ -126,6 +126,11 @@ class TuyaDevs:
|
|
|
126
126
|
# return con_devs
|
|
127
127
|
|
|
128
128
|
def dev_is_connected(self, dev_id: str, timeout: int = 8, rescan: bool = False) -> bool:
|
|
129
|
+
"""
|
|
130
|
+
if rescan:
|
|
131
|
+
self.scan(timeout=timeout)
|
|
132
|
+
Check if dev_id in last scan list (self.devs_online)
|
|
133
|
+
"""
|
|
129
134
|
if rescan:
|
|
130
135
|
# update self.devs_online
|
|
131
136
|
self.scan(timeout=timeout)
|
|
@@ -178,9 +183,10 @@ class TuyaDevs:
|
|
|
178
183
|
return dev
|
|
179
184
|
|
|
180
185
|
def outlet_dev(self, dev_id: str, local_key: str) -> Optional[OutletDevice]:
|
|
181
|
-
"""TurnOn/Off:
|
|
186
|
+
"""TurnOn/Off & toggle:
|
|
182
187
|
odev.turn_on()
|
|
183
188
|
odev.turn_off()
|
|
189
|
+
odev.toggle()
|
|
184
190
|
"""
|
|
185
191
|
try:
|
|
186
192
|
dev = OutletDeviceM(
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
from nicegui import ui
|
|
2
|
-
from ng_lib import CardTable, DialogBox
|
|
3
|
-
import functools
|
|
4
|
-
|
|
5
|
-
from difonlib.bt_utils import logdbg
|
|
6
|
-
|
|
7
|
-
dbg = logdbg
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
@ui.page("/", dark=True)
|
|
11
|
-
def main() -> None:
|
|
12
|
-
|
|
13
|
-
card_table = CardTable(
|
|
14
|
-
title="Connected Devices",
|
|
15
|
-
columns=[
|
|
16
|
-
{"name": "id", "label": "id", "field": "id"},
|
|
17
|
-
{"name": "name", "label": "Name", "field": "name"},
|
|
18
|
-
{"name": "ip", "label": "IP Address", "field": "ip"},
|
|
19
|
-
],
|
|
20
|
-
selection="single",
|
|
21
|
-
rows=[
|
|
22
|
-
{"id": "123456", "name": "ANNNNN", "ip": "192.168.0.18"},
|
|
23
|
-
{"id": "987654", "name": "VNNNNN", "ip": "192.168.0.118"},
|
|
24
|
-
{"id": "123456", "name": "BNNNNN", "ip": "192.168.0.12"},
|
|
25
|
-
{"id": "003456", "name": "SNNNNN", "ip": "192.168.0.144"},
|
|
26
|
-
{"id": "129956", "name": "QNNNNN", "ip": "192.168.0.49"},
|
|
27
|
-
],
|
|
28
|
-
)
|
|
29
|
-
|
|
30
|
-
found = card_table.mark_row(id="123456", mark=True)
|
|
31
|
-
print(f"card_table.table.rows:{card_table.table.rows}") # //Dima
|
|
32
|
-
found = card_table.mark_row(id="123456", name="ANNNNN", mark=False)
|
|
33
|
-
found = card_table.mark_row(id="129956")
|
|
34
|
-
print(f" ==> found: {found}") # //Dima
|
|
35
|
-
|
|
36
|
-
print(f"card_table.table.rows: {card_table.table.rows}")
|
|
37
|
-
|
|
38
|
-
card_table.add_checkbox(chbox_txt="Used Only", on_change=lambda v: ui.notify(v))
|
|
39
|
-
|
|
40
|
-
dialog_box = DialogBox()
|
|
41
|
-
|
|
42
|
-
def btnok() -> None:
|
|
43
|
-
ui.notify("You press OK")
|
|
44
|
-
|
|
45
|
-
def btncancel() -> None:
|
|
46
|
-
ui.notify("You press Cancel")
|
|
47
|
-
|
|
48
|
-
card_table.add_button(
|
|
49
|
-
"test_ok_cancel",
|
|
50
|
-
on_click=functools.partial(
|
|
51
|
-
dialog_box.dialog_ok_cancel,
|
|
52
|
-
text="OK or Cancel?",
|
|
53
|
-
on_click_ok=btnok,
|
|
54
|
-
on_click_cancel=btncancel,
|
|
55
|
-
),
|
|
56
|
-
)
|
|
57
|
-
|
|
58
|
-
async def confirm() -> None:
|
|
59
|
-
result = await dialog_box.dialog_confirm()
|
|
60
|
-
ui.notify(f"You chose {result}")
|
|
61
|
-
|
|
62
|
-
card_table.add_button(
|
|
63
|
-
"test_confirm",
|
|
64
|
-
on_click=confirm,
|
|
65
|
-
)
|
|
66
|
-
|
|
67
|
-
async def dialog_input() -> None:
|
|
68
|
-
inp = await dialog_box.dialog_input("Input IR_KEY_NAME", input_prefix="IR_KEY_")
|
|
69
|
-
ui.notify(f"Your input: {inp}")
|
|
70
|
-
|
|
71
|
-
card_table.add_button(
|
|
72
|
-
"test_input",
|
|
73
|
-
on_click=dialog_input,
|
|
74
|
-
)
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
ui.run(port=1111)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|