基于Python编写一个win10桌面便签工具
作者:Yorlen_Zhang
Python的GUI(图形用户界面)库Tkinter是Python标准库的一部分,用于创建桌面应用程序。"Python GUI Win10 便贴"项目就是利用Tkinter来模仿Windows 10操作系统中的便签功能,提供了类似的功能,让用户可以在桌面上创建、编辑和管理文本小记。
Tkinter库提供了丰富的控件和布局管理器,使得开发者可以轻松构建具有窗口、按钮、文本框等元素的应用程序。在"Python tkinter GUI Windows10 sticky note"这个项目中,开发者可能使用了Tkinter的`Tk`类来创建主窗口,`Label`控件来显示文本,`Text`控件来实现可编辑的便签内容,并可能使用了`Button`控件来添加、保存或删除便签。
在设计这样一个GUI应用时,开发者可能考虑了以下几点:
1. 用户交互:通过点击按钮或者使用快捷键来实现新建、编辑、保存、删除等功能。
2. 数据持久化:为了保存用户的便签内容,开发者可能使用了文件存储(如JSON或pickle格式)或数据库来存储数据,确保即使程序关闭后,便签内容也不会丢失。
3. 界面设计:模仿Windows 10的风格,包括颜色、字体、图标等,以提供一致的用户体验。
4. 窗口管理:利用Tkinter的`geometry`方法调整窗口大小和位置,允许用户自由拖动和调整大小。
5. 事件绑定:使用`bind`函数监听键盘和鼠标事件,响应用户的操作。
6. 多个便签管理:如果程序支持创建多个便签,可能使用列表或其他容器结构来存储每个便签对象。
在实际使用中,用户可以通过这个Python实现的"Win10 便贴"轻松记录日常琐事、待办事项或者灵感,享受与Windows 10系统一致的便利体验,同时得益于Python和Tkinter的易用性,开发者可以快速实现和定制自己的需求。
以下是完整代码
可以拿去自己生成小程序
import tkinter as tk
from tkinter import colorchooser, font, messagebox, simpledialog
import json
import os
from pathlib import Path
from datetime import datetime
# 常量定义(便于维护)
DEFAULT_PASSWORD = "123456"
MIN_WIDTH = 200
MIN_HEIGHT = 150
AUTO_SAVE_INTERVAL = 5000 # 5秒自动保存
PURE_MODE_DELAY = 10000 # 10秒进入纯净模式
CONFIG_FILE = Path.home() / "sticky_note_config.json" # 保存到用户目录
CONTENT_FILE = Path.home() / "sticky_note_content.txt"
PASSWORD_FILE = Path.home() / "sticky_note_pwd.json"
class BorderlessStickyNote:
def __init__(self, root):
self.root = root
self.root.title("极简便签")
self.root.geometry("400x500+100+100")
# 核心状态变量
self.root.overrideredirect(True) # 移除窗口装饰
self.resizing = False
self.moving = False
self._drag_data = {"x": 0, "y": 0}
self.hide_timer = None
# 样式配置
self.current_font_family = "Microsoft YaHei"
self.current_font_size = 14
self.current_font_color = "#2C3E50"
self.current_bg_color = "#FFFEF0"
self.current_alpha = 0.95
self.is_topmost = True
# 密码配置
self.close_password = self.load_password()
# 初始化UI
self.root.attributes('-topmost', self.is_topmost)
self.root.attributes('-alpha', self.current_alpha)
self.load_config() # 加载配置(覆盖默认值)
self.create_ui()
self.create_context_menu()
self.bind_events()
self.load_content()
# 启动定时任务
self.schedule_pure_mode()
self.schedule_auto_save()
def create_ui(self):
"""创建界面(优化布局和初始提示)"""
# 主容器(调整大小边框)
self.main_container = tk.Frame(self.root, bg="#CCCCCC", cursor="arrow")
self.main_container.pack(fill=tk.BOTH, expand=True)
# 内容区域
self.main_frame = tk.Frame(self.main_container, bg=self.current_bg_color, bd=0)
self.main_frame.pack(fill=tk.BOTH, expand=True, padx=1, pady=1)
# 文本编辑区(增加初始提示)
self.text_area = tk.Text(
self.main_frame,
wrap=tk.WORD,
font=(self.current_font_family, self.current_font_size),
fg=self.current_font_color,
bg=self.current_bg_color,
padx=20,
pady=20,
undo=True,
maxundo=50, # 增加撤销次数
relief=tk.FLAT,
highlightthickness=0,
insertbackground=self.current_font_color,
selectbackground="#3498DB",
selectforeground="white",
spacing1=3,
spacing3=3,
borderwidth=0
)
self.text_area.pack(fill=tk.BOTH, expand=True, padx=2, pady=2)
# 初始提示文字
if not os.path.exists(CONTENT_FILE) or os.path.getsize(CONTENT_FILE) == 0:
self.text_area.insert("1.0",
"✨ 欢迎使用极简便签\n\n- 右键可打开功能菜单\n- Alt+左键拖动移动窗口\n- 边缘/角落拖动调整大小\n- Ctrl+滚轮调整字号")
self.text_area.tag_add("hint", "1.0", "5.0")
self.text_area.tag_config("hint", foreground="#999999")
def create_context_menu(self):
"""创建优化后的右键菜单(修复勾选状态、新增功能)"""
# 置顶状态变量(持久化)
self.topmost_var = tk.BooleanVar(value=self.is_topmost)
self.menu = tk.Menu(self.root, tearoff=0, bg="white", fg="#333",
activebackground="#E0E0E0", font=("Microsoft YaHei", 10))
# 窗口控制(优化)
self.menu.add_command(label="🖱️ 移动窗口", command=self.start_move_mode)
self.menu.add_command(label="🗕 最小化窗口", command=self.minimize_window)
self.menu.add_checkbutton(
label="📌 窗口置顶",
variable=self.topmost_var,
command=self.toggle_topmost
)
self.menu.add_separator()
# 字体设置(新增字体家族选择)
font_menu = tk.Menu(self.menu, tearoff=0, bg="white")
# 字体家族子菜单
family_menu = tk.Menu(font_menu, tearoff=0, bg="white")
common_fonts = ["Microsoft YaHei", "SimSun", "SimHei", "KaiTi", "Arial", "Times New Roman"]
for f in common_fonts:
family_menu.add_command(
label=f" {f} {'✓' if f == self.current_font_family else ''}",
command=lambda fm=f: self.set_font_family(fm)
)
font_menu.add_cascade(label="字体家族", menu=family_menu)
# 字体大小子菜单
size_menu = tk.Menu(font_menu, tearoff=0, bg="white")
for size in [10, 12, 14, 16, 18, 20, 24, 28, 32]:
size_menu.add_command(
label=f" {size}px {'✓' if size == self.current_font_size else ''}",
command=lambda s=size: self.set_font_size(s)
)
font_menu.add_cascade(label="字体大小", menu=size_menu)
self.menu.add_cascade(label="✏️ 字体设置", menu=font_menu)
# 样式设置
self.menu.add_command(label="🎨 文字颜色", command=self.choose_color)
self.menu.add_command(label="🖌️ 背景颜色", command=self.choose_bg_color)
# 透明度(优化显示)
alpha_menu = tk.Menu(self.menu, tearoff=0, bg="white")
alpha_levels = [
(0.3, "30% 透视"),
(0.5, "50% 半透明"),
(0.7, "70% 轻薄"),
(0.85, "85% 淡雅"),
(0.95, "95% 默认"),
(1.0, "100% 不透明")
]
for alpha_val, label_text in alpha_levels:
alpha_menu.add_command(
label=f" {label_text} {'✓' if abs(alpha_val - self.current_alpha) < 0.01 else ''}",
command=lambda a=alpha_val: self.set_alpha(a)
)
self.menu.add_cascade(label="🌫️ 背景透明度", menu=alpha_menu)
self.menu.add_separator()
# 编辑功能(绑定快捷键)
self.menu.add_command(label="𝗕 加粗 (Ctrl+B)", command=self.toggle_bold)
self.menu.add_command(label="↩️ 撤销 (Ctrl+Z)", command=lambda: self.text_area.edit_undo())
self.menu.add_command(label="↪️ 重做 (Ctrl+Y)", command=lambda: self.text_area.edit_redo())
self.menu.add_separator()
self.menu.add_command(label="全选 (Ctrl+A)", command=self.select_all)
self.menu.add_command(label="复制 (Ctrl+C)", command=self.copy_text)
self.menu.add_command(label="粘贴 (Ctrl+V)", command=self.paste_text)
self.menu.add_separator()
# 高级功能
self.menu.add_command(label="🔄 清空内容", command=self.clear_text, foreground="#E74C3C")
self.menu.add_command(label="🔐 修改关闭密码", command=self.change_password)
self.menu.add_command(label="ℹ️ 关于", command=self.show_about)
self.menu.add_separator()
# 退出(优化提示)
self.menu.add_command(label="🚪 退出程序 (Alt+F4/Ctrl+Q)", command=self.on_closing,
foreground="#C0392B")
# -------------------------- 核心功能:修复调整大小 --------------------------
def check_resize_cursor(self, event):
"""优化:扩大边缘检测区域(20px),覆盖所有边缘,光标样式更精准"""
width = self.main_container.winfo_width()
height = self.main_container.winfo_height()
x, y = event.x, event.y
edge_size = 20 # 扩大检测区域,提升易用性
# 检测各边缘
is_left = x < edge_size
is_right = width - x < edge_size
is_top = y < edge_size
is_bottom = height - y < edge_size
# 按优先级设置光标
if is_left and is_top:
self.main_container.config(cursor="size_nw_se")
elif is_left and is_bottom:
self.main_container.config(cursor="size_ne_sw")
elif is_right and is_top:
self.main_container.config(cursor="size_ne_sw")
elif is_right and is_bottom:
self.main_container.config(cursor="size_nw_se")
elif is_left or is_right:
self.main_container.config(cursor="sb_h_double_arrow")
elif is_top or is_bottom:
self.main_container.config(cursor="sb_v_double_arrow")
else:
self.main_container.config(cursor="arrow")
def start_resize(self, event):
"""修复:记录完整初始状态,明确边缘类型,避免计算偏差"""
width = self.main_container.winfo_width()
height = self.main_container.winfo_height()
x, y = event.x, event.y
edge_size = 20
# 仅在边缘区域启动调整
if not (x < edge_size or width - x < edge_size or y < edge_size or height - y < edge_size):
return
self.resizing = True
self._resize_start = {
"start_x": event.x_root, # 记录鼠标绝对位置,避免容器偏移影响
"start_y": event.y_root,
"init_width": self.root.winfo_width(),
"init_height": self.root.winfo_height(),
"init_x": self.root.winfo_x(), # 记录窗口初始位置,支持左上边缘调整
"init_y": self.root.winfo_y(),
"edge": self._get_resize_edge(x, y, width, height, edge_size)
}
def _get_resize_edge(self, x, y, width, height, edge_size):
"""辅助函数:判断调整的边缘类型"""
is_left = x < edge_size
is_right = width - x < edge_size
is_top = y < edge_size
is_bottom = height - y < edge_size
if is_left and is_top:
return "top_left"
elif is_left and is_bottom:
return "bottom_left"
elif is_right and is_top:
return "top_right"
elif is_right and is_bottom:
return "bottom_right"
elif is_left:
return "left"
elif is_right:
return "right"
elif is_top:
return "top"
elif is_bottom:
return "bottom"
return None
def do_resize(self, event):
"""修复:基于初始状态计算尺寸,支持所有边缘调整,限制最小尺寸"""
if not self.resizing or not hasattr(self, "_resize_start"):
return
start = self._resize_start
delta_x = event.x_root - start["start_x"]
delta_y = event.y_root - start["start_y"]
min_w, min_h = MIN_WIDTH, MIN_HEIGHT # 最小尺寸
# 根据边缘类型计算新尺寸和位置
if start["edge"] == "right":
new_w = max(min_w, start["init_width"] + delta_x)
self.root.geometry(f"{int(new_w)}x{self.root.winfo_height()}")
elif start["edge"] == "bottom":
new_h = max(min_h, start["init_height"] + delta_y)
self.root.geometry(f"{self.root.winfo_width()}x{int(new_h)}")
elif start["edge"] == "bottom_right":
new_w = max(min_w, start["init_width"] + delta_x)
new_h = max(min_h, start["init_height"] + delta_y)
self.root.geometry(f"{int(new_w)}x{int(new_h)}")
elif start["edge"] == "left":
new_w = max(min_w, start["init_width"] - delta_x)
new_x = start["init_x"] + delta_x
self.root.geometry(f"{int(new_w)}x{self.root.winfo_height()}+{int(new_x)}+{self.root.winfo_y()}")
elif start["edge"] == "top":
new_h = max(min_h, start["init_height"] - delta_y)
new_y = start["init_y"] + delta_y
self.root.geometry(f"{self.root.winfo_width()}x{int(new_h)}+{self.root.winfo_x()}+{int(new_y)}")
elif start["edge"] == "top_left":
new_w = max(min_w, start["init_width"] - delta_x)
new_h = max(min_h, start["init_height"] - delta_y)
new_x = start["init_x"] + delta_x
new_y = start["init_y"] + delta_y
self.root.geometry(f"{int(new_w)}x{int(new_h)}+{int(new_x)}+{int(new_y)}")
elif start["edge"] == "top_right":
new_w = max(min_w, start["init_width"] + delta_x)
new_h = max(min_h, start["init_height"] - delta_y)
new_y = start["init_y"] + delta_y
self.root.geometry(f"{int(new_w)}x{int(new_h)}+{self.root.winfo_x()}+{int(new_y)}")
elif start["edge"] == "bottom_left":
new_w = max(min_w, start["init_width"] - delta_x)
new_h = max(min_h, start["init_height"] + delta_y)
new_x = start["init_x"] + delta_x
self.root.geometry(f"{int(new_w)}x{int(new_h)}+{int(new_x)}+{self.root.winfo_y()}")
def _stop_resize(self, event):
"""新增:鼠标释放时重置调整状态,保存窗口配置"""
if self.resizing:
self.resizing = False
self.save_config() # 调整后保存尺寸和位置
# -------------------------- 移动窗口功能 --------------------------
def start_move_mode(self):
"""修复移动窗口逻辑:基于鼠标指针位置计算"""
self.moving = True
self.root.config(cursor="fleur")
# 记录初始偏移量
self._drag_data["x"] = self.root.winfo_pointerx() - self.root.winfo_x()
self._drag_data["y"] = self.root.winfo_pointery() - self.root.winfo_y()
# 绑定移动和停止事件
self.root.bind('<Motion>', self.do_move)
self.root.bind('<ButtonRelease-1>', self.stop_move_mode)
def do_move(self, event):
"""正确的窗口移动逻辑"""
if self.moving:
x = self.root.winfo_pointerx() - self._drag_data["x"]
y = self.root.winfo_pointery() - self._drag_data["y"]
self.root.geometry(f"+{x}+{y}")
def stop_move_mode(self, event):
"""停止移动模式(优化恢复逻辑)"""
self.moving = False
self.root.config(cursor="arrow")
self.root.unbind('<Motion>')
self.root.unbind('<ButtonRelease-1>')
self.save_config() # 移动后保存位置
def start_alt_move(self, event):
self._drag_data = {"x": event.x, "y": event.y, "moving": True}
def do_alt_move(self, event):
if hasattr(self, '_drag_data') and self._drag_data.get("moving"):
x = self.root.winfo_x() + (event.x - self._drag_data["x"])
y = self.root.winfo_y() + (event.y - self._drag_data["y"])
self.root.geometry(f"+{x}+{y}")
def stop_alt_move(self, event):
if hasattr(self, '_drag_data'):
self._drag_data["moving"] = False
# -------------------------- 新增功能 --------------------------
def minimize_window(self):
"""最小化窗口(无边框窗口专用)"""
self.root.overrideredirect(False) # 临时恢复窗口装饰
self.root.iconify() # 最小化
# 恢复无边框(最小化还原后)
self.root.bind('<Map>', lambda e: self.root.overrideredirect(True) if e.widget == self.root else None)
def set_font_family(self, family):
"""新增:设置字体家族"""
self.current_font_family = family
self.update_font()
self.save_config()
self.create_context_menu() # 更新菜单勾选状态
def change_password(self):
"""新增:修改关闭密码"""
old_pwd = simpledialog.askstring("验证旧密码", "请输入当前关闭密码:", show="*", parent=self.root)
if old_pwd != self.close_password:
messagebox.showerror("错误", "旧密码不正确!", parent=self.root)
return
new_pwd = simpledialog.askstring("设置新密码", "请输入新的关闭密码(至少4位):", show="*", parent=self.root)
if not new_pwd or len(new_pwd) < 4:
messagebox.warning("提示", "密码长度不能少于4位!", parent=self.root)
return
confirm_pwd = simpledialog.askstring("确认新密码", "请再次输入新密码:", show="*", parent=self.root)
if new_pwd == confirm_pwd:
self.close_password = new_pwd
self.save_password()
messagebox.showinfo("成功", "密码修改成功!", parent=self.root)
else:
messagebox.showerror("错误", "两次输入的密码不一致!", parent=self.root)
def load_password(self):
"""加载自定义密码"""
try:
if os.path.exists(PASSWORD_FILE):
with open(PASSWORD_FILE, 'r', encoding='utf-8') as f:
return json.load(f).get("password", DEFAULT_PASSWORD)
return DEFAULT_PASSWORD
except:
return DEFAULT_PASSWORD
def save_password(self):
"""保存密码到文件"""
try:
with open(PASSWORD_FILE, 'w', encoding='utf-8') as f:
json.dump({"password": self.close_password}, f)
except Exception as e:
messagebox.showerror("错误", f"保存密码失败:{str(e)}", parent=self.root)
def show_about(self):
"""新增:关于窗口"""
about_window = tk.Toplevel(self.root)
about_window.title("关于极简便签")
about_window.geometry("300x200+%d+%d" % (self.root.winfo_x() + 50, self.root.winfo_y() + 50))
about_window.resizable(False, False)
about_window.attributes('-topmost', True)
tk.Label(about_window, text="极简便签 v1.0", font=("Microsoft YaHei", 16)).pack(pady=20)
tk.Label(about_window, text="基于Python Tkinter开发").pack()
tk.Label(about_window, text="✨ 轻量 · 简洁 · 易用").pack(pady=5)
tk.Button(about_window, text="确定", command=about_window.destroy, width=10).pack(pady=20)
# -------------------------- 原有功能优化 --------------------------
def toggle_topmost(self):
"""优化:保存置顶状态到配置"""
self.is_topmost = self.topmost_var.get()
self.root.attributes('-topmost', self.is_topmost)
self.save_config()
def enter_pure_mode(self):
"""优化纯净模式:鼠标移动也退出"""
self.main_container.config(bg=self.current_bg_color)
self.text_area.config(padx=25, pady=25)
# 鼠标移动时退出纯净模式
self.root.bind('<Motion>', self.exit_pure_mode_on_move)
def exit_pure_mode_on_move(self, event):
"""鼠标移动退出纯净模式"""
self.exit_pure_mode()
self.root.unbind('<Motion>')
def exit_pure_mode(self):
"""优化退出纯净模式逻辑"""
self.main_container.config(bg="#CCCCCC")
self.text_area.config(padx=20, pady=20)
self.schedule_pure_mode()
def schedule_pure_mode(self):
if self.hide_timer:
self.root.after_cancel(self.hide_timer)
self.hide_timer = self.root.after(PURE_MODE_DELAY, self.enter_pure_mode)
def schedule_auto_save(self):
"""优化自动保存:添加成功提示(可选)"""
try:
self.save_content()
self.save_config()
except Exception as e:
messagebox.warning("提示", f"自动保存失败:{str(e)}", parent=self.root)
finally:
self.root.after(AUTO_SAVE_INTERVAL, self.schedule_auto_save)
def set_font_size(self, size):
self.current_font_size = size
self.update_font()
self.save_config()
self.create_context_menu()
def update_font(self):
new_font = font.Font(family=self.current_font_family, size=self.current_font_size)
self.text_area.config(
font=new_font,
fg=self.current_font_color,
insertbackground=self.current_font_color
)
def choose_color(self):
color = colorchooser.askcolor(color=self.current_font_color, title="选择文字颜色")
if color[1]:
self.current_font_color = color[1]
self.update_font()
self.save_config()
def choose_bg_color(self):
color = colorchooser.askcolor(color=self.current_bg_color, title="选择背景颜色")
if color[1]:
self.current_bg_color = color[1]
self.main_frame.config(bg=self.current_bg_color)
self.text_area.config(bg=self.current_bg_color)
self.save_config()
def toggle_bold(self):
try:
if self.text_area.tag_ranges("sel"):
current_tags = self.text_area.tag_names("sel.first")
if "bold" in current_tags:
self.text_area.tag_remove("bold", "sel.first", "sel.last")
else:
bold_font = font.Font(self.text_area, self.text_area.cget("font"))
bold_font.configure(weight="bold")
self.text_area.tag_configure("bold", font=bold_font)
self.text_area.tag_add("bold", "sel.first", "sel.last")
except tk.TclError:
pass
def show_menu(self, event):
if not self.resizing:
self.menu.post(event.x_root, event.y_root)
self.resizing = False
def set_alpha(self, alpha_val):
self.current_alpha = alpha_val
self.root.attributes('-alpha', alpha_val)
self.save_config()
self.create_context_menu()
def on_closing(self):
"""优化关闭逻辑:更友好的提示"""
if not messagebox.askyesno("确认退出", "确定要退出极简便签吗?\n(内容会自动保存)", parent=self.root):
return
password = simpledialog.askstring(
"安全验证",
"请输入关闭密码:",
parent=self.root,
show="*"
)
if password is None:
return
elif password == self.close_password:
self.save_content()
self.save_config()
self.root.destroy()
else:
messagebox.showerror("密码错误", f"密码不正确!\n\n当前默认密码:{DEFAULT_PASSWORD}(若未修改)",
parent=self.root)
def bind_events(self):
"""修复:补充鼠标释放事件,重置调整状态,避免冲突"""
# 基础交互
self.text_area.bind('<Alt-Button-1>', self.start_alt_move)
self.text_area.bind('<Alt-B1-Motion>', self.do_alt_move)
self.text_area.bind('<Alt-ButtonRelease-1>', self.stop_alt_move)
self.text_area.bind("<Button-3>", self.show_menu)
self.text_area.bind("<Button-1>", self.on_text_click)
self.text_area.bind("<Key>", self.on_text_input)
self.text_area.bind("<Control-MouseWheel>", self.on_mouse_wheel)
# 快捷键绑定
self.root.bind('<Control-b>', lambda e: self.toggle_bold())
self.root.bind('<Control-a>', lambda e: self.select_all())
self.root.bind('<Control-c>', lambda e: self.copy_text())
self.root.bind('<Control-v>', lambda e: self.paste_text())
self.root.bind('<Control-z>', lambda e: self.text_area.edit_undo())
self.root.bind('<Control-y>', lambda e: self.text_area.edit_redo())
self.root.bind('<Control-q>', lambda e: self.on_closing())
self.root.bind('<Alt-F4>', lambda e: self.on_closing())
# 调整大小(核心修复)
self.main_container.bind('<Motion>', self.check_resize_cursor)
self.main_container.bind('<Button-1>', self.start_resize)
self.main_container.bind('<B1-Motion>', self.do_resize)
self.main_container.bind('<ButtonRelease-1>', self._stop_resize)
def on_text_input(self, event):
"""输入文字时移除初始提示"""
if self.text_area.tag_ranges("hint"):
self.text_area.delete("hint.first", "hint.last")
self.text_area.tag_remove("hint", "1.0", tk.END)
self.schedule_pure_mode()
def copy_text(self):
self.text_area.event_generate("<<Copy>>")
def paste_text(self):
self.text_area.event_generate("<<Paste>>")
def select_all(self):
self.text_area.tag_add("sel", "1.0", tk.END)
def clear_text(self):
if messagebox.askyesno("确认清空", "确定要清空所有内容吗?\n此操作不可撤销!", parent=self.root):
self.text_area.delete("1.0", tk.END)
self.save_content()
def save_content(self):
try:
with open(CONTENT_FILE, 'w', encoding='utf-8') as f:
content = self.text_area.get("1.0", tk.END)
f.write(content)
except Exception as e:
messagebox.showerror("错误", f"保存内容失败:{str(e)}", parent=self.root)
def load_content(self):
if os.path.exists(CONTENT_FILE):
try:
with open(CONTENT_FILE, 'r', encoding='utf-8') as f:
content = f.read()
self.text_area.delete("1.0", tk.END)
self.text_area.insert("1.0", content)
except Exception as e:
messagebox.showerror("错误", f"加载内容失败:{str(e)}", parent=self.root)
def save_config(self):
config = {
'font_family': self.current_font_family,
'font_size': self.current_font_size,
'font_color': self.current_font_color,
'bg_color': self.current_bg_color,
'alpha': self.current_alpha,
'geometry': self.root.geometry(),
'is_topmost': self.is_topmost
}
try:
with open(CONFIG_FILE, 'w', encoding='utf-8') as f:
json.dump(config, f, ensure_ascii=False, indent=2)
except Exception as e:
messagebox.showerror("错误", f"保存配置失败:{str(e)}", parent=self.root)
def load_config(self):
if os.path.exists(CONFIG_FILE):
try:
with open(CONFIG_FILE, 'r', encoding='utf-8') as f:
config = json.load(f)
self.current_font_family = config.get('font_family', self.current_font_family)
self.current_font_size = config.get('font_size', self.current_font_size)
self.current_font_color = config.get('font_color', self.current_font_color)
self.current_bg_color = config.get('bg_color', self.current_bg_color)
self.current_alpha = config.get('alpha', self.current_alpha)
self.is_topmost = config.get('is_topmost', self.is_topmost)
if 'geometry' in config:
self.root.geometry(config['geometry'])
except Exception as e:
messagebox.warning("提示", f"加载配置失败,使用默认设置:{str(e)}", parent=self.root)
def on_text_click(self, event=None):
current_padding = int(self.text_area.cget("padx"))
if current_padding > 20:
self.exit_pure_mode()
else:
self.schedule_pure_mode()
def on_mouse_wheel(self, event):
if event.delta > 0:
new_size = min(self.current_font_size + 1, 72)
else:
new_size = max(self.current_font_size - 1, 8)
if new_size != self.current_font_size:
self.current_font_size = new_size
self.update_font()
self.save_config()
self.create_context_menu()
if __name__ == "__main__":
root = tk.Tk()
app = BorderlessStickyNote(root)
root.mainloop()以上就是基于Python编写一个win10桌面便签工具的详细内容,更多关于Python桌面便签工具的资料请关注脚本之家其它相关文章!
