Use python tkinter to get user input from text area
问渠哪得清如许 白云深处有人家
- cat gui.py
from __future__ import annotations
import sys
import tkinter as tk
class TkGui:
@classmethod
def input(cls, prompt: str = "", label_btn_text: tuple[str, str] | None = None) -> str:
self = cls(prompt, label_btn_text)
self.root.mainloop()
return str(self)
def __str__(self) -> str:
return self.text_content
@property
def text_content(self) -> str:
return self._text_content
def __init__(
self, title: str | None = None, label_btn_text: tuple[str, str] | None = None
) -> None:
self.root = tk.Tk()
if title:
self.root.title(title)
self.text_area = tk.Text(self.root, height=50, width=180)
if label_btn_text:
self.pack_label_button(*label_btn_text)
self.text_area.pack(padx=10, pady=2)
self.root.protocol("WM_DELETE_WINDOW", self.on_closing)
self._text_content = ""
def on_closing(self) -> None:
self._text_content = self.text_area.get("1.0", tk.END)
self.root.destroy()
def pack_label_button(self, label_text: str, btn_text: str) -> None:
frame = tk.Frame(self.root)
frame.pack(pady=0)
label = tk.Label(frame, text=label_text)
label.pack(side=tk.LEFT, padx=5)
btn = tk.Button(frame, text=btn_text, command=self.on_closing)
btn.pack(side=tk.LEFT, padx=5)
def main() -> None:
if not sys.argv[1:]:
text = TkGui.input()
elif not sys.argv[2:]:
text = TkGui.input(sys.argv[1])
elif not sys.argv[3:]:
text = TkGui.input(label_btn_text=(sys.argv[1], sys.argv[2]))
else:
text = TkGui.input(sys.argv[1], label_btn_text=(sys.argv[2], sys.argv[3]))
print("text:", text)
if __name__ == "__main__":
main()
- python3.14 gui.py 这是标题 提示框文本 确认
![image]()
代码丢给DeepSeek,叫她优化一下,结果变成这样了:
from __future__ import annotations
import sys
import tkinter as tk
class NotepadGui(tk.Tk):
"""一个简单的文本输入GUI应用,支持自定义标题和按钮标签"""
def __init__(
self, title: str | None = None, label_btn_text: tuple[str, str] | None = None
) -> None:
"""初始化GUI
Args:
title: 窗口标题
label_btn_text: 包含标签文本和按钮文本的元组
"""
super().__init__()
self._text_content = ""
self._setup_ui(title, label_btn_text)
def _setup_ui(self, title: str | None, label_btn_text: tuple[str, str] | None) -> None:
"""设置用户界面"""
if title:
self.title(title)
self.text_area = tk.Text(self, height=30, width=100, wrap=tk.WORD)
self.text_area.pack(padx=10, pady=10, expand=True, fill=tk.BOTH)
if label_btn_text:
self._add_label_button(*label_btn_text)
self.protocol("WM_DELETE_WINDOW", self._on_closing)
self.bind("<Escape>", lambda e: self._on_closing())
def _add_label_button(self, label_text: str, btn_text: str) -> None:
"""添加标签和按钮"""
control_frame = tk.Frame(self)
control_frame.pack(pady=(0, 10))
tk.Label(control_frame, text=label_text).pack(side=tk.LEFT, padx=5)
tk.Button(control_frame, text=btn_text, command=self._on_closing, padx=10).pack(
side=tk.LEFT, padx=5
)
def _on_closing(self) -> None:
"""窗口关闭时的处理"""
self._text_content = self.text_area.get("1.0", tk.END).strip()
self.destroy()
@classmethod
def input(cls, prompt: str = "", label_btn_text: tuple[str, str] | None = None) -> str:
"""类方法提供简洁的输入接口
Args:
prompt: 窗口标题
label_btn_text: 标签和按钮文本
Returns:
用户输入的文本内容
"""
instance = cls(prompt, label_btn_text)
instance.mainloop()
return str(instance)
def __str__(self) -> str:
"""返回文本内容"""
return self.text_content
@property
def text_content(self) -> str:
"""文本内容属性"""
return self._text_content
def parse_args(args: list[str]) -> tuple[str, tuple[str, str] | None]:
"""解析命令行参数"""
if not args:
return "", None
if len(args) == 1:
return args[0], None
if len(args) == 2:
return "", (args[0], args[1])
return args[0], (args[1], args[2])
def main() -> None:
"""主函数"""
title, label_btn_text = parse_args(sys.argv[1:])
text = NotepadGui.input(title, label_btn_text)
print("用户输入:", text)
if __name__ == "__main__":
main()
优化结果还行吧,至少加了很多注释,有时候最烦的就是写注释。。。
审视了一下,把代码重构成Python3.10以上专用的:
import tkinter as tk
class NotepadGui(tk.Tk):
"""一个简单的文本输入GUI应用,支持自定义标题和按钮标签"""
@classmethod
def input(
cls, prompt: str = "", label_btn_text: tuple[str, str] | None = None
) -> str:
"""类方法提供简洁的输入接口
Args:
prompt: 窗口标题
label_btn_text: 标签和按钮文本
Returns:
用户输入的文本内容
"""
instance = cls(prompt, label_btn_text)
instance.mainloop()
return str(instance)
def __str__(self) -> str:
"""返回文本框内容"""
return self.text_content
@property
def text_content(self) -> str:
# Use property to make it readonly
return self._text_content
def __init__(
self, title: str | None = None, label_btn_text: tuple[str, str] | None = None
) -> None:
"""初始化GUI
Args:
title: 窗口标题
label_btn_text: 包含标签文本和按钮文本的元组
"""
super().__init__()
self._text_content = ""
self._setup_ui(title, label_btn_text)
def _setup_ui(
self, title: str | None, label_btn_text: tuple[str, str] | None
) -> None:
"""设置用户界面"""
if title:
self.title(title)
self.text_area = tk.Text(self, height=30, width=100, wrap=tk.WORD)
if label_btn_text:
self._add_label_button(*label_btn_text)
self.text_area.pack(padx=10, pady=10, expand=True, fill=tk.BOTH)
def _add_label_button(self, label_text: str, btn_text: str) -> None:
"""添加标签和按钮"""
frame = tk.Frame(self)
frame.pack(pady=(0, 10))
tk.Label(frame, text=label_text).pack(side=tk.LEFT, padx=5)
tk.Button(frame, text=btn_text, command=self.destroy, padx=10).pack(
side=tk.LEFT, padx=5
)
def destroy(self) -> None:
self._text_content = self.text_area.get("1.0", tk.END).strip()
return super().destroy()
def parse_args(args: list[str]) -> tuple[str, tuple[str, str] | None]:
"""解析命令行参数"""
match len(args):
case 0:
return "", None
case 1:
return args[0], None
case 2:
return "", (args[0], args[1])
case _:
return args[0], (args[1], args[2])
def main() -> None:
import sys
title, label_btn_text = parse_args(sys.argv[1:])
text = NotepadGui.input(title, label_btn_text)
print("用户输入:", text)
if __name__ == "__main__":
main()


浙公网安备 33010602011771号