bcmd 0.6.8__py3-none-any.whl → 0.6.9__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.
Potentially problematic release.
This version of bcmd might be problematic. Click here for more details.
- bcmd/tasks/image.py +63 -70
- bcmd/tasks/lib.py +18 -21
- {bcmd-0.6.8.dist-info → bcmd-0.6.9.dist-info}/METADATA +2 -2
- {bcmd-0.6.8.dist-info → bcmd-0.6.9.dist-info}/RECORD +7 -8
- bcmd/utils/tkUtil.py +0 -243
- {bcmd-0.6.8.dist-info → bcmd-0.6.9.dist-info}/WHEEL +0 -0
- {bcmd-0.6.8.dist-info → bcmd-0.6.9.dist-info}/entry_points.txt +0 -0
- {bcmd-0.6.8.dist-info → bcmd-0.6.9.dist-info}/top_level.txt +0 -0
bcmd/tasks/image.py
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
1
|
import asyncio
|
|
4
2
|
import os
|
|
5
3
|
import random
|
|
6
|
-
import tkinter as tk
|
|
7
4
|
from enum import StrEnum
|
|
8
5
|
from pathlib import Path
|
|
9
6
|
from typing import Final, List, Tuple
|
|
@@ -16,9 +13,6 @@ from beni.bfunc import syncCall
|
|
|
16
13
|
from beni.btype import Null, XPath
|
|
17
14
|
from PIL import Image, ImageDraw, ImageFont
|
|
18
15
|
|
|
19
|
-
from bcmd.utils.tkUtil import TkForm, setWidgetEnabled
|
|
20
|
-
from tkinter import messagebox
|
|
21
|
-
|
|
22
16
|
app: Final = btask.newSubApp('图片工具集')
|
|
23
17
|
|
|
24
18
|
|
|
@@ -310,67 +304,66 @@ async def merge(
|
|
|
310
304
|
bcolor.printGreen('OK')
|
|
311
305
|
|
|
312
306
|
|
|
313
|
-
@app.command()
|
|
314
|
-
@syncCall
|
|
315
|
-
async def xone():
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
showGui()
|
|
307
|
+
# @app.command()
|
|
308
|
+
# @syncCall
|
|
309
|
+
# async def xone():
|
|
310
|
+
# def showGui():
|
|
311
|
+
# app = TkForm()
|
|
312
|
+
# app.title('图片操作')
|
|
313
|
+
# entry = app.addEntry('保存文件', tk.StringVar(value=r'C:\project\docs\source\docs\public\icon.webp'), width=60)
|
|
314
|
+
# app.addEntry('输入密码', tk.StringVar(), password=True, width=60, command=lambda: messagebox.showerror('错误', '密码错误'))
|
|
315
|
+
|
|
316
|
+
# scrolltextVar = tk.StringVar(value='xxiioo')
|
|
317
|
+
# app.addScrolledText('测试信箱', scrolltextVar)
|
|
318
|
+
|
|
319
|
+
# radioVarScale = app.addRadioBtnList(
|
|
320
|
+
# '缩放操作',
|
|
321
|
+
# [
|
|
322
|
+
# '保持',
|
|
323
|
+
# '缩放比',
|
|
324
|
+
# '指定宽度',
|
|
325
|
+
# '指定高度',
|
|
326
|
+
# ],
|
|
327
|
+
# onChanged=lambda x: onScaleValueChanged(x),
|
|
328
|
+
# var=tk.StringVar(value='保持'),
|
|
329
|
+
# )
|
|
330
|
+
|
|
331
|
+
# scaleValueEntry = app.addEntry('缩放参数', tk.StringVar(), width=10, justify=tk.CENTER)
|
|
332
|
+
|
|
333
|
+
# app.addChoisePath('选择文件', tk.StringVar(), isDir=True)
|
|
334
|
+
|
|
335
|
+
# radioVarFormat = app.addRadioBtnList(
|
|
336
|
+
# '格式转换',
|
|
337
|
+
# [
|
|
338
|
+
# '保持',
|
|
339
|
+
# 'PNG',
|
|
340
|
+
# 'JPEG',
|
|
341
|
+
# 'WEBP',
|
|
342
|
+
# ],
|
|
343
|
+
# var=tk.StringVar(value='保持'),
|
|
344
|
+
# )
|
|
345
|
+
# app.addCheckBox('去除透明', '去除透明', tk.BooleanVar(value=True))
|
|
346
|
+
# app.addCheckBox('TinyPng', 'TinyPng', tk.BooleanVar())
|
|
347
|
+
# app.addCheckBoxList('其他选项', [
|
|
348
|
+
# ('去除透明', tk.BooleanVar()),
|
|
349
|
+
# ('TinyPng', tk.BooleanVar(value=True)),
|
|
350
|
+
# ])
|
|
351
|
+
|
|
352
|
+
# def onScaleValueChanged(value: str):
|
|
353
|
+
# match value:
|
|
354
|
+
# case '保持':
|
|
355
|
+
# setWidgetEnabled(scaleValueEntry, False)
|
|
356
|
+
# case _:
|
|
357
|
+
# setWidgetEnabled(scaleValueEntry, True)
|
|
358
|
+
|
|
359
|
+
# app.addBtn('确定', lambda: onBtn())
|
|
360
|
+
|
|
361
|
+
# def onBtn():
|
|
362
|
+
# nonlocal result
|
|
363
|
+
# app.destroy()
|
|
364
|
+
|
|
365
|
+
# result: str = ''
|
|
366
|
+
# app.run()
|
|
367
|
+
# return result
|
|
368
|
+
|
|
369
|
+
# showGui()
|
bcmd/tasks/lib.py
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import os
|
|
2
|
+
import tkinter as tk
|
|
2
3
|
from pathlib import Path
|
|
3
4
|
from typing import Final
|
|
4
5
|
|
|
5
6
|
import typer
|
|
6
7
|
from beni import bcolor, bfile, bpath, brun, btask
|
|
8
|
+
from beni.bform import BForm
|
|
7
9
|
from beni.bfunc import syncCall
|
|
8
10
|
|
|
9
|
-
from bcmd.utils.tkUtil import TkForm
|
|
10
|
-
|
|
11
11
|
from ..common import secret
|
|
12
12
|
|
|
13
13
|
app: Final = btask.newSubApp('lib 工具')
|
|
@@ -23,7 +23,7 @@ async def update_version(
|
|
|
23
23
|
file = path / 'pyproject.toml'
|
|
24
24
|
btask.assertTrue(file.is_file(), '文件不存在', file)
|
|
25
25
|
data = await bfile.readToml(file)
|
|
26
|
-
latestVersion = data['project']['version']
|
|
26
|
+
latestVersion: str = data['project']['version']
|
|
27
27
|
vAry = [int(x) for x in latestVersion.split('.')]
|
|
28
28
|
versionList = [
|
|
29
29
|
f'{vAry[0] + 1}.0.0',
|
|
@@ -31,27 +31,24 @@ async def update_version(
|
|
|
31
31
|
f'{vAry[0]}.{vAry[1]}.{vAry[2] + 1}',
|
|
32
32
|
]
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
app = TkForm()
|
|
36
|
-
app.title('bcmd 版本更新')
|
|
37
|
-
app.addLabel('当前版本号', latestVersion)
|
|
38
|
-
version_var = app.addRadioBtnList(
|
|
39
|
-
'请选择新版本',
|
|
40
|
-
versionList,
|
|
41
|
-
selectedIndex=-1,
|
|
42
|
-
)
|
|
43
|
-
result: str = ''
|
|
34
|
+
class UpdateVersionForm(BForm):
|
|
44
35
|
|
|
45
|
-
def
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
36
|
+
def __init__(self):
|
|
37
|
+
super().__init__()
|
|
38
|
+
self.versionVar = tk.StringVar(value=versionList[-1])
|
|
39
|
+
self.title('bcmd 版本更新')
|
|
40
|
+
self.addLabel('当前版本号', latestVersion)
|
|
41
|
+
self.addRadioBtnList(
|
|
42
|
+
'请选择新版本',
|
|
43
|
+
versionList,
|
|
44
|
+
var=self.versionVar,
|
|
45
|
+
)
|
|
46
|
+
self.addBtn('确定', self.destroy, focus=True)
|
|
49
47
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
return result
|
|
48
|
+
def getResult(self) -> str:
|
|
49
|
+
return self.versionVar.get()
|
|
53
50
|
|
|
54
|
-
newVersion =
|
|
51
|
+
newVersion: str = UpdateVersionForm().run()
|
|
55
52
|
if not newVersion:
|
|
56
53
|
btask.abort('用户取消操作')
|
|
57
54
|
content = await bfile.readText(file)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bcmd
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.9
|
|
4
4
|
Summary: Commands for Beni
|
|
5
5
|
Author-email: Beni Mang <benimang@126.com>
|
|
6
6
|
Maintainer-email: Beni Mang <benimang@126.com>
|
|
@@ -8,7 +8,7 @@ Keywords: benimang,beni,bcmd
|
|
|
8
8
|
Requires-Python: >=3.10
|
|
9
9
|
Requires-Dist: aioconsole==0.8.1
|
|
10
10
|
Requires-Dist: async-lru==2.0.5
|
|
11
|
-
Requires-Dist: benimang==0.8.
|
|
11
|
+
Requires-Dist: benimang==0.8.6
|
|
12
12
|
Requires-Dist: cryptography==45.0.4
|
|
13
13
|
Requires-Dist: nest-asyncio==1.6.0
|
|
14
14
|
Requires-Dist: pillow==11.2.1
|
|
@@ -9,9 +9,9 @@ bcmd/tasks/code.py,sha256=IUs_ClZuSsBk2gavlitC8mkRrQQX9rvNDgR8cFxduBA,3992
|
|
|
9
9
|
bcmd/tasks/crypto.py,sha256=LKvgsMPLvsi1wlt66TinYiN-oV2IPAfaN9y7hWaVpHs,2951
|
|
10
10
|
bcmd/tasks/debian.py,sha256=B9aMIIct3vNqMJr5hTr1GegXVf20H49C27FMvRRGIzI,3004
|
|
11
11
|
bcmd/tasks/download.py,sha256=XdZYKi8zQTNYWEgUxeTNDqPgP7IGYJkMmlDDC9u93Vk,2315
|
|
12
|
-
bcmd/tasks/image.py,sha256=
|
|
12
|
+
bcmd/tasks/image.py,sha256=_ck-WVfUlyQ2fZTpVPcpcurWSud7AkANKUuFjMW7MwA,14283
|
|
13
13
|
bcmd/tasks/json.py,sha256=WWOyvcZPYaqQgp-Tkm-uIJschNMBKPKtZN3yXz_SC5s,635
|
|
14
|
-
bcmd/tasks/lib.py,sha256=
|
|
14
|
+
bcmd/tasks/lib.py,sha256=CmIRUHzNSa6s0Ft2oYZcfEr-5YwvxrVCNM55qq9sBXg,2948
|
|
15
15
|
bcmd/tasks/math.py,sha256=xbl5UdaDMyAjiLodDPleP4Cutrk2S3NOAgurzAgOEAE,2862
|
|
16
16
|
bcmd/tasks/mirror.py,sha256=nAe8NYftMKzht16MFBj7RqXwvVhR6Jh2uuAyJLh87og,1098
|
|
17
17
|
bcmd/tasks/pdf.py,sha256=fkHRgxqzrRxdb4_-9pL9wp2roqAHJPS_dVqAGJvRUsM,1504
|
|
@@ -20,14 +20,13 @@ bcmd/tasks/time.py,sha256=ZiqA1jdgl-TBtFSOxxP51nwv4g9iZItmkFKpf9MKelk,2453
|
|
|
20
20
|
bcmd/tasks/upgrade.py,sha256=z9Ein8U_Co7fsijPxyDFM8tXBFCp4bWATImwwwvC5ho,536
|
|
21
21
|
bcmd/tasks/wasabi.py,sha256=xWFAxprSIlBqDDMGaNXZFb-SahnW1d_R9XxSKRYIhnM,3110
|
|
22
22
|
bcmd/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
23
|
-
bcmd/utils/tkUtil.py,sha256=zhOFQB0SN-ZPSXgJ0-pyHeVldf_u8VNnODz7pQRbLkw,7709
|
|
24
23
|
test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
25
24
|
test/conftest.py,sha256=grlPunlsvrkt_8QPckmF4POiKUPVxIxm2TPAh_ZB-zs,405
|
|
26
25
|
test/test_pdf.py,sha256=7yYlfydyhy2dmVYdTA5Vir2AI8TUdzEi55fL-AqJmio,1533
|
|
27
26
|
test/test_proxy.py,sha256=UMF2hFFGUEbJR1jT2mO_wdo-7Rfp0NDqIdTRnOmwtjY,164
|
|
28
27
|
test/test_wasabi.py,sha256=qqXG1Kb9hKH6t624R173j6LagkgmejN0CFYt7kL0nNs,1066
|
|
29
|
-
bcmd-0.6.
|
|
30
|
-
bcmd-0.6.
|
|
31
|
-
bcmd-0.6.
|
|
32
|
-
bcmd-0.6.
|
|
33
|
-
bcmd-0.6.
|
|
28
|
+
bcmd-0.6.9.dist-info/METADATA,sha256=dUP3hFm6hT4tvf13ubEiaPvjyA5tloVlls7RlQQiNTE,812
|
|
29
|
+
bcmd-0.6.9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
30
|
+
bcmd-0.6.9.dist-info/entry_points.txt,sha256=mriCeYh3wksKcqq3-LtzyFkSCIdN1uZc1IJwom-SW1s,34
|
|
31
|
+
bcmd-0.6.9.dist-info/top_level.txt,sha256=fYY6tRrJ_G7tn24RXAG0M5ZKbcuaQznodfX1toFPSKs,10
|
|
32
|
+
bcmd-0.6.9.dist-info/RECORD,,
|
bcmd/utils/tkUtil.py
DELETED
|
@@ -1,243 +0,0 @@
|
|
|
1
|
-
import tkinter as tk
|
|
2
|
-
from tkinter import filedialog
|
|
3
|
-
from tkinter.scrolledtext import ScrolledText
|
|
4
|
-
from typing import Any, Callable, Literal, TypeVar, Union
|
|
5
|
-
from uuid import uuid4
|
|
6
|
-
|
|
7
|
-
RADIO_NOTHING = uuid4().hex
|
|
8
|
-
TkVar = TypeVar('TkVar', bound=Union[tk.StringVar, tk.IntVar, tk.DoubleVar, tk.BooleanVar])
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class TkForm(tk.Tk):
|
|
12
|
-
|
|
13
|
-
_rowIndex = -1
|
|
14
|
-
_initList: list[Callable[..., None]] = []
|
|
15
|
-
_varList: list[tk.Variable] = [] # 用来存储 var 变量,避免传出去,外面没有接收导致界面异常
|
|
16
|
-
|
|
17
|
-
def __init__(self):
|
|
18
|
-
super().__init__()
|
|
19
|
-
self.resizable(False, False)
|
|
20
|
-
self.bind("<Map>", self._onInit)
|
|
21
|
-
|
|
22
|
-
def _onInit(self, evt: tk.Event):
|
|
23
|
-
if evt.widget == self:
|
|
24
|
-
for callback in self._initList:
|
|
25
|
-
callback()
|
|
26
|
-
self._initList.clear()
|
|
27
|
-
|
|
28
|
-
def addInitHandler(self, handler: Callable[..., None]):
|
|
29
|
-
self._initList.append(handler)
|
|
30
|
-
|
|
31
|
-
def _initVar(self, var: TkVar) -> TkVar:
|
|
32
|
-
self._varList.append(var)
|
|
33
|
-
return var
|
|
34
|
-
|
|
35
|
-
def run(self):
|
|
36
|
-
self.center()
|
|
37
|
-
self.mainloop()
|
|
38
|
-
|
|
39
|
-
def center(self):
|
|
40
|
-
self.withdraw() # 先隐藏窗口,避免闪动
|
|
41
|
-
self.update_idletasks() # 确保获取正确的窗口尺寸
|
|
42
|
-
width = self.winfo_width() # 获取窗口宽度
|
|
43
|
-
height = self.winfo_height() # 获取窗口高度
|
|
44
|
-
screen_width = self.winfo_screenwidth() # 屏幕宽度
|
|
45
|
-
screen_height = self.winfo_screenheight() # 屏幕高度
|
|
46
|
-
x = (screen_width - width) // 2 # 水平居中
|
|
47
|
-
y = (screen_height - height) // 2 # 垂直居中
|
|
48
|
-
self.geometry(f"+{x}+{y}") # 设置窗口位置
|
|
49
|
-
self.deiconify() # 恢复显示窗口
|
|
50
|
-
|
|
51
|
-
def addRow(self, desc: str, widget: tk.Widget):
|
|
52
|
-
self._rowIndex += 1
|
|
53
|
-
tk.Label(text=desc).grid(row=self._rowIndex, column=0, padx=10, pady=5, sticky='e')
|
|
54
|
-
widget.grid(row=self._rowIndex, column=1, padx=10, pady=5, sticky='w')
|
|
55
|
-
|
|
56
|
-
def addRowFrame(self):
|
|
57
|
-
self._rowIndex += 1
|
|
58
|
-
frame = tk.Frame(self)
|
|
59
|
-
frame.grid(row=self._rowIndex, column=0, columnspan=2, padx=10, pady=5)
|
|
60
|
-
return frame
|
|
61
|
-
|
|
62
|
-
def addRowFrameWithDesc(self, desc: str):
|
|
63
|
-
self._rowIndex += 1
|
|
64
|
-
tk.Label(text=desc).grid(row=self._rowIndex, column=0, padx=10, pady=5, sticky='e')
|
|
65
|
-
frame = tk.Frame(self)
|
|
66
|
-
frame.grid(row=self._rowIndex, column=1, padx=10, pady=5, sticky='w')
|
|
67
|
-
return frame
|
|
68
|
-
|
|
69
|
-
def addLabel(
|
|
70
|
-
self,
|
|
71
|
-
desc: str,
|
|
72
|
-
text: str
|
|
73
|
-
):
|
|
74
|
-
self.addRow(desc, tk.Label(text=text))
|
|
75
|
-
|
|
76
|
-
def addBtn(
|
|
77
|
-
self,
|
|
78
|
-
label: str,
|
|
79
|
-
command: Callable[..., None],
|
|
80
|
-
*,
|
|
81
|
-
width: int = 20,
|
|
82
|
-
focus: bool = False
|
|
83
|
-
):
|
|
84
|
-
frame = self.addRowFrame()
|
|
85
|
-
btn = tk.Button(frame, text=label, width=width, command=command)
|
|
86
|
-
btn.pack(side="left", expand=True, padx=15)
|
|
87
|
-
if focus:
|
|
88
|
-
self._initFocus(btn)
|
|
89
|
-
|
|
90
|
-
def addRadioBtnList(
|
|
91
|
-
self,
|
|
92
|
-
desc: str,
|
|
93
|
-
selectionList: list[str],
|
|
94
|
-
*,
|
|
95
|
-
selectedIndex: int | None = None,
|
|
96
|
-
focusIndex: int | None = None,
|
|
97
|
-
onChanged: Callable[[str], None] | None = None,
|
|
98
|
-
):
|
|
99
|
-
frame = tk.Frame()
|
|
100
|
-
self.addRow(desc, frame)
|
|
101
|
-
var = tk.StringVar(value=selectionList[selectedIndex] if selectedIndex is not None else RADIO_NOTHING)
|
|
102
|
-
radioBtnList: list[tk.Radiobutton] = []
|
|
103
|
-
for version in selectionList:
|
|
104
|
-
radioBtn = tk.Radiobutton(frame, text=version, variable=var, value=version)
|
|
105
|
-
radioBtn.pack(side="left", padx=(0, 15))
|
|
106
|
-
setWidgetClickFocus(radioBtn)
|
|
107
|
-
radioBtnList.append(radioBtn)
|
|
108
|
-
if focusIndex is not None:
|
|
109
|
-
self._initFocus(radioBtnList[focusIndex])
|
|
110
|
-
if onChanged:
|
|
111
|
-
var.trace_add('write', lambda *args: onChanged(var.get())) # type: ignore
|
|
112
|
-
self.addInitHandler(
|
|
113
|
-
lambda: onChanged(var.get())
|
|
114
|
-
)
|
|
115
|
-
return var
|
|
116
|
-
|
|
117
|
-
def addEntry(
|
|
118
|
-
self,
|
|
119
|
-
desc: str,
|
|
120
|
-
var: tk.StringVar,
|
|
121
|
-
*,
|
|
122
|
-
width: int = 60,
|
|
123
|
-
focus: bool = False,
|
|
124
|
-
justify: Literal['left', 'right', 'center'] = tk.LEFT,
|
|
125
|
-
password: bool = False,
|
|
126
|
-
command: Callable[..., Any] | None = None,
|
|
127
|
-
):
|
|
128
|
-
self._initVar(var)
|
|
129
|
-
entry = tk.Entry(self, width=width, justify=justify, textvariable=var)
|
|
130
|
-
entry.icursor(tk.END)
|
|
131
|
-
self.addRow(desc, entry)
|
|
132
|
-
if password:
|
|
133
|
-
entry.config(show='*')
|
|
134
|
-
if focus:
|
|
135
|
-
self._initFocus(entry)
|
|
136
|
-
if command:
|
|
137
|
-
entry.bind('<Return>', lambda event: command())
|
|
138
|
-
return entry
|
|
139
|
-
|
|
140
|
-
def addChoisePath(
|
|
141
|
-
self,
|
|
142
|
-
desc: str,
|
|
143
|
-
var: tk.StringVar,
|
|
144
|
-
*,
|
|
145
|
-
width: int = 47,
|
|
146
|
-
focus: bool = False,
|
|
147
|
-
isDir: bool = False,
|
|
148
|
-
):
|
|
149
|
-
self._initVar(var)
|
|
150
|
-
frame = self.addRowFrameWithDesc(desc)
|
|
151
|
-
entry = tk.Entry(frame, width=width, textvariable=var)
|
|
152
|
-
entry.icursor(tk.END)
|
|
153
|
-
entry.pack(side="left")
|
|
154
|
-
btn = tk.Button(frame, text=f'选择{'目录' if isDir else '文件'} ...', width=10, command=lambda: onBtn())
|
|
155
|
-
btn.pack(side="left", padx=(10, 0))
|
|
156
|
-
if focus:
|
|
157
|
-
self._initFocus(btn)
|
|
158
|
-
|
|
159
|
-
def onBtn():
|
|
160
|
-
if isDir:
|
|
161
|
-
var.set(filedialog.askdirectory())
|
|
162
|
-
else:
|
|
163
|
-
var.set(filedialog.askopenfilename())
|
|
164
|
-
|
|
165
|
-
def addScrolledText(
|
|
166
|
-
self,
|
|
167
|
-
desc: str,
|
|
168
|
-
var: tk.StringVar,
|
|
169
|
-
*,
|
|
170
|
-
width: int = 60,
|
|
171
|
-
height: int = 3,
|
|
172
|
-
focus: bool = False,
|
|
173
|
-
):
|
|
174
|
-
self._initVar(var)
|
|
175
|
-
scrolledText = ScrolledText(self, width=width, height=height)
|
|
176
|
-
scrolledText.insert(tk.END, var.get())
|
|
177
|
-
self.addRow(desc, scrolledText)
|
|
178
|
-
|
|
179
|
-
def on_text_change(*args: Any):
|
|
180
|
-
new_value = scrolledText.get("1.0", tk.END)
|
|
181
|
-
if new_value != var.get():
|
|
182
|
-
var.set(new_value)
|
|
183
|
-
|
|
184
|
-
scrolledText.bind("<KeyRelease>", on_text_change)
|
|
185
|
-
|
|
186
|
-
def on_tab(event: tk.Event):
|
|
187
|
-
widget = event.widget.tk_focusNext()
|
|
188
|
-
assert widget
|
|
189
|
-
widget.focus_set()
|
|
190
|
-
return "break"
|
|
191
|
-
|
|
192
|
-
scrolledText.bind("<Tab>", on_tab)
|
|
193
|
-
|
|
194
|
-
if focus:
|
|
195
|
-
self._initFocus(scrolledText)
|
|
196
|
-
return scrolledText
|
|
197
|
-
|
|
198
|
-
def addCheckBox(
|
|
199
|
-
self,
|
|
200
|
-
desc: str,
|
|
201
|
-
text: str,
|
|
202
|
-
value: bool = False,
|
|
203
|
-
):
|
|
204
|
-
var = tk.BooleanVar(value=value)
|
|
205
|
-
self._initVar(var)
|
|
206
|
-
check_btn = tk.Checkbutton(text=text, variable=var)
|
|
207
|
-
self.addRow(desc, check_btn)
|
|
208
|
-
self.addInitHandler(
|
|
209
|
-
lambda: var.set(var.get())
|
|
210
|
-
)
|
|
211
|
-
setWidgetClickFocus(check_btn)
|
|
212
|
-
return var
|
|
213
|
-
|
|
214
|
-
def addCheckBoxList(
|
|
215
|
-
self,
|
|
216
|
-
desc: str,
|
|
217
|
-
dataList: list[tuple[str, bool]],
|
|
218
|
-
):
|
|
219
|
-
varDict: dict[str, tk.BooleanVar] = {}
|
|
220
|
-
frame = tk.Frame(self)
|
|
221
|
-
self.addRow(desc, frame)
|
|
222
|
-
for label, value in dataList:
|
|
223
|
-
varDict[label] = tk.BooleanVar(value=value)
|
|
224
|
-
checkbox = tk.Checkbutton(frame, text=label, variable=varDict[label])
|
|
225
|
-
checkbox.pack(side="left", expand=True, padx=(0, 15))
|
|
226
|
-
setWidgetClickFocus(checkbox)
|
|
227
|
-
self.addInitHandler(
|
|
228
|
-
lambda: varDict[label].set(varDict[label].get())
|
|
229
|
-
)
|
|
230
|
-
return varDict
|
|
231
|
-
|
|
232
|
-
def _initFocus(self, widget: tk.Widget):
|
|
233
|
-
self.addInitHandler(
|
|
234
|
-
lambda: widget.focus_set()
|
|
235
|
-
)
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
def setWidgetEnabled(widget: tk.Widget, value: bool):
|
|
239
|
-
widget['state'] = tk.NORMAL if value else tk.DISABLED
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
def setWidgetClickFocus(widget: tk.Widget):
|
|
243
|
-
widget.bind("<Button-1>", lambda args: args.widget.focus_set())
|
|
File without changes
|
|
File without changes
|
|
File without changes
|