ikkVisualKit 0.0.0__py3-none-any.whl
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.
- ikkVisualKit/CTkUiBase.py +555 -0
- ikkVisualKit/Dialog/CdialogBase.py +96 -0
- ikkVisualKit/Dialog/CdialogOk.py +102 -0
- ikkVisualKit/Dialog/CdialogYesNo.py +91 -0
- ikkVisualKit/Dialog/DialogBase.py +97 -0
- ikkVisualKit/Dialog/DialogOk.py +59 -0
- ikkVisualKit/Dialog/DialogSelectReaderPort.py +110 -0
- ikkVisualKit/Dialog/DialogYesNo.py +62 -0
- ikkVisualKit/Dialog/__init__.py +21 -0
- ikkVisualKit/TkUiBase.py +167 -0
- ikkVisualKit/Tray/ResidentApp.py +264 -0
- ikkVisualKit/Tray/TrayMenu.py +140 -0
- ikkVisualKit/Tray/__init__.py +4 -0
- ikkVisualKit/Window/WindowBase.py +149 -0
- ikkVisualKit/Window/WindowBaseModan.py +233 -0
- ikkVisualKit/Window/__init__.py +3 -0
- ikkVisualKit/__init__.py +22 -0
- ikkVisualKit/image/clear.dio.png +0 -0
- ikkVisualKit/image/goto.dio.png +0 -0
- ikkVisualKit/image/help.dio.png +0 -0
- ikkVisualKit/image/link.dio.png +0 -0
- ikkVisualKit/image/lock.dio.png +0 -0
- ikkVisualKit/image/log.dio.png +0 -0
- ikkVisualKit/image/open.dio.png +0 -0
- ikkVisualKit/image/recipe.dio.png +0 -0
- ikkVisualKit/image/save.dio.png +0 -0
- ikkVisualKit/image/search.dio.png +0 -0
- ikkVisualKit/image/setting.dio.png +0 -0
- ikkVisualKit/image/start.dio.png +0 -0
- ikkVisualKit/image/unlock.dio.png +0 -0
- ikkvisualkit-0.0.0.dist-info/METADATA +176 -0
- ikkvisualkit-0.0.0.dist-info/RECORD +35 -0
- ikkvisualkit-0.0.0.dist-info/WHEEL +5 -0
- ikkvisualkit-0.0.0.dist-info/licenses/LICENSE +21 -0
- ikkvisualkit-0.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# DialogOk.py
|
|
2
|
+
import customtkinter as tk
|
|
3
|
+
from .CdialogBase import CdialogBase, CdialogResult, CdialogIcon
|
|
4
|
+
|
|
5
|
+
class CdialogOk(CdialogBase):
|
|
6
|
+
|
|
7
|
+
def __init__(self, parent, title="OK", message="Message", icon=None,
|
|
8
|
+
size=(700, 400), msg_font_size=18, msg_wraplength=420,
|
|
9
|
+
btn_width=150, btn_height=50, btn_font_size=14, blink=False, blink_speed=500):
|
|
10
|
+
self._message = message
|
|
11
|
+
self._icon = icon
|
|
12
|
+
self._msg_font_size = msg_font_size
|
|
13
|
+
self._msg_wraplength = msg_wraplength
|
|
14
|
+
self._btn_width = btn_width
|
|
15
|
+
self._btn_height = btn_height
|
|
16
|
+
self._btn_font_size = btn_font_size
|
|
17
|
+
self._blink = blink
|
|
18
|
+
self._blink_speed = blink_speed
|
|
19
|
+
self._msg_label = None
|
|
20
|
+
self._blink_state = True
|
|
21
|
+
super().__init__(parent, title=title, size=size)
|
|
22
|
+
|
|
23
|
+
def _build(self, root):
|
|
24
|
+
root.configure(padx=20, pady=20)
|
|
25
|
+
|
|
26
|
+
container = tk.CTkFrame(root)
|
|
27
|
+
container.pack(expand=True)
|
|
28
|
+
|
|
29
|
+
if self._icon:
|
|
30
|
+
icon_label = tk.CTkLabel(container, bitmap=self._icon.value)
|
|
31
|
+
icon_label.pack(side="left", padx=(0, 15))
|
|
32
|
+
#表示するメッセージ
|
|
33
|
+
msg = tk.CTkLabel(
|
|
34
|
+
container,
|
|
35
|
+
text=self._message,
|
|
36
|
+
font=("Meiryo", self._msg_font_size),
|
|
37
|
+
wraplength=self._msg_wraplength,
|
|
38
|
+
justify="left"
|
|
39
|
+
)
|
|
40
|
+
msg.pack(side="left")
|
|
41
|
+
self._msg_label = msg
|
|
42
|
+
|
|
43
|
+
# 点滅機能が有効な場合
|
|
44
|
+
if self._blink:
|
|
45
|
+
self._start_blink()
|
|
46
|
+
#OKボタン
|
|
47
|
+
btn = tk.CTkButton(
|
|
48
|
+
root,
|
|
49
|
+
text="OK",
|
|
50
|
+
width=self._btn_width,
|
|
51
|
+
height=self._btn_height,
|
|
52
|
+
font=("Meiryo", self._btn_font_size),
|
|
53
|
+
command=lambda: self._action_handle(CdialogResult.OK)
|
|
54
|
+
)
|
|
55
|
+
btn.pack(pady=15)
|
|
56
|
+
|
|
57
|
+
btn.focus_set()
|
|
58
|
+
|
|
59
|
+
root.bind("<Return>", lambda e: self._action_handle(CdialogResult.OK))
|
|
60
|
+
root.bind("<Escape>", lambda e: self._action_handle(CdialogResult.OK))
|
|
61
|
+
|
|
62
|
+
# ---------------------------------
|
|
63
|
+
def _start_blink(self):
|
|
64
|
+
"""メッセージラベルを点滅させる"""
|
|
65
|
+
if self._msg_label:
|
|
66
|
+
self._toggle_blink()
|
|
67
|
+
|
|
68
|
+
def _toggle_blink(self):
|
|
69
|
+
"""点滅のトグル"""
|
|
70
|
+
if self._msg_label:
|
|
71
|
+
if self._blink_state:
|
|
72
|
+
self._msg_label.configure(text_color="gray")
|
|
73
|
+
else:
|
|
74
|
+
self._msg_label.configure(text_color="white")
|
|
75
|
+
self._blink_state = not self._blink_state
|
|
76
|
+
self._msg_label.after(self._blink_speed, self._toggle_blink)
|
|
77
|
+
#####################################################################
|
|
78
|
+
#
|
|
79
|
+
#####################################################################
|
|
80
|
+
if __name__ == "__main__":
|
|
81
|
+
#TKのルート
|
|
82
|
+
root = tk.CTk()
|
|
83
|
+
#
|
|
84
|
+
def test_ok():
|
|
85
|
+
dlg = CdialogOk(root,
|
|
86
|
+
message="メッセージ",
|
|
87
|
+
size=(800, 400), # ダイアログのサイズ
|
|
88
|
+
msg_font_size=30, # メッセージのフォントサイズ
|
|
89
|
+
msg_wraplength=620, # メッセージの折り返し幅
|
|
90
|
+
btn_width=300, # ボタンの幅
|
|
91
|
+
btn_height=120, # ボタンの高さ
|
|
92
|
+
btn_font_size=30, # ボタンのフォントサイズ
|
|
93
|
+
blink=True, # 点滅有効
|
|
94
|
+
blink_speed=500) # 点滅速度(ミリ秒)
|
|
95
|
+
# dlg = CdialogOk(root, message="処理が完了しました。", icon=DialogIcon.INFO)
|
|
96
|
+
result = dlg.show()
|
|
97
|
+
print(result)
|
|
98
|
+
|
|
99
|
+
root.geometry("800x400")
|
|
100
|
+
root.title("OK Dialog テスト")
|
|
101
|
+
tk.CTkButton(root, text="ここを押してダイアログを表示", command=test_ok).pack(pady=20)
|
|
102
|
+
root.mainloop()
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# DialogYesNo.py
|
|
2
|
+
import customtkinter as tk
|
|
3
|
+
from .CdialogBase import CdialogBase, CdialogResult
|
|
4
|
+
|
|
5
|
+
class CdialogYesNo(CdialogBase):
|
|
6
|
+
|
|
7
|
+
def __init__(self, parent, title="Confirm", message="実行しますか?",
|
|
8
|
+
size=(600, 300), msg_font_size=18, msg_wraplength=420,
|
|
9
|
+
btn_width=100, btn_height=50, btn_font_size=14, default_button="YES"):
|
|
10
|
+
self._message = message
|
|
11
|
+
self._msg_font_size = msg_font_size
|
|
12
|
+
self._msg_wraplength = msg_wraplength
|
|
13
|
+
self._btn_width = btn_width
|
|
14
|
+
self._btn_height = btn_height
|
|
15
|
+
self._btn_font_size = btn_font_size
|
|
16
|
+
self._default_button = default_button # "YES" or "NO"
|
|
17
|
+
self._yes_btn = None
|
|
18
|
+
self._no_btn = None
|
|
19
|
+
super().__init__(parent, title=title, size=size)
|
|
20
|
+
|
|
21
|
+
def _build(self, root):
|
|
22
|
+
root.configure(padx=20, pady=20)
|
|
23
|
+
|
|
24
|
+
label = tk.CTkLabel(
|
|
25
|
+
root,
|
|
26
|
+
text=self._message,
|
|
27
|
+
font=("Meiryo", self._msg_font_size),
|
|
28
|
+
wraplength=self._msg_wraplength,
|
|
29
|
+
justify="center"
|
|
30
|
+
)
|
|
31
|
+
label.pack(pady=10)
|
|
32
|
+
|
|
33
|
+
frame = tk.CTkFrame(root)
|
|
34
|
+
frame.pack(pady=10)
|
|
35
|
+
|
|
36
|
+
yes_btn = tk.CTkButton(
|
|
37
|
+
frame,
|
|
38
|
+
text="YES",
|
|
39
|
+
width=self._btn_width,
|
|
40
|
+
height=self._btn_height,
|
|
41
|
+
font=("Meiryo", self._btn_font_size),
|
|
42
|
+
command=lambda: self._action_handle(CdialogResult.YES)
|
|
43
|
+
)
|
|
44
|
+
yes_btn.pack(side="left", padx=10)
|
|
45
|
+
|
|
46
|
+
no_btn = tk.CTkButton(
|
|
47
|
+
frame,
|
|
48
|
+
text="NO",
|
|
49
|
+
width=self._btn_width,
|
|
50
|
+
height=self._btn_height,
|
|
51
|
+
font=("Meiryo", self._btn_font_size),
|
|
52
|
+
command=lambda: self._action_handle(CdialogResult.NO)
|
|
53
|
+
)
|
|
54
|
+
no_btn.pack(side="right", padx=10)
|
|
55
|
+
|
|
56
|
+
self._yes_btn = yes_btn
|
|
57
|
+
self._no_btn = no_btn
|
|
58
|
+
|
|
59
|
+
# デフォルトボタンにフォーカスを設定
|
|
60
|
+
if self._default_button == "NO":
|
|
61
|
+
no_btn.focus_set()
|
|
62
|
+
else:
|
|
63
|
+
yes_btn.focus_set()
|
|
64
|
+
|
|
65
|
+
root.bind("<Return>", lambda e: self._action_handle(CdialogResult.YES))
|
|
66
|
+
root.bind("<Escape>", lambda e: self._action_handle(CdialogResult.NO))
|
|
67
|
+
#####################################################################
|
|
68
|
+
#サンプル
|
|
69
|
+
#####################################################################
|
|
70
|
+
if __name__ == "__main__":
|
|
71
|
+
root = tk.CTk()
|
|
72
|
+
root.geometry("800x400")
|
|
73
|
+
root.title("YES/NO Dialog テスト")
|
|
74
|
+
|
|
75
|
+
def test_yesno():
|
|
76
|
+
dlg = CdialogYesNo(root,
|
|
77
|
+
message="削除しますか?",
|
|
78
|
+
size=(700, 400), # ダイアログのサイズ
|
|
79
|
+
msg_font_size=24, # メッセージのフォントサイズ
|
|
80
|
+
msg_wraplength=550, # メッセージの折り返し幅
|
|
81
|
+
btn_width=150, # ボタンの幅
|
|
82
|
+
btn_height=60, # ボタンの高さ
|
|
83
|
+
btn_font_size=16, # ボタンのフォントサイズ
|
|
84
|
+
default_button="NO") # デフォルト選択("YES" or "NO")
|
|
85
|
+
result = dlg.show()
|
|
86
|
+
print(result)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
tk.CTkButton(root, text="YES/NO", command=test_yesno).pack(pady=20)
|
|
90
|
+
|
|
91
|
+
root.mainloop()
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# DialogBase.py
|
|
2
|
+
from enum import Enum
|
|
3
|
+
import tkinter as tk
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class DialogResult(Enum):
|
|
7
|
+
NONE = 0
|
|
8
|
+
OK = 1
|
|
9
|
+
CANCEL = 2
|
|
10
|
+
CLOSED = 3
|
|
11
|
+
YES = 4
|
|
12
|
+
NO = 5
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class DialogIcon(Enum):
|
|
16
|
+
INFO = "info"
|
|
17
|
+
WARNING = "warning"
|
|
18
|
+
ERROR = "error"
|
|
19
|
+
|
|
20
|
+
class DialogBase:
|
|
21
|
+
"""
|
|
22
|
+
Toplevel ベースのモーダルダイアログ基底クラス
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
def __init__(self, parent: tk.Tk, title="Dialog", size=(400, 200)):
|
|
26
|
+
self._parent = parent
|
|
27
|
+
self._result = DialogResult.NONE
|
|
28
|
+
|
|
29
|
+
self._tkRoot = tk.Toplevel(parent)
|
|
30
|
+
self._tkRoot.title(title)
|
|
31
|
+
self._tkRoot.geometry(f"{size[0]}x{size[1]}")
|
|
32
|
+
self._tkRoot.protocol("WM_DELETE_WINDOW", self._on_window_close)
|
|
33
|
+
|
|
34
|
+
self._tkRoot.transient(parent)
|
|
35
|
+
self._tkRoot.resizable(False, False)
|
|
36
|
+
self._tkRoot.withdraw()
|
|
37
|
+
|
|
38
|
+
self._build(self._tkRoot)
|
|
39
|
+
|
|
40
|
+
# ---------------------------------
|
|
41
|
+
def _build(self, root: tk.Toplevel):
|
|
42
|
+
pass
|
|
43
|
+
|
|
44
|
+
# ---------------------------------
|
|
45
|
+
def _on_window_close(self):
|
|
46
|
+
self._result = DialogResult.CLOSED
|
|
47
|
+
self._tkRoot.destroy()
|
|
48
|
+
|
|
49
|
+
# ---------------------------------
|
|
50
|
+
def _action_handle(self, result: DialogResult):
|
|
51
|
+
self._result = result
|
|
52
|
+
self._tkRoot.destroy()
|
|
53
|
+
|
|
54
|
+
# ---------------------------------
|
|
55
|
+
def show(self) -> DialogResult:
|
|
56
|
+
self._result = DialogResult.NONE
|
|
57
|
+
|
|
58
|
+
self._center_to_parent()
|
|
59
|
+
|
|
60
|
+
self._tkRoot.deiconify()
|
|
61
|
+
self._tkRoot.lift()
|
|
62
|
+
self._tkRoot.grab_set()
|
|
63
|
+
self._tkRoot.focus_set()
|
|
64
|
+
self._parent.wait_window(self._tkRoot)
|
|
65
|
+
|
|
66
|
+
return self._result
|
|
67
|
+
|
|
68
|
+
# ---------------------------------
|
|
69
|
+
def _center_to_parent(self):
|
|
70
|
+
self._parent.update_idletasks()
|
|
71
|
+
|
|
72
|
+
px = self._parent.winfo_x()
|
|
73
|
+
py = self._parent.winfo_y()
|
|
74
|
+
pw = self._parent.winfo_width()
|
|
75
|
+
ph = self._parent.winfo_height()
|
|
76
|
+
|
|
77
|
+
w = self._tkRoot.winfo_reqwidth()
|
|
78
|
+
h = self._tkRoot.winfo_reqheight()
|
|
79
|
+
|
|
80
|
+
x = px + (pw - w) // 2
|
|
81
|
+
y = py + (ph - h) // 2
|
|
82
|
+
|
|
83
|
+
self._tkRoot.geometry(f"+{x}+{y}")
|
|
84
|
+
|
|
85
|
+
#####################################################################
|
|
86
|
+
# 使用例(単体テスト)
|
|
87
|
+
#####################################################################
|
|
88
|
+
if __name__ == "__main__":
|
|
89
|
+
root = tk.Tk()
|
|
90
|
+
root.withdraw()
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
dlg = DialogBase(root, title="Dialog Example", size=(400, 200))
|
|
94
|
+
result = dlg.show()
|
|
95
|
+
print(f"Dialog result: {result}")
|
|
96
|
+
|
|
97
|
+
root.destroy()
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# DialogOk.py
|
|
2
|
+
import tkinter as tk
|
|
3
|
+
from .DialogBase import DialogBase, DialogResult, DialogIcon
|
|
4
|
+
|
|
5
|
+
class DialogOk(DialogBase):
|
|
6
|
+
|
|
7
|
+
def __init__(self, parent, title="OK", message="Message", icon=None):
|
|
8
|
+
self._message = message
|
|
9
|
+
self._icon = icon
|
|
10
|
+
super().__init__(parent, title=title, size=(420, 200))
|
|
11
|
+
|
|
12
|
+
def _build(self, root):
|
|
13
|
+
root.configure(padx=20, pady=20)
|
|
14
|
+
|
|
15
|
+
container = tk.Frame(root)
|
|
16
|
+
container.pack(expand=True)
|
|
17
|
+
|
|
18
|
+
if self._icon:
|
|
19
|
+
icon_label = tk.Label(container, bitmap=self._icon.value)
|
|
20
|
+
icon_label.pack(side="left", padx=(0, 15))
|
|
21
|
+
|
|
22
|
+
msg = tk.Label(
|
|
23
|
+
container,
|
|
24
|
+
text=self._message,
|
|
25
|
+
font=("Meiryo", 14),
|
|
26
|
+
wraplength=320,
|
|
27
|
+
justify="left"
|
|
28
|
+
)
|
|
29
|
+
msg.pack(side="left")
|
|
30
|
+
|
|
31
|
+
btn = tk.Button(
|
|
32
|
+
root,
|
|
33
|
+
text="OK",
|
|
34
|
+
width=10,
|
|
35
|
+
command=lambda: self._action_handle(DialogResult.OK)
|
|
36
|
+
)
|
|
37
|
+
btn.pack(pady=15)
|
|
38
|
+
|
|
39
|
+
btn.focus_set()
|
|
40
|
+
|
|
41
|
+
root.bind("<Return>", lambda e: self._action_handle(DialogResult.OK))
|
|
42
|
+
root.bind("<Escape>", lambda e: self._action_handle(DialogResult.OK))
|
|
43
|
+
#####################################################################
|
|
44
|
+
#
|
|
45
|
+
#####################################################################
|
|
46
|
+
if __name__ == "__main__":
|
|
47
|
+
root = tk.Tk()
|
|
48
|
+
root.geometry("500x300")
|
|
49
|
+
root.title("Dialog Test")
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def test_ok():
|
|
53
|
+
dlg = DialogOk(root, message="処理が完了しました。", icon=DialogIcon.INFO)
|
|
54
|
+
result = dlg.show()
|
|
55
|
+
print(result)
|
|
56
|
+
|
|
57
|
+
tk.Button(root, text="OK", command=test_ok).pack(pady=20)
|
|
58
|
+
|
|
59
|
+
root.mainloop()
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import tkinter as tk
|
|
2
|
+
from tkinter import ttk
|
|
3
|
+
|
|
4
|
+
from .DialogBase import DialogBase, DialogResult
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class DialogSelectReaderPort(DialogBase):
|
|
8
|
+
def __init__(self, parent, candidates, title="バーコードリーダー選択", message: str | None = None):
|
|
9
|
+
self._candidates = candidates
|
|
10
|
+
self._selection = None
|
|
11
|
+
self._message = message or "keyword に一致する機器が見つかりませんでした。\n同種の機器が接続されている場合は、使用する COM ポートを選択してください。"
|
|
12
|
+
super().__init__(parent, title=title, size=(860, 420))
|
|
13
|
+
|
|
14
|
+
def _build(self, root):
|
|
15
|
+
root.configure(padx=16, pady=16)
|
|
16
|
+
|
|
17
|
+
tk.Label(
|
|
18
|
+
root,
|
|
19
|
+
text=self._message,
|
|
20
|
+
font=("Meiryo", 11),
|
|
21
|
+
justify="left",
|
|
22
|
+
anchor="w",
|
|
23
|
+
).pack(fill="x", pady=(0, 10))
|
|
24
|
+
|
|
25
|
+
list_frame = ttk.Frame(root)
|
|
26
|
+
list_frame.pack(fill="both", expand=True)
|
|
27
|
+
|
|
28
|
+
columns = ("port", "description", "vid_pid", "serial", "manufacturer")
|
|
29
|
+
tree = ttk.Treeview(list_frame, columns=columns, show="headings", height=9, selectmode="browse")
|
|
30
|
+
tree.heading("port", text="COM")
|
|
31
|
+
tree.heading("description", text="説明")
|
|
32
|
+
tree.heading("vid_pid", text="VID/PID")
|
|
33
|
+
tree.heading("serial", text="Serial")
|
|
34
|
+
tree.heading("manufacturer", text="Manufacturer")
|
|
35
|
+
tree.column("port", width=90, anchor="center")
|
|
36
|
+
tree.column("description", width=320, anchor="w")
|
|
37
|
+
tree.column("vid_pid", width=120, anchor="center")
|
|
38
|
+
tree.column("serial", width=150, anchor="w")
|
|
39
|
+
tree.column("manufacturer", width=130, anchor="w")
|
|
40
|
+
|
|
41
|
+
scrollbar = ttk.Scrollbar(list_frame, orient="vertical", command=tree.yview)
|
|
42
|
+
tree.configure(yscrollcommand=scrollbar.set)
|
|
43
|
+
tree.pack(side="left", fill="both", expand=True)
|
|
44
|
+
scrollbar.pack(side="left", fill="y", padx=(8, 0))
|
|
45
|
+
|
|
46
|
+
for index, candidate in enumerate(self._candidates):
|
|
47
|
+
vid = candidate.get("vid", "")
|
|
48
|
+
pid = candidate.get("pid", "")
|
|
49
|
+
vid_pid = f"{vid}/{pid}" if vid and pid else vid or pid
|
|
50
|
+
tree.insert(
|
|
51
|
+
"",
|
|
52
|
+
"end",
|
|
53
|
+
iid=str(index),
|
|
54
|
+
values=(
|
|
55
|
+
candidate.get("port", ""),
|
|
56
|
+
candidate.get("description", ""),
|
|
57
|
+
vid_pid,
|
|
58
|
+
candidate.get("serial_number", ""),
|
|
59
|
+
candidate.get("manufacturer", ""),
|
|
60
|
+
),
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
if self._candidates:
|
|
64
|
+
tree.selection_set("0")
|
|
65
|
+
tree.focus("0")
|
|
66
|
+
self._tree = tree
|
|
67
|
+
|
|
68
|
+
button_frame = ttk.Frame(root)
|
|
69
|
+
button_frame.pack(fill="x", pady=(14, 0), side="bottom")
|
|
70
|
+
|
|
71
|
+
ttk.Button(
|
|
72
|
+
button_frame,
|
|
73
|
+
text="今回だけ接続",
|
|
74
|
+
command=lambda: self._select(False),
|
|
75
|
+
).pack(side="left")
|
|
76
|
+
ttk.Button(
|
|
77
|
+
button_frame,
|
|
78
|
+
text="今後も優先",
|
|
79
|
+
command=lambda: self._select(True),
|
|
80
|
+
).pack(side="left", padx=(8, 0))
|
|
81
|
+
ttk.Button(
|
|
82
|
+
button_frame,
|
|
83
|
+
text="キャンセル",
|
|
84
|
+
command=lambda: self._action_handle(DialogResult.CANCEL),
|
|
85
|
+
).pack(side="right")
|
|
86
|
+
|
|
87
|
+
root.bind("<Escape>", lambda _event: self._action_handle(DialogResult.CANCEL))
|
|
88
|
+
root.bind("<Return>", lambda _event: self._select(False))
|
|
89
|
+
tree.bind("<Double-1>", lambda _event: self._select(False))
|
|
90
|
+
|
|
91
|
+
def _get_selected_candidate(self):
|
|
92
|
+
selection = self._tree.selection()
|
|
93
|
+
if not selection:
|
|
94
|
+
return None
|
|
95
|
+
return self._candidates[int(selection[0])]
|
|
96
|
+
|
|
97
|
+
def _select(self, remember: bool) -> None:
|
|
98
|
+
candidate = self._get_selected_candidate()
|
|
99
|
+
if candidate is None:
|
|
100
|
+
return
|
|
101
|
+
self._selection = {
|
|
102
|
+
"port": candidate.get("port", ""),
|
|
103
|
+
"remember": remember,
|
|
104
|
+
"candidate": candidate,
|
|
105
|
+
}
|
|
106
|
+
self._action_handle(DialogResult.OK)
|
|
107
|
+
|
|
108
|
+
def show_selection(self):
|
|
109
|
+
self.show()
|
|
110
|
+
return self._selection
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# DialogYesNo.py
|
|
2
|
+
import tkinter as tk
|
|
3
|
+
from .DialogBase import DialogBase, DialogResult
|
|
4
|
+
|
|
5
|
+
class DialogYesNo(DialogBase):
|
|
6
|
+
|
|
7
|
+
def __init__(self, parent, title="Confirm", message="実行しますか?"):
|
|
8
|
+
self._message = message
|
|
9
|
+
super().__init__(parent, title=title, size=(420, 220))
|
|
10
|
+
|
|
11
|
+
def _build(self, root):
|
|
12
|
+
root.configure(padx=20, pady=20)
|
|
13
|
+
|
|
14
|
+
label = tk.Label(
|
|
15
|
+
root,
|
|
16
|
+
text=self._message,
|
|
17
|
+
font=("Meiryo", 14),
|
|
18
|
+
wraplength=360,
|
|
19
|
+
justify="center"
|
|
20
|
+
)
|
|
21
|
+
label.pack(pady=10)
|
|
22
|
+
|
|
23
|
+
frame = tk.Frame(root)
|
|
24
|
+
frame.pack(pady=10)
|
|
25
|
+
|
|
26
|
+
yes_btn = tk.Button(
|
|
27
|
+
frame,
|
|
28
|
+
text="YES",
|
|
29
|
+
width=8,
|
|
30
|
+
command=lambda: self._action_handle(DialogResult.YES)
|
|
31
|
+
)
|
|
32
|
+
yes_btn.pack(side="left", padx=10)
|
|
33
|
+
|
|
34
|
+
no_btn = tk.Button(
|
|
35
|
+
frame,
|
|
36
|
+
text="NO",
|
|
37
|
+
width=8,
|
|
38
|
+
command=lambda: self._action_handle(DialogResult.NO)
|
|
39
|
+
)
|
|
40
|
+
no_btn.pack(side="right", padx=10)
|
|
41
|
+
|
|
42
|
+
yes_btn.focus_set()
|
|
43
|
+
|
|
44
|
+
root.bind("<Return>", lambda e: self._action_handle(DialogResult.YES))
|
|
45
|
+
root.bind("<Escape>", lambda e: self._action_handle(DialogResult.NO))
|
|
46
|
+
#####################################################################
|
|
47
|
+
#サンプル
|
|
48
|
+
#####################################################################
|
|
49
|
+
if __name__ == "__main__":
|
|
50
|
+
root = tk.Tk()
|
|
51
|
+
root.geometry("500x300")
|
|
52
|
+
root.title("Dialog Test")
|
|
53
|
+
|
|
54
|
+
def test_yesno():
|
|
55
|
+
dlg = DialogYesNo(root, message="削除しますか?")
|
|
56
|
+
result = dlg.show()
|
|
57
|
+
print(result)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
tk.Button(root, text="YES/NO", command=test_yesno).pack(pady=20)
|
|
61
|
+
|
|
62
|
+
root.mainloop()
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from .DialogBase import DialogBase, DialogResult, DialogIcon
|
|
2
|
+
from .DialogOk import DialogOk
|
|
3
|
+
from .DialogYesNo import DialogYesNo
|
|
4
|
+
from .DialogSelectReaderPort import DialogSelectReaderPort
|
|
5
|
+
from .CdialogBase import CdialogBase, CdialogResult, CdialogIcon
|
|
6
|
+
from .CdialogOk import CdialogOk
|
|
7
|
+
from .CdialogYesNo import CdialogYesNo
|
|
8
|
+
|
|
9
|
+
__all__ = [
|
|
10
|
+
"DialogBase",
|
|
11
|
+
"DialogResult",
|
|
12
|
+
"DialogIcon",
|
|
13
|
+
"DialogOk",
|
|
14
|
+
"DialogYesNo",
|
|
15
|
+
"DialogSelectReaderPort",
|
|
16
|
+
"CdialogBase",
|
|
17
|
+
"CdialogResult",
|
|
18
|
+
"CdialogIcon",
|
|
19
|
+
"CdialogOk",
|
|
20
|
+
"CdialogYesNo"
|
|
21
|
+
]
|