pyxllib 0.3.197__py3-none-any.whl → 3.201.1__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.
Files changed (127) hide show
  1. pyxllib/__init__.py +14 -21
  2. pyxllib/algo/__init__.py +8 -8
  3. pyxllib/algo/disjoint.py +54 -54
  4. pyxllib/algo/geo.py +537 -541
  5. pyxllib/algo/intervals.py +964 -964
  6. pyxllib/algo/matcher.py +389 -389
  7. pyxllib/algo/newbie.py +166 -166
  8. pyxllib/algo/pupil.py +629 -629
  9. pyxllib/algo/shapelylib.py +67 -67
  10. pyxllib/algo/specialist.py +241 -241
  11. pyxllib/algo/stat.py +494 -494
  12. pyxllib/algo/treelib.py +145 -149
  13. pyxllib/algo/unitlib.py +62 -66
  14. pyxllib/autogui/__init__.py +5 -5
  15. pyxllib/autogui/activewin.py +246 -246
  16. pyxllib/autogui/all.py +9 -9
  17. pyxllib/autogui/autogui.py +846 -852
  18. pyxllib/autogui/uiautolib.py +362 -362
  19. pyxllib/autogui/virtualkey.py +102 -102
  20. pyxllib/autogui/wechat.py +827 -827
  21. pyxllib/autogui/wechat_msg.py +421 -421
  22. pyxllib/autogui/wxautolib.py +84 -84
  23. pyxllib/cv/__init__.py +5 -5
  24. pyxllib/cv/expert.py +267 -267
  25. pyxllib/cv/imfile.py +159 -159
  26. pyxllib/cv/imhash.py +39 -39
  27. pyxllib/cv/pupil.py +9 -9
  28. pyxllib/cv/rgbfmt.py +1525 -1525
  29. pyxllib/cv/slidercaptcha.py +137 -137
  30. pyxllib/cv/trackbartools.py +251 -251
  31. pyxllib/cv/xlcvlib.py +1040 -1040
  32. pyxllib/cv/xlpillib.py +423 -423
  33. pyxllib/data/echarts.py +236 -240
  34. pyxllib/data/jsonlib.py +85 -89
  35. pyxllib/data/oss.py +72 -72
  36. pyxllib/data/pglib.py +1111 -1127
  37. pyxllib/data/sqlite.py +568 -568
  38. pyxllib/data/sqllib.py +297 -297
  39. pyxllib/ext/JLineViewer.py +505 -505
  40. pyxllib/ext/__init__.py +6 -6
  41. pyxllib/ext/demolib.py +251 -246
  42. pyxllib/ext/drissionlib.py +277 -277
  43. pyxllib/ext/kq5034lib.py +12 -12
  44. pyxllib/ext/qt.py +449 -449
  45. pyxllib/ext/robustprocfile.py +493 -497
  46. pyxllib/ext/seleniumlib.py +76 -76
  47. pyxllib/ext/tk.py +173 -173
  48. pyxllib/ext/unixlib.py +821 -827
  49. pyxllib/ext/utools.py +345 -351
  50. pyxllib/ext/webhook.py +124 -119
  51. pyxllib/ext/win32lib.py +40 -40
  52. pyxllib/ext/wjxlib.py +91 -88
  53. pyxllib/ext/wpsapi.py +124 -124
  54. pyxllib/ext/xlwork.py +9 -9
  55. pyxllib/ext/yuquelib.py +1110 -1105
  56. pyxllib/file/__init__.py +17 -17
  57. pyxllib/file/docxlib.py +757 -761
  58. pyxllib/file/gitlib.py +309 -309
  59. pyxllib/file/libreoffice.py +165 -165
  60. pyxllib/file/movielib.py +144 -148
  61. pyxllib/file/newbie.py +10 -10
  62. pyxllib/file/onenotelib.py +1469 -1469
  63. pyxllib/file/packlib/__init__.py +330 -330
  64. pyxllib/file/packlib/zipfile.py +2441 -2441
  65. pyxllib/file/pdflib.py +422 -426
  66. pyxllib/file/pupil.py +185 -185
  67. pyxllib/file/specialist/__init__.py +681 -685
  68. pyxllib/file/specialist/dirlib.py +799 -799
  69. pyxllib/file/specialist/download.py +193 -193
  70. pyxllib/file/specialist/filelib.py +2825 -2829
  71. pyxllib/file/xlsxlib.py +3122 -3131
  72. pyxllib/file/xlsyncfile.py +341 -341
  73. pyxllib/prog/__init__.py +5 -5
  74. pyxllib/prog/cachetools.py +58 -64
  75. pyxllib/prog/deprecatedlib.py +233 -233
  76. pyxllib/prog/filelock.py +42 -42
  77. pyxllib/prog/ipyexec.py +253 -253
  78. pyxllib/prog/multiprogs.py +940 -940
  79. pyxllib/prog/newbie.py +451 -451
  80. pyxllib/prog/pupil.py +1208 -1197
  81. pyxllib/prog/sitepackages.py +33 -33
  82. pyxllib/prog/specialist/__init__.py +348 -391
  83. pyxllib/prog/specialist/bc.py +203 -203
  84. pyxllib/prog/specialist/browser.py +497 -497
  85. pyxllib/prog/specialist/common.py +347 -347
  86. pyxllib/prog/specialist/datetime.py +198 -198
  87. pyxllib/prog/specialist/tictoc.py +240 -240
  88. pyxllib/prog/specialist/xllog.py +180 -180
  89. pyxllib/prog/xlosenv.py +110 -108
  90. pyxllib/stdlib/__init__.py +17 -17
  91. pyxllib/stdlib/tablepyxl/__init__.py +10 -10
  92. pyxllib/stdlib/tablepyxl/style.py +303 -303
  93. pyxllib/stdlib/tablepyxl/tablepyxl.py +130 -130
  94. pyxllib/text/__init__.py +8 -8
  95. pyxllib/text/ahocorasick.py +36 -39
  96. pyxllib/text/airscript.js +754 -744
  97. pyxllib/text/charclasslib.py +121 -121
  98. pyxllib/text/jiebalib.py +267 -267
  99. pyxllib/text/jinjalib.py +27 -32
  100. pyxllib/text/jsa_ai_prompt.md +271 -271
  101. pyxllib/text/jscode.py +922 -922
  102. pyxllib/text/latex/__init__.py +158 -158
  103. pyxllib/text/levenshtein.py +303 -303
  104. pyxllib/text/nestenv.py +1215 -1215
  105. pyxllib/text/newbie.py +300 -300
  106. pyxllib/text/pupil/__init__.py +8 -8
  107. pyxllib/text/pupil/common.py +1121 -1121
  108. pyxllib/text/pupil/xlalign.py +326 -326
  109. pyxllib/text/pycode.py +47 -47
  110. pyxllib/text/specialist/__init__.py +8 -8
  111. pyxllib/text/specialist/common.py +112 -112
  112. pyxllib/text/specialist/ptag.py +186 -186
  113. pyxllib/text/spellchecker.py +172 -172
  114. pyxllib/text/templates/echart_base.html +10 -10
  115. pyxllib/text/templates/highlight_code.html +16 -16
  116. pyxllib/text/templates/latex_editor.html +102 -102
  117. pyxllib/text/vbacode.py +17 -17
  118. pyxllib/text/xmllib.py +741 -747
  119. pyxllib/xl.py +42 -39
  120. pyxllib/xlcv.py +17 -17
  121. pyxllib-3.201.1.dist-info/METADATA +296 -0
  122. pyxllib-3.201.1.dist-info/RECORD +125 -0
  123. {pyxllib-0.3.197.dist-info → pyxllib-3.201.1.dist-info}/licenses/LICENSE +190 -190
  124. pyxllib/ext/old.py +0 -663
  125. pyxllib-0.3.197.dist-info/METADATA +0 -48
  126. pyxllib-0.3.197.dist-info/RECORD +0 -126
  127. {pyxllib-0.3.197.dist-info → pyxllib-3.201.1.dist-info}/WHEEL +0 -0
@@ -1,76 +1,76 @@
1
- #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
- # @Author : 陈坤泽
4
- # @Email : 877362867@qq.com
5
- # @Date : 2023/03/28
6
-
7
- import time
8
-
9
- from selenium import webdriver
10
- from selenium.webdriver.common.by import By
11
- from selenium.webdriver.support.ui import WebDriverWait
12
- from selenium.webdriver.support import expected_conditions as EC
13
- from selenium.common.exceptions import ElementClickInterceptedException, NoSuchWindowException
14
-
15
-
16
- class element_has_text(object):
17
- def __init__(self, locator, text):
18
- self.locator = locator
19
- self.text = text
20
-
21
- def __call__(self, driver):
22
- element = driver.find_element(*self.locator)
23
- if self.text in element.text:
24
- return element
25
- else:
26
- return False
27
-
28
-
29
- class XlChrome(webdriver.Chrome):
30
- def __init__(self, *args, **kwargs):
31
- super().__init__(*args, **kwargs)
32
- self.maximize_window()
33
-
34
- def locate(self, locator, seconds=10):
35
- """ 定位一个元素 """
36
- if isinstance(locator, str): # 默认是XPATH格式
37
- locator = (By.XPATH, locator)
38
- return WebDriverWait(self, seconds).until(EC.presence_of_element_located(locator))
39
-
40
- def click(self, locator, seconds=10, check=True):
41
- """ 点击一个元素 """
42
- if isinstance(locator, str):
43
- locator = (By.XPATH, locator)
44
- if check:
45
- element = WebDriverWait(self, seconds).until(EC.element_to_be_clickable(locator))
46
- else:
47
- element = self.locate(locator, seconds)
48
- time.sleep(0.5) # 最好稍微等一下再点击
49
- try:
50
- element.click()
51
- except ElementClickInterceptedException:
52
- # 特殊情况,例如小鹅通下载页面的"下载"按钮没法正常click,要用js脚本去click
53
- self.execute_script("arguments[0].click();", element)
54
-
55
- def locate_text(self, locator, text, seconds=10):
56
- """ 判断指定元素位置是否含有指定文本 """
57
- if isinstance(locator, str):
58
- locator = (By.XPATH, locator)
59
- return WebDriverWait(self, seconds).until(element_has_text(locator, text))
60
-
61
- def __bool__(self):
62
- """ 判断driver是否还存在,如果已被手动关闭,这个值会返回False """
63
- try:
64
- self.title
65
- return True
66
- except NoSuchWindowException:
67
- return False
68
-
69
-
70
- def get_global_driver(_driver_store=[None]): # trick
71
- """ 通过这个接口可以固定一个driver来使用 """
72
- if _driver_store[0] is None:
73
- _driver_store[0] = XlChrome()
74
- if not _driver_store[0]: # 如果驱动没了,重新启动
75
- _driver_store[0] = XlChrome()
76
- return _driver_store[0]
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # @Author : 陈坤泽
4
+ # @Email : 877362867@qq.com
5
+ # @Date : 2023/03/28
6
+
7
+ import time
8
+
9
+ from selenium import webdriver
10
+ from selenium.webdriver.common.by import By
11
+ from selenium.webdriver.support.ui import WebDriverWait
12
+ from selenium.webdriver.support import expected_conditions as EC
13
+ from selenium.common.exceptions import ElementClickInterceptedException, NoSuchWindowException
14
+
15
+
16
+ class element_has_text(object):
17
+ def __init__(self, locator, text):
18
+ self.locator = locator
19
+ self.text = text
20
+
21
+ def __call__(self, driver):
22
+ element = driver.find_element(*self.locator)
23
+ if self.text in element.text:
24
+ return element
25
+ else:
26
+ return False
27
+
28
+
29
+ class XlChrome(webdriver.Chrome):
30
+ def __init__(self, *args, **kwargs):
31
+ super().__init__(*args, **kwargs)
32
+ self.maximize_window()
33
+
34
+ def locate(self, locator, seconds=10):
35
+ """ 定位一个元素 """
36
+ if isinstance(locator, str): # 默认是XPATH格式
37
+ locator = (By.XPATH, locator)
38
+ return WebDriverWait(self, seconds).until(EC.presence_of_element_located(locator))
39
+
40
+ def click(self, locator, seconds=10, check=True):
41
+ """ 点击一个元素 """
42
+ if isinstance(locator, str):
43
+ locator = (By.XPATH, locator)
44
+ if check:
45
+ element = WebDriverWait(self, seconds).until(EC.element_to_be_clickable(locator))
46
+ else:
47
+ element = self.locate(locator, seconds)
48
+ time.sleep(0.5) # 最好稍微等一下再点击
49
+ try:
50
+ element.click()
51
+ except ElementClickInterceptedException:
52
+ # 特殊情况,例如小鹅通下载页面的"下载"按钮没法正常click,要用js脚本去click
53
+ self.execute_script("arguments[0].click();", element)
54
+
55
+ def locate_text(self, locator, text, seconds=10):
56
+ """ 判断指定元素位置是否含有指定文本 """
57
+ if isinstance(locator, str):
58
+ locator = (By.XPATH, locator)
59
+ return WebDriverWait(self, seconds).until(element_has_text(locator, text))
60
+
61
+ def __bool__(self):
62
+ """ 判断driver是否还存在,如果已被手动关闭,这个值会返回False """
63
+ try:
64
+ self.title
65
+ return True
66
+ except NoSuchWindowException:
67
+ return False
68
+
69
+
70
+ def get_global_driver(_driver_store=[None]): # trick
71
+ """ 通过这个接口可以固定一个driver来使用 """
72
+ if _driver_store[0] is None:
73
+ _driver_store[0] = XlChrome()
74
+ if not _driver_store[0]: # 如果驱动没了,重新启动
75
+ _driver_store[0] = XlChrome()
76
+ return _driver_store[0]
pyxllib/ext/tk.py CHANGED
@@ -1,173 +1,173 @@
1
- #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
- # @Author : 陈坤泽
4
- # @Email : 877362867@qq.com
5
- # @Date : 2018/07/24 19:42
6
-
7
- """
8
- tkinter相关工具
9
- """
10
-
11
- import tkinter as tk
12
-
13
- from pyxllib.text.pupil import strwidth
14
-
15
-
16
- def askquestion(title='code4101py', message='void', **options):
17
- """对tk.messagebox.askquestion的封装,用于消息提示
18
-
19
- 默认会弹出一个主窗口,这里关掉了主窗口
20
- """
21
- from tkinter import messagebox
22
-
23
- win = tk.Tk()
24
- win.withdraw() # 不显示主窗口
25
-
26
- # 弹出信息提示窗口,根据选择会返回yes、no
27
- return tk.messagebox.askquestion(title, message, **options)
28
-
29
-
30
- def askstring(title='code4101py', prompt='void', **kwargs):
31
- """ 类似askquestion
32
- """
33
- from tkinter import simpledialog, messagebox
34
-
35
- # 不显示主窗口
36
- win = tk.Tk()
37
- win.withdraw()
38
-
39
- # 如果提示内容太短,要增加空格,使得标题的显示长度足够
40
- # tk的askstring默认最短有11个汉字多的长度
41
- # 标题非文本内容已经占掉大概13个汉字的宽度
42
- # 根据以上规律可推导出下述宽度控制算法
43
- len1 = strwidth(title) * 2 + 26
44
- len2 = strwidth(prompt)
45
- if len2 < len1:
46
- prompt += ' ' * (len1 - len2)
47
- # 显示窗口
48
- s = tk.simpledialog.askstring(title, prompt, **kwargs)
49
- return s
50
-
51
-
52
- def tk_init(title='tk', geometry='300x200'):
53
- """主窗口初始化"""
54
- from tkinter import Tk
55
-
56
- tk = Tk()
57
- tk.title(title)
58
- tk.geometry(geometry)
59
-
60
- # 可以设置字体
61
- # tk.option_add('*font', ('verdana', 12, 'bold'))
62
- return tk
63
-
64
-
65
- class AskStringByList:
66
- """使用举例:
67
- ob = AskStringByList(['选项1', '选项2'], title='AskStringByList')
68
- print(ob.value.get())
69
- """
70
-
71
- def __init__(self, ls=tuple(range(3)), **kwargs):
72
- """
73
- :param ls:
74
- :param kwargs:
75
- title: 设置主窗口名
76
- geometry: 设置主窗口大小,例如'300x200'
77
- """
78
- from tkinter import Frame
79
- from tkinter.constants import YES, BOTH
80
-
81
- self.ls = ls
82
- self.kwargs = kwargs
83
-
84
- self.tk = self.tk_init()
85
- self.frame = Frame()
86
- self.value = None
87
- self.entry = None
88
- self.listbox = None
89
- self.frame_init()
90
-
91
- self.frame.pack(fill=BOTH, expand=YES)
92
- self.tk.mainloop()
93
-
94
- def tk_init(self):
95
- # 1 设置基本属性
96
- from tkinter import Tk
97
- tk = Tk()
98
-
99
- # 设置标题
100
- if 'title' not in self.kwargs:
101
- self.kwargs['title'] = 'AskStringByList'
102
- tk.title(self.kwargs['title'])
103
-
104
- # 设置窗口大小
105
- if 'geometry' not in self.kwargs:
106
- self.kwargs['geometry'] = '300x400'
107
- tk.geometry(self.kwargs['geometry'])
108
-
109
- # 禁用窗口调整大小
110
- tk.resizable(False, False)
111
-
112
- # 2 绑定快捷键
113
- tk.bind("<Return>", self.enter) # 回车键跟 enter() 绑定
114
- tk.bind("<Escape>", self.esc) # Esc键跟 esc() 绑定
115
-
116
- return tk
117
-
118
- def enter(self, ev=None):
119
- """按下确认键后的功能"""
120
- self.tk.quit()
121
- # self.result = xxx
122
-
123
- def esc(self, ev=None):
124
- """按下esc键后的反应"""
125
- self.tk.quit()
126
- self.value.set('')
127
-
128
- def onselect(self, ev):
129
- d = self.listbox.curselection()
130
- d = d[0] if d else 0 # 如果没有选择,默认选第0个
131
- self.value.set(self.ls[d])
132
-
133
- def listbox_init(self):
134
- from tkinter import Listbox, Scrollbar
135
- from tkinter.constants import END
136
-
137
- # 1 创建listbox
138
- listbox = Listbox(self.frame, width=35)
139
- for t in self.ls:
140
- listbox.insert(END, t)
141
- listbox.place(relx=0.1, rely=0.3)
142
- listbox.bind('<<ListboxSelect>>', self.onselect)
143
-
144
- # 2 为列表添加滚动条
145
- s = Scrollbar(listbox)
146
- s.place(relx=0.94, relheight=1)
147
- s.config(command=listbox.yview)
148
- listbox.config(yscrollcommand=s.set)
149
-
150
- return listbox
151
-
152
- def frame_init(self):
153
- """主要是设置布局"""
154
- from tkinter import Button, Label, Entry, StringVar
155
-
156
- fm = self.frame
157
- Label(fm, text='请选择一个值或输入自定义新值:').place(relx=0.1, rely=0.1)
158
-
159
- self.value = StringVar()
160
- self.entry = Entry(fm, textvariable=self.value, width=35).place(relx=0.1, rely=0.2)
161
- self.listbox = self.listbox_init()
162
-
163
- # 默认第1个为初始值
164
- self.listbox.select_set(0)
165
- self.value.set(self.ls[0])
166
-
167
- Button(fm, text='确认(Enter)', command=self.enter, width=12).place(relx=0.15, rely=0.85)
168
- Button(fm, text='取消(Esc)', command=self.esc, width=12).place(relx=0.5, rely=0.85)
169
-
170
-
171
- if __name__ == '__main__':
172
- ob = AskStringByList()
173
- print(ob.value.get())
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # @Author : 陈坤泽
4
+ # @Email : 877362867@qq.com
5
+ # @Date : 2018/07/24 19:42
6
+
7
+ """
8
+ tkinter相关工具
9
+ """
10
+
11
+ import tkinter as tk
12
+
13
+ from pyxllib.text.pupil import strwidth
14
+
15
+
16
+ def askquestion(title='code4101py', message='void', **options):
17
+ """对tk.messagebox.askquestion的封装,用于消息提示
18
+
19
+ 默认会弹出一个主窗口,这里关掉了主窗口
20
+ """
21
+ from tkinter import messagebox
22
+
23
+ win = tk.Tk()
24
+ win.withdraw() # 不显示主窗口
25
+
26
+ # 弹出信息提示窗口,根据选择会返回yes、no
27
+ return tk.messagebox.askquestion(title, message, **options)
28
+
29
+
30
+ def askstring(title='code4101py', prompt='void', **kwargs):
31
+ """ 类似askquestion
32
+ """
33
+ from tkinter import simpledialog, messagebox
34
+
35
+ # 不显示主窗口
36
+ win = tk.Tk()
37
+ win.withdraw()
38
+
39
+ # 如果提示内容太短,要增加空格,使得标题的显示长度足够
40
+ # tk的askstring默认最短有11个汉字多的长度
41
+ # 标题非文本内容已经占掉大概13个汉字的宽度
42
+ # 根据以上规律可推导出下述宽度控制算法
43
+ len1 = strwidth(title) * 2 + 26
44
+ len2 = strwidth(prompt)
45
+ if len2 < len1:
46
+ prompt += ' ' * (len1 - len2)
47
+ # 显示窗口
48
+ s = tk.simpledialog.askstring(title, prompt, **kwargs)
49
+ return s
50
+
51
+
52
+ def tk_init(title='tk', geometry='300x200'):
53
+ """主窗口初始化"""
54
+ from tkinter import Tk
55
+
56
+ tk = Tk()
57
+ tk.title(title)
58
+ tk.geometry(geometry)
59
+
60
+ # 可以设置字体
61
+ # tk.option_add('*font', ('verdana', 12, 'bold'))
62
+ return tk
63
+
64
+
65
+ class AskStringByList:
66
+ """使用举例:
67
+ ob = AskStringByList(['选项1', '选项2'], title='AskStringByList')
68
+ print(ob.value.get())
69
+ """
70
+
71
+ def __init__(self, ls=tuple(range(3)), **kwargs):
72
+ """
73
+ :param ls:
74
+ :param kwargs:
75
+ title: 设置主窗口名
76
+ geometry: 设置主窗口大小,例如'300x200'
77
+ """
78
+ from tkinter import Frame
79
+ from tkinter.constants import YES, BOTH
80
+
81
+ self.ls = ls
82
+ self.kwargs = kwargs
83
+
84
+ self.tk = self.tk_init()
85
+ self.frame = Frame()
86
+ self.value = None
87
+ self.entry = None
88
+ self.listbox = None
89
+ self.frame_init()
90
+
91
+ self.frame.pack(fill=BOTH, expand=YES)
92
+ self.tk.mainloop()
93
+
94
+ def tk_init(self):
95
+ # 1 设置基本属性
96
+ from tkinter import Tk
97
+ tk = Tk()
98
+
99
+ # 设置标题
100
+ if 'title' not in self.kwargs:
101
+ self.kwargs['title'] = 'AskStringByList'
102
+ tk.title(self.kwargs['title'])
103
+
104
+ # 设置窗口大小
105
+ if 'geometry' not in self.kwargs:
106
+ self.kwargs['geometry'] = '300x400'
107
+ tk.geometry(self.kwargs['geometry'])
108
+
109
+ # 禁用窗口调整大小
110
+ tk.resizable(False, False)
111
+
112
+ # 2 绑定快捷键
113
+ tk.bind("<Return>", self.enter) # 回车键跟 enter() 绑定
114
+ tk.bind("<Escape>", self.esc) # Esc键跟 esc() 绑定
115
+
116
+ return tk
117
+
118
+ def enter(self, ev=None):
119
+ """按下确认键后的功能"""
120
+ self.tk.quit()
121
+ # self.result = xxx
122
+
123
+ def esc(self, ev=None):
124
+ """按下esc键后的反应"""
125
+ self.tk.quit()
126
+ self.value.set('')
127
+
128
+ def onselect(self, ev):
129
+ d = self.listbox.curselection()
130
+ d = d[0] if d else 0 # 如果没有选择,默认选第0个
131
+ self.value.set(self.ls[d])
132
+
133
+ def listbox_init(self):
134
+ from tkinter import Listbox, Scrollbar
135
+ from tkinter.constants import END
136
+
137
+ # 1 创建listbox
138
+ listbox = Listbox(self.frame, width=35)
139
+ for t in self.ls:
140
+ listbox.insert(END, t)
141
+ listbox.place(relx=0.1, rely=0.3)
142
+ listbox.bind('<<ListboxSelect>>', self.onselect)
143
+
144
+ # 2 为列表添加滚动条
145
+ s = Scrollbar(listbox)
146
+ s.place(relx=0.94, relheight=1)
147
+ s.config(command=listbox.yview)
148
+ listbox.config(yscrollcommand=s.set)
149
+
150
+ return listbox
151
+
152
+ def frame_init(self):
153
+ """主要是设置布局"""
154
+ from tkinter import Button, Label, Entry, StringVar
155
+
156
+ fm = self.frame
157
+ Label(fm, text='请选择一个值或输入自定义新值:').place(relx=0.1, rely=0.1)
158
+
159
+ self.value = StringVar()
160
+ self.entry = Entry(fm, textvariable=self.value, width=35).place(relx=0.1, rely=0.2)
161
+ self.listbox = self.listbox_init()
162
+
163
+ # 默认第1个为初始值
164
+ self.listbox.select_set(0)
165
+ self.value.set(self.ls[0])
166
+
167
+ Button(fm, text='确认(Enter)', command=self.enter, width=12).place(relx=0.15, rely=0.85)
168
+ Button(fm, text='取消(Esc)', command=self.esc, width=12).place(relx=0.5, rely=0.85)
169
+
170
+
171
+ if __name__ == '__main__':
172
+ ob = AskStringByList()
173
+ print(ob.value.get())