回答編集履歴

3

FocusOut による挙動のサンプル

2022/04/12 07:05

投稿

teamikl
teamikl

スコア8760

test CHANGED
@@ -22,3 +22,96 @@
22
22
  - WM_DELETE_WINDOW 時に非表示 (withdraw)
23
23
 
24
24
  とすると、Combobox のリスト選択ででてくるようなポップアップ・ウィンドウの挙動に近くなります。
25
+
26
+
27
+ ----
28
+ FocusOut による挙動のサンプル
29
+
30
+ ```python
31
+ #!/usr/bin/env python3.9
32
+
33
+ import tkinter as tk
34
+ from tkinter import ttk
35
+ from functools import partial
36
+
37
+ TimeSpinbox = partial(ttk.Spinbox,
38
+ from_=0, to=60, format="%02.0f")
39
+
40
+
41
+ class TimeEdit(ttk.Frame):
42
+ def __init__(self, *args, **kw):
43
+ super().__init__(*args, **kw)
44
+
45
+ var_hh = tk.IntVar(self)
46
+ var_mm = tk.IntVar(self)
47
+
48
+ entry_hh = TimeSpinbox(self,
49
+ textvariable=var_hh)
50
+ entry_mm = TimeSpinbox(self,
51
+ textvariable=var_mm)
52
+ separator = ttk.Label(self, text=":")
53
+
54
+ entry_hh.grid(row=0, column=0)
55
+ separator.grid(row=0, column=1)
56
+ entry_mm.grid(row=0, column=2)
57
+
58
+ entry_hh.set("00")
59
+ entry_mm.set("00")
60
+
61
+ self._var_hh = var_hh
62
+ self._var_mm = var_mm
63
+ self._entry_hh = entry_hh
64
+ self._entry_mm = entry_mm
65
+
66
+
67
+ def main():
68
+ root = tk.Tk()
69
+
70
+ top = tk.Toplevel(root)
71
+ top.wm_overrideredirect (True)
72
+ top.withdraw()
73
+ top.bind("<FocusOut>", lambda e:top.withdraw())
74
+ top.protocol("WM_DELETE_WINDOW", top.withdraw)
75
+ edit = TimeEdit(top)
76
+ edit.pack()
77
+
78
+
79
+
80
+ def enterEditCell(event):
81
+ tree = event.widget
82
+ region = tree.identify_region(event.x, event.y)
83
+ if region == "cell":
84
+ col = tree.identify_column(event.x)
85
+ item = tree.selection()[0]
86
+ x, y, w, h = tree.bbox(item, col)
87
+
88
+ x += tree.winfo_rootx()
89
+ y += tree.winfo_rooty() + h
90
+
91
+ w2 = top.winfo_reqwidth()
92
+ h2 = top.winfo_reqheight()
93
+ W = root.winfo_screenwidth()
94
+ H = root.winfo_screenheight()
95
+ if (y + h2) > H:
96
+ y -= h
97
+ y -= h2
98
+
99
+ top.geometry(f"{w2}x{h2}+{x}+{y}")
100
+ top.deiconify()
101
+ top.focus_set()
102
+
103
+ COLUMNS = ["Value", "Time (hh:mm)"]
104
+ tree = ttk.Treeview(root, columns=COLUMNS, show="headings")
105
+ for col in COLUMNS:
106
+ tree.heading(col, text=col)
107
+ tree.bind("<Double-ButtonRelease-1>", enterEditCell)
108
+ for num in range(10):
109
+ tree.insert("", tk.END, values=(num,num*10))
110
+ tree.pack()
111
+
112
+ root.mainloop()
113
+
114
+
115
+ if __name__ == '__main__':
116
+ main()
117
+ ```

2

追記

2022/04/11 13:05

投稿

teamikl
teamikl

スコア8760

test CHANGED
@@ -13,3 +13,12 @@
13
13
  ちなみに、タイトルバーのサイズを足し引きして調整は可能ですが、
14
14
  タイトルバーのサイズを所得する関数は tkinter にはなく、
15
15
  プラットフォームやモニター環境依存になってきます。
16
+
17
+ ----
18
+ 追記: ポップアップウィンドウの挙動に寄せるなら
19
+
20
+ - ウィンドウ表示時に入力欄へ focus 移動
21
+ - ポップアップウィンドウ(Toplevel)の"<Leave>" イベントで、フォーカスが外れた時に非表示 (withdraw)
22
+ - WM_DELETE_WINDOW 時に非表示 (withdraw)
23
+
24
+ とすると、Combobox のリスト選択ででてくるようなポップアップ・ウィンドウの挙動に近くなります。

1

情報訂正: テーマ影響はなし

2022/04/11 12:33

投稿

teamikl
teamikl

スコア8760

test CHANGED
@@ -12,4 +12,4 @@
12
12
 
13
13
  ちなみに、タイトルバーのサイズを足し引きして調整は可能ですが、
14
14
  タイトルバーのサイズを所得する関数は tkinter にはなく、
15
- プラットフォームやモニター環境、テーマ依存になってきます。
15
+ プラットフォームやモニター環境依存になってきます。