tkinter笔记002-防止窗口大小调整

本文介绍如何使用Python的Tkinter库创建一个不可调整大小的GUI窗口。通过设置win.resizable(0,0),可以禁止用户调整窗口的尺寸。

python在创建出窗口后窗口的大小可以拖动放大、缩小

 

【阻止Python GUI的大小调整】

1 import tkinter as tk
2 win=tk.Tk()
3 
4 win.title('Python Gui')
5 
6 win.resizable(0,0) #阻止Python GUI的大小调整
7 
8 win.mainloop()
resizable()是TK()中的一个方法,通过设置(0,0)来阻止Python GUI的大小调整

转载于:https://www.cnblogs.com/mathpro/p/8052266.html

# -*- coding: utf-8 -*- import tkinter as tk from tkinter import ttk, messagebox import json import os from datetime import datetime, timedelta import threading import sys class SmartStickyNote: def __init__(self, root): self.root = root self.root.title("智能便签") # 初始化设置 self.settings = { 'view_mode': 'all', # 视图模式: all/pinned/completed 'theme': 'light', # 主题: light/dark 'opacity': 0.9, # 窗口不透明度: 0.0-1.0 'font_size': 10, # 默认字体大小 'sort_by': 'created' # 排序方式: created/modified/urgency } # 初始化颜色方案 self.init_colors() # 初始化样式 self.setup_styles() # 初始化数据 self.notes = [] self.recycle_bin = [] # 创建UI元素 self.create_widgets() # 加载保存的数据 self.load_data() # 渲染笔记列表 self.render_notes() # 启动后台任务 self.start_background_tasks() def init_colors(self): """初始化颜色方案""" # 浅色主题 self.bg_color = '#FFFFFF' # 背景色 self.secondary_color = '#F5F5F5' # 次要背景色 self.text_color = '#000000' # 文本颜色 self.accent_color = '#42A5F5' # 强调色 # 可以根据主题切换颜色 if hasattr(self, 'settings') and self.settings.get('theme') == 'dark': self.bg_color = '#212121' self.secondary_color = '#424242' self.text_color = '#FFFFFF' self.accent_color = '#BB86FC' def setup_styles(self): """配置自定义样式""" style = ttk.Style() # 基础样式 style.theme_use('clam') # 使用一个支持样式修改的主题 # 紧急程度按钮样式 urgency_colors = { 0: ('#E8F5E9', '低'), # 绿色 1: ('#E3F2FD', '普通'), # 蓝色 2: ('#FFE0B2', '重要'), # 橙色 3: ('#FFCDD2', '紧急') # 红色 } for level, (color, text) in urgency_colors.items(): style.configure( f'Urgency.TButton.{level}', background=color, foreground='black', font=('Microsoft YaHei', 8), padding=2, borderwidth=1, relief='raised' ) style.map( f'Urgency.TButton.{level}', background=[('active', color), ('disabled', '#F5F5F5')], relief=[('pressed', 'sunken'), ('!pressed', 'raised')] ) # 框架样式 style.configure('Note.TFrame', background=self.bg_color, bordercolor='#E0E0E0', lightcolor='#F5F5F5', darkcolor='#E0E0E0') style.configure('Pinned.TFrame', background='#FFF9C4', bordercolor='#FFD54F') style.configure('Completed.TFrame', background='#E8F5E9', bordercolor='#A5D6A7') style.configure('Deleted.TFrame', background='#F5F5F5', bordercolor='#BDBDBD') style.configure('UrgentFlash.TFrame', background='#FFEBEE', bordercolor='#EF9A9A') # 按钮样式 style.configure('Accent.TButton', font=('Microsoft YaHei', 9, 'bold'), foreground='#FFFFFF', background='#42A5F5', padding=5) style.map('Accent.TButton', background=[('active', '#1E88E5'), ('disabled', '#BBDEFB')]) # 标签样式 style.configure('Title.TLabel', font=('Microsoft YaHei', 10, 'bold'), foreground='#212121') style.configure('Subtitle.TLabel', font=('Microsoft YaHei', 8), foreground='#616161') def load_data(self): """加载保存的数据""" try: if os.path.exists(self.data_file): with open(self.data_file, 'r', encoding='utf-8') as f: data = json.load(f) self.notes = data.get('notes', []) self.settings = {**self.settings, **data.get('settings', {})} if os.path.exists(self.recycle_file): with open(self.recycle_file, 'r', encoding='utf-8') as f: self.recycle_bin = json.load(f) except Exception as e: messagebox.showerror("错误", f"加载数据失败: {str(e)}") try: with open('notes_data.json', 'r') as f: data = json.load(f) self.notes = data.get('notes', []) self.recycle_bin = data.get('recycle_bin', []) # 合并设置,保留默认值 self.settings = {**self.settings, **data.get('settings', {})} except FileNotFoundError: # 文件不存在时使用默认设置 pass def save_data(self): """保存数据到文件""" data = { 'notes': self.notes, 'recycle_bin': self.recycle_bin, 'settings': self.settings } try: with open(self.data_file, 'w', encoding='utf-8') as f: json.dump(data, f, ensure_ascii=False, indent=2) with open(self.recycle_file, 'w', encoding='utf-8') as f: json.dump(self.recycle_bin, f, ensure_ascii=False, indent=2) except Exception as e: messagebox.showerror("错误", f"保存数据失败: {str(e)}") def create_widgets(self): """创建界面组件""" # 主框架 self.main_frame = ttk.Frame(self.root) self.main_frame.pack(fill=tk.BOTH, expand=True, padx=5, pady=5) # 工具栏 self.create_toolbar() # 笔记列表容器 self.create_notes_list() # 新建笔记表单 (初始隐藏) self.create_new_note_form() # 设置窗口透明度 self.root.attributes('-alpha', self.settings['opacity']) # 设置窗口置顶 self.root.attributes('-topmost', self.settings['always_on_top']) def create_toolbar(self): """创建工具栏""" toolbar = ttk.Frame(self.root, padding=5) toolbar.pack(fill=tk.X) # 不透明度控制 opacity_frame = ttk.Frame(toolbar) opacity_frame.pack(side=tk.RIGHT, padx=5) ttk.Label(opacity_frame, text="不透明度:").pack(side=tk.LEFT) # 使用 get() 方法获取 opacity 设置,提供默认值 self.opacity = tk.DoubleVar(value=self.settings.get('opacity', 0.9)) opacity_slider = ttk.Scale( opacity_frame, from_=0.3, to=1.0, variable=self.opacity, command=lambda v: self.root.attributes('-alpha', float(v)) ) opacity_slider.pack(side=tk.LEFT, padx=5) # 搜索框 search_frame = ttk.Frame(toolbar) search_frame.pack(side=tk.LEFT, padx=5, fill=tk.X, expand=True) self.search_var = tk.StringVar() search_entry = ttk.Entry( search_frame, textvariable=self.search_var, style='Search.TEntry' ) search_entry.pack(side=tk.LEFT, fill=tk.X, expand=True) search_entry.bind('<KeyRelease>', lambda e: self.render_notes()) search_btn = ttk.Button( search_frame, text="🔍", width=3, command=self.show_advanced_search ) search_btn.pack(side=tk.LEFT, padx=(2, 0)) # 视图模式选择 self.view_mode = tk.StringVar(value=self.settings['view_mode']) view_options = ttk.Combobox( toolbar, textvariable=self.view_mode, values=['active', 'pinned', 'all'], width=8, state='readonly' ) view_options.pack(side=tk.LEFT, padx=2) view_options.bind('<<ComboboxSelected>>', self.change_view_mode) # 历史记录按钮 history_btn = ttk.Button( toolbar, text="📅", width=3, command=lambda: self.show_history('week') ) history_btn.pack(side=tk.LEFT, padx=2) # 新建按钮 new_btn = ttk.Button( toolbar, text="+ 新建", style='Accent.TButton', command=self.show_new_note_form ) new_btn.pack(side=tk.RIGHT, padx=2) # 透明度滑块 self.opacity = tk.DoubleVar(value=self.settings['opacity']) opacity_slider = ttk.Scale( toolbar, from_=0.5, to=1.0, variable=self.opacity, command=self.change_opacity, length=80 ) opacity_slider.pack(side=tk.RIGHT, padx=5) ttk.Label(toolbar, text="透明度:").pack(side=tk.RIGHT) # 置顶按钮 self.topmost_btn = ttk.Button( toolbar, text="📌" if self.settings['always_on_top'] else "📋", width=3, command=self.toggle_topmost ) self.topmost_btn.pack(side=tk.RIGHT, padx=2) def create_notes_list(self): """创建笔记列表区域""" # 笔记列表容器 self.notes_canvas = tk.Canvas( self.main_frame, bg=self.bg_color, highlightthickness=0 ) self.notes_canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) # 滚动条 scrollbar = ttk.Scrollbar( self.main_frame, orient=tk.VERTICAL, command=self.notes_canvas.yview ) scrollbar.pack(side=tk.RIGHT, fill=tk.Y) self.notes_canvas.configure(yscrollcommand=scrollbar.set) self.notes_canvas.bind('<Configure>', lambda e: self.notes_canvas.configure( scrollregion=self.notes_canvas.bbox("all") )) # 笔记框架容器 self.notes_frame = ttk.Frame(self.notes_canvas) self.notes_canvas.create_window((0, 0), window=self.notes_frame, anchor="nw") def create_new_note_form(self): """创建新建笔记表单""" self.new_note_frame = ttk.LabelFrame( self.main_frame, text="新建笔记", padding=10 ) # 标题输入框 ttk.Label(self.new_note_frame, text="标题:").pack(anchor=tk.W, padx=5, pady=2) self.note_title = ttk.Entry(self.new_note_frame) self.note_title.pack(fill=tk.X, padx=5, pady=2) # 内容文本框 ttk.Label(self.new_note_frame, text="内容:").pack(anchor=tk.W, padx=5, pady=2) self.note_content = tk.Text( self.new_note_frame, height=5, wrap=tk.WORD, bg=self.secondary_color, fg=self.text_color, insertbackground=self.text_color, relief=tk.FLAT, padx=5, pady=5 ) self.note_content.pack(fill=tk.BOTH, expand=True, padx=5, pady=2) # 紧急程度选择 urgency_frame = ttk.Frame(self.new_note_frame) urgency_frame.pack(fill=tk.X, padx=5, pady=5) ttk.Label(urgency_frame, text="紧急程度:").pack(side=tk.LEFT) self.urgency = tk.IntVar(value=1) # 默认普通 urgency_levels = [ ("低", 0), ("普通", 1), ("重要", 2), ("紧急", 3) ] for text, level in urgency_levels: btn = ttk.Radiobutton( urgency_frame, text=text, variable=self.urgency, value=level ) btn.pack(side=tk.LEFT, padx=2) # 按钮区域 btn_frame = ttk.Frame(self.new_note_frame) btn_frame.pack(fill=tk.X, padx=5, pady=5) ttk.Button( btn_frame, text="取消", command=self.hide_new_note_form ).pack(side=tk.RIGHT, padx=2) ttk.Button( btn_frame, text="保存", style='Accent.TButton', command=self.save_new_note ).pack(side=tk.RIGHT, padx=2) def start_timers(self): """启动定时检查任务""" self.root.after(1000, self.check_note_status) self.root.after(600000, self.check_note_status) # 每10分钟检查一次 self.root.after(3600000, self.check_urgent_tasks) # 每小时检查紧急任务 self.root.after(86400000, self.empty_recycle_bin) # 每天检查回收站 def render_notes(self): """渲染笔记列表""" for widget in self.notes_frame.winfo_children(): widget.destroy() filtered_notes = self.filter_notes() if not filtered_notes: ttk.Label( self.notes_frame, text="暂无笔记" if self.view_mode.get() != 'pinned' else "无固定笔记", font=('Microsoft YaHei', 10, 'italic') ).pack(pady=20) return filtered_notes.sort(key=lambda x: ( -x.get('pinned', False), -x['urgency'], x['created_at'] )) for note in filtered_notes: self.create_note_widget(note) self.notes_frame.update_idletasks() self.notes_canvas.config(scrollregion=self.notes_canvas.bbox("all")) def filter_notes(self): """根据视图模式和搜索条件过滤笔记""" view_mode = self.view_mode.get() search_text = self.search_var.get().lower() filtered = [] for note in self.notes: if note['status'] == 'completed' and view_mode != 'all': continue if view_mode == 'pinned' and not note.get('pinned', False): continue if search_text and search_text not in note['title'].lower() and search_text not in note['content'].lower(): continue filtered.append(note) return filtered def create_note_widget(self, note): """创建笔记组件""" urgency_colors = { 0: ('#E8F5E9', '低'), # 绿色 1: ('#E3F2FD', '普通'), # 蓝色 2: ('#FFE0B2', '重要'), # 橙色 3: ('#FFCDD2', '紧急') # 红色 } status_styles = { 'pending': ('○', '#FFFFFF'), 'ongoing': ('◔', '#F8F8F8'), 'completed': ('✓', '#E8F5E9') } status_icon, bg_color = status_styles.get(note['status'], ('?', '#FFFFFF')) urgency_color, urgency_text = urgency_colors.get(note['urgency'], ('#E3F2FD', '普通')) frame_style = 'Pinned.TFrame' if note.get('pinned', False) else 'Note.TFrame' if note['status'] == 'completed': frame_style = 'Completed.TFrame' frame = ttk.Frame( self.notes_frame, borderwidth=2, relief=tk.RAISED, padding=(10, 8), style=frame_style ) frame.pack(fill=tk.X, pady=5, padx=2) # 标题区域 title_frame = ttk.Frame(frame) title_frame.pack(fill=tk.X, pady=(0, 5)) # 状态和紧急程度 status_label = ttk.Label( title_frame, text=status_icon, font=('Arial', 12), width=2 ) status_label.pack(side=tk.LEFT, padx=(0, 5)) urgency_label = ttk.Label( title_frame, text=urgency_text, font=('Microsoft YaHei', 8, 'bold'), background=urgency_color, foreground='black', padding=(3, 0), borderwidth=1, relief=tk.SOLID ) urgency_label.pack(side=tk.LEFT, padx=(0, 5)) # 笔记标题 title_label = ttk.Label( title_frame, text=note['title'] or '无标题', font=('Microsoft YaHei', 10, 'bold'), anchor=tk.W ) title_label.pack(side=tk.LEFT, fill=tk.X, expand=True) # 内容区域 content_frame = ttk.Frame(frame) content_frame.pack(fill=tk.X, pady=(0, 8)) # 动态高度的文本框 content = tk.Text( content_frame, wrap=tk.WORD, font=('Microsoft YaHei', 9), background=bg_color, foreground=self.text_color, borderwidth=0, highlightthickness=0, padx=5, pady=3, height=1 ) content.insert(tk.END, note['content']) content.config(state=tk.DISABLED) content.pack(fill=tk.BOTH, expand=True) # 动态调整高度 line_count = content.count('1.0', 'end', 'displaylines')[0] content.configure(height=min(max(line_count, 1), 10)) # 元信息区域 meta_frame = ttk.Frame(frame) meta_frame.pack(fill=tk.X) # 创建时间 created_time = datetime.fromisoformat(note['created_at']).strftime('%m/%d %H:%M') ttk.Label( meta_frame, text=f"🕒 {created_time}", font=('TkDefaultFont', 8), foreground='#666666' ).pack(side=tk.LEFT) # 操作按钮区域 btn_frame = ttk.Frame(frame) btn_frame.pack(fill=tk.X, pady=(5, 0)) # 左侧按钮组 - 紧急程度调整 urgency_frame = ttk.Frame(btn_frame) urgency_frame.pack(side=tk.LEFT, fill=tk.X, expand=True) for level, (color, text) in urgency_colors.items(): btn = ttk.Button( urgency_frame, text=text, style=f'Urgency.TButton.{level}', command=lambda l=level, nid=note['id']: self.change_urgency(nid, l) ) btn.pack(side=tk.LEFT, padx=1) # 右侧按钮组 - 操作按钮 action_frame = ttk.Frame(btn_frame) action_frame.pack(side=tk.RIGHT) # 固定按钮 pin_btn = ttk.Button( action_frame, text="📍" if note.get('pinned', False) else "📌", width=3, command=lambda nid=note['id']: self.toggle_pin(nid) ) pin_btn.pack(side=tk.LEFT, padx=2) # 状态切换按钮 status_btn = ttk.Button( action_frame, text="✓" if note['status'] != 'completed' else "↩", width=3, command=lambda nid=note['id']: self.toggle_note_status(nid) ) status_btn.pack(side=tk.LEFT, padx=2) # 删除按钮 del_btn = ttk.Button( action_frame, text="🗑", width=3, command=lambda nid=note['id']: self.delete_note(nid) ) del_btn.pack(side=tk.LEFT, padx=2) # 编辑按钮 edit_btn = ttk.Button( action_frame, text="✏️", width=3, command=lambda nid=note['id']: self.edit_note(nid) ) edit_btn.pack(side=tk.LEFT, padx=2) # 为笔记组件添加ID标识 frame.note_id = note['id'] def edit_note(self, note_id): """编辑现有笔记""" note = next((n for n in self.notes if n['id'] == note_id), None) if not note: return # 创建编辑窗口 edit_window = tk.Toplevel(self.root) edit_window.title("编辑笔记") edit_window.geometry("400x500") # 标题输入框 ttk.Label(edit_window, text="标题:").pack(anchor=tk.W, padx=5, pady=2) title_entry = ttk.Entry(edit_window) title_entry.insert(0, note['title']) title_entry.pack(fill=tk.X, padx=5, pady=2) # 内容文本框 ttk.Label(edit_window, text="内容:").pack(anchor=tk.W, padx=5, pady=2) content_text = tk.Text( edit_window, height=10, wrap=tk.WORD, bg=self.secondary_color, fg=self.text_color, insertbackground=self.text_color, padx=5, pady=5 ) content_text.insert(tk.END, note['content']) content_text.pack(fill=tk.BOTH, expand=True, padx=5, pady=2) # 紧急程度选择 urgency_frame = ttk.Frame(edit_window) urgency_frame.pack(fill=tk.X, padx=5, pady=5) ttk.Label(urgency_frame, text="紧急程度:").pack(side=tk.LEFT) urgency_var = tk.IntVar(value=note['urgency']) urgency_levels = [ ("低", 0), ("普通", 1), ("重要", 2), ("紧急", 3) ] for text, level in urgency_levels: btn = ttk.Radiobutton( urgency_frame, text=text, variable=urgency_var, value=level ) btn.pack(side=tk.LEFT, padx=2) # 按钮区域 btn_frame = ttk.Frame(edit_window) btn_frame.pack(fill=tk.X, padx=5, pady=5) def save_changes(): """保存编辑内容""" note['title'] = title_entry.get().strip() note['content'] = content_text.get("1.0", tk.END).strip() note['urgency'] = urgency_var.get() note['modified_at'] = datetime.now().isoformat() self.save_data() self.render_notes() edit_window.destroy() messagebox.showinfo("提示", "笔记已更新") ttk.Button( btn_frame, text="保存", style='Accent.TButton', command=save_changes ).pack(side=tk.RIGHT, padx=2) ttk.Button( btn_frame, text="取消", command=edit_window.destroy ).pack(side=tk.RIGHT, padx=2) def delete_note(self, note_id): """删除笔记到回收站""" if not messagebox.askyesno("确认", "确定要删除这个笔记吗?"): return for i, note in enumerate(self.notes): if note['id'] == note_id: deleted_note = self.notes.pop(i) deleted_note['deleted_at'] = datetime.now().isoformat() self.recycle_bin.append(deleted_note) break self.save_data() self.render_notes() messagebox.showinfo("提示", "笔记已移到回收站") def show_new_note_form(self): """显示新建笔记表单""" self.new_note_frame.pack(fill=tk.BOTH, expand=True, pady=5) self.note_title.focus() def hide_new_note_form(self): """隐藏新建笔记表单""" self.new_note_frame.pack_forget() self.note_title.delete(0, tk.END) self.note_content.delete('1.0', tk.END) self.urgency.set(1) # 重置为普通 def save_new_note(self): """保存新笔记""" title = self.note_title.get().strip() content = self.note_content.get('1.0', tk.END).strip() urgency = self.urgency.get() if not title and not content: messagebox.showwarning("提示", "请输入标题或内容") return new_note = { 'id': str(datetime.now().timestamp()), 'title': title or "无标题", 'content': content, 'urgency': urgency, 'status': 'pending', 'created_at': datetime.now().isoformat(), 'modified_at': None, 'completed_at': None, 'pinned': False } self.notes.append(new_note) self.save_data() self.hide_new_note_form() self.render_notes() messagebox.showinfo("提示", "笔记已保存") def toggle_pin(self, note_id): """切换固定状态""" for note in self.notes: if note['id'] == note_id: note['pinned'] = not note.get('pinned', False) break self.save_data() self.render_notes() def toggle_note_status(self, note_id): """切换笔记完成状态""" for note in self.notes: if note['id'] == note_id: if note['status'] == 'completed': note['status'] = 'pending' note['completed_at'] = None else: note['status'] = 'completed' note['completed_at'] = datetime.now().isoformat() break self.save_data() self.render_notes() def change_urgency(self, note_id, urgency_level): """修改笔记紧急程度""" for note in self.notes: if note['id'] == note_id: note['urgency'] = urgency_level break self.save_data() self.render_notes() def change_view_mode(self, event=None): """改变视图模式""" self.settings['view_mode'] = self.view_mode.get() self.save_data() self.render_notes() def show_history(self, period='week'): """显示历史记录窗口""" history_window = tk.Toplevel(self.root) history_window.title(f"{period.capitalize()}历史记录") history_window.geometry("500x600") # 创建时间范围 now = datetime.now() if period == 'week': cutoff = now - timedelta(weeks=1) elif period == 'month': cutoff = now - timedelta(days=30) elif period == 'year': cutoff = now - timedelta(days=365) else: cutoff = now - timedelta(weeks=1) # 过滤历史笔记 history_notes = [ n for n in self.notes + self.recycle_bin if n.get('completed_at') or n.get('deleted_at') ] # 按时间排序 history_notes.sort(key=lambda x: x.get('completed_at') or x.get('deleted_at'), reverse=True) # 创建容器 canvas = tk.Canvas(history_window, bg=self.bg_color, highlightthickness=0) canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) scrollbar = ttk.Scrollbar(history_window, orient=tk.VERTICAL, command=canvas.yview) scrollbar.pack(side=tk.RIGHT, fill=tk.Y) canvas.configure(yscrollcommand=scrollbar.set) canvas.bind('<Configure>', lambda e: canvas.configure(scrollregion=canvas.bbox("all"))) history_frame = ttk.Frame(canvas) canvas.create_window((0, 0), window=history_frame, anchor="nw") # 时间段选择 period_frame = ttk.Frame(history_window) period_frame.pack(fill=tk.X, padx=5, pady=5) ttk.Button( period_frame, text="最近一周", command=lambda: self.update_history_view(history_window, 'week') ).pack(side=tk.LEFT, padx=2) ttk.Button( period_frame, text="最近一月", command=lambda: self.update_history_view(history_window, 'month') ).pack(side=tk.LEFT, padx=2) ttk.Button( period_frame, text="最近一年", command=lambda: self.update_history_view(history_window, 'year') ).pack(side=tk.LEFT, padx=2) # 渲染历史笔记 for note in history_notes: self.create_history_note_widget(history_frame, note) def create_history_note_widget(self, parent, note): """创建历史笔记组件""" # 样式配置 bg_color = '#F0F0F0' if note.get('deleted_at') else '#E8F5E9' border_color = '#D0D0D0' if note.get('deleted_at') else '#C8E6C9' frame = ttk.Frame( parent, borderwidth=2, relief=tk.RAISED, padding=5, style='Deleted.TFrame' if note.get('deleted_at') else 'Completed.TFrame' ) frame.pack(fill=tk.X, pady=2, padx=2) # 标题区域 title_frame = ttk.Frame(frame) title_frame.pack(fill=tk.X) # 状态图标 status_icon = "🗑" if note.get('deleted_at') else "✓" ttk.Label( title_frame, text=status_icon, font=('Arial', 12) ).pack(side=tk.LEFT, padx=(0, 5)) # 笔记标题 ttk.Label( title_frame, text=note['title'] or "无标题", font=('Microsoft YaHei', 10, 'bold'), anchor=tk.W ).pack(side=tk.LEFT, fill=tk.X, expand=True) # 时间信息 time_frame = ttk.Frame(frame) time_frame.pack(fill=tk.X, pady=(2, 0)) created_time = datetime.fromisoformat(note['created_at']).strftime('%Y/%m/%d %H:%M') ttk.Label( time_frame, text=f"创建: {created_time}", font=('TkDefaultFont', 8), foreground='#666666' ).pack(side=tk.LEFT) if note.get('completed_at'): completed_time = datetime.fromisoformat(note['completed_at']).strftime('%Y/%m/%d %H:%M') ttk.Label( time_frame, text=f"完成: {completed_time}", font=('TkDefaultFont', 8), foreground='#666666' ).pack(side=tk.LEFT, padx=(10, 0)) if note.get('deleted_at'): deleted_time = datetime.fromisoformat(note['deleted_at']).strftime('%Y/%m/%d %H:%M') ttk.Label( time_frame, text=f"删除: {deleted_time}", font=('TkDefaultFont', 8), foreground='#666666' ).pack(side=tk.LEFT, padx=(10, 0)) # 内容预览 content_preview = note['content'][:100] + "..." if len(note['content']) > 100 else note['content'] ttk.Label( frame, text=content_preview, font=('Microsoft YaHei', 9), wraplength=400, anchor=tk.W ).pack(fill=tk.X, pady=(5, 0)) # 恢复按钮(仅回收站项目) if note.get('deleted_at'): btn_frame = ttk.Frame(frame) btn_frame.pack(fill=tk.X, pady=(5, 0)) ttk.Button( btn_frame, text="恢复", command=lambda nid=note['id']: self.restore_note(nid) ).pack(side=tk.LEFT) ttk.Button( btn_frame, text="永久删除", command=lambda nid=note['id']: self.permanent_delete(nid) ).pack(side=tk.RIGHT) def update_history_view(self, window, period): """更新历史记录视图""" window.destroy() self.show_history(period) def restore_note(self, note_id): """从回收站恢复笔记""" for i, note in enumerate(self.recycle_bin): if note['id'] == note_id: restored_note = self.recycle_bin.pop(i) restored_note.pop('deleted_at', None) self.notes.append(restored_note) break self.save_data() messagebox.showinfo("提示", "笔记已恢复") self.show_history('week') # 刷新历史视图 def permanent_delete(self, note_id): """永久删除笔记""" if not messagebox.askyesno("确认", "确定要永久删除这个笔记吗?此操作不可恢复!"): return for i, note in enumerate(self.recycle_bin): if note['id'] == note_id: self.recycle_bin.pop(i) break self.save_data() messagebox.showinfo("提示", "笔记已永久删除") self.show_history('week') # 刷新历史视图 def empty_recycle_bin(self): """清空超过7天的回收站内容""" cutoff = datetime.now() - timedelta(days=7) self.recycle_bin = [item for item in self.recycle_bin if datetime.fromisoformat(item['deleted_at']) > cutoff] self.save_data() self.root.after(86400000, self.empty_recycle_bin) # 每天检查一次 def check_note_status(self): """检查笔记状态(定时任务)""" def _check(): try: now = datetime.now() for note in self.notes: if note['status'] == 'pending' and note['urgency'] >= 2: created_time = datetime.fromisoformat(note['created_at']) time_diff = now - created_time if time_diff.days >= 1 and note['urgency'] == 2: # 重要任务超过1天 self.root.after(0, lambda: self.notify_urgent_task(note)) elif time_diff.total_seconds() >= 10800 and note['urgency'] == 3: # 紧急任务超过3小时(10800秒) self.root.after(0, lambda: self.notify_urgent_task(note)) except Exception as e: print(f"笔记状态检查出错: {e}") finally: self.root.after(600000, self.check_note_status) # 每十分钟检查一次 threading.Thread(target=_check, daemon=True).start() def check_urgent_tasks(self): """检查紧急任务(定时任务)""" def _check(): try: now = datetime.now() urgent_notes = [] for note in self.notes: if note['status'] == 'pending' and note['urgency'] >= 2: created_time = datetime.fromisoformat(note['created_at']) time_diff = now - created_time if (note['urgency'] == 2 and time_diff.days >= 1) or \ (note['urgency'] == 3 and time_diff.total_seconds() >= 7200): urgent_notes.append(note) if urgent_notes: self.root.after(0, lambda: self.show_reminder_window(urgent_notes)) except Exception as e: print(f"紧急任务检查出错: {e}") finally: self.root.after(3600000, self.check_urgent_tasks) # 每小时检查一次 threading.Thread(target=_check, daemon=True).start() def notify_urgent_task(self, note): """通知紧急任务""" messagebox.showwarning( "待办提醒", f"【{note['title']}】\n\n{note['content'][:100]}...\n\n该任务尚未完成!", parent=self.root ) def show_reminder_window(self, notes): """显示提醒窗口""" if hasattr(self, 'reminder_window') and self.reminder_window.winfo_exists(): return self.reminder_window = tk.Toplevel(self.root) self.reminder_window.title("⚠️ 紧急任务提醒") self.reminder_window.geometry("500x400") self.reminder_window.protocol("WM_DELETE_WINDOW", self.on_reminder_close) # 顶部提示 header = ttk.Frame(self.reminder_window) header.pack(fill=tk.X, padx=10, pady=10) ttk.Label( header, text=f"您有 {len(notes)} 个紧急任务待处理", style='Title.TLabel', font=('Microsoft YaHei', 10, 'bold') ).pack(side=tk.LEFT) ttk.Button( header, text="关闭", command=self.on_reminder_close ).pack(side=tk.RIGHT) # 笔记列表区域 canvas = tk.Canvas(self.reminder_window) scrollbar = ttk.Scrollbar(self.reminder_window, orient="vertical", command=canvas.yview) scrollable_frame = ttk.Frame(canvas) scrollable_frame.bind( "<Configure>", lambda e: canvas.configure(scrollregion=canvas.bbox("all")) ) canvas.create_window((0, 0), window=scrollable_frame, anchor="nw") canvas.configure(yscrollcommand=scrollbar.set) canvas.pack(side="left", fill="both", expand=True) scrollbar.pack(side="right", fill="y") # 添加紧急任务列表 for note in notes: frame = ttk.Frame( scrollable_frame, borderwidth=1, relief="solid", padding=10, style='UrgentFlash.TFrame' ) frame.pack(fill="x", padx=5, pady=5, ipady=5) # 标题和紧急程度 title_frame = ttk.Frame(frame) title_frame.pack(fill="x", pady=(0, 5)) ttk.Label( title_frame, text=f"【{note['urgency']}级】{note['title']}", font=('Microsoft YaHei', 10, 'bold'), foreground='#D32F2F' ).pack(side="left") # 创建时间 created_time = datetime.fromisoformat(note['created_at']).strftime('%m/%d %H:%M') ttk.Label( title_frame, text=f"创建于: {created_time}", font=('TkDefaultFont', 8), foreground='#666666' ).pack(side="right") # 内容预览 content_preview = note['content'][:200] + "..." if len(note['content']) > 200 else note['content'] ttk.Label( frame, text=content_preview, font=('Microsoft YaHei', 9), wraplength=400 ).pack(anchor="w") # 操作按钮 btn_frame = ttk.Frame(frame) btn_frame.pack(fill="x", pady=(5, 0)) ttk.Button( btn_frame, text="标记为已完成", command=lambda nid=note['id']: self.complete_and_close(nid) ).pack(side="left", padx=2) ttk.Button( btn_frame, text="查看详情", command=lambda nid=note['id']: self.focus_note(nid) ).pack(side="left", padx=2) ttk.Button( btn_frame, text="稍后提醒", command=lambda: self.reminder_window.after(1800000, self.show_reminder_window, [note]) # 30分钟后再次提醒 ).pack(side="right", padx=2) def complete_and_close(self, note_id): """标记为已完成并关闭提醒窗口""" for note in self.notes: if note['id'] == note_id: note['status'] = 'completed' note['completed_at'] = datetime.now().isoformat() break self.save_data() self.on_reminder_close() self.render_notes() messagebox.showinfo("提示", "任务已标记为已完成") def focus_note(self, note_id): """聚焦到指定笔记""" self.on_reminder_close() self.render_notes() # 确保笔记列表是最新的 # 滚动到指定笔记 for widget in self.notes_frame.winfo_children(): if hasattr(widget, 'note_id') and widget.note_id == note_id: self.notes_canvas.yview_moveto(widget.winfo_y() / self.notes_frame.winfo_height()) # 高亮显示 widget.configure(style='UrgentFlash.TFrame') self.root.after(3000, lambda: widget.configure(style='Note.TFrame')) break def on_reminder_close(self): """关闭提醒窗口""" if hasattr(self, 'reminder_window') and self.reminder_window.winfo_exists(): self.reminder_window.destroy() delattr(self, 'reminder_window') def show_advanced_search(self): """显示高级搜索窗口""" search_window = tk.Toplevel(self.root) search_window.title("高级搜索") search_window.geometry("400x300") # 搜索条件框架 condition_frame = ttk.LabelFrame(search_window, text="搜索条件", padding=10) condition_frame.pack(fill="both", expand=True, padx=10, pady=10) # 关键词搜索 ttk.Label(condition_frame, text="关键词:").grid(row=0, column=0, sticky="w", pady=2) keyword_entry = ttk.Entry(condition_frame) keyword_entry.grid(row=0, column=1, sticky="ew", pady=2) # 紧急程度 ttk.Label(condition_frame, text="紧急程度:").grid(row=1, column=0, sticky="w", pady=2) urgency_var = tk.StringVar(value="any") urgency_options = ttk.Combobox( condition_frame, textvariable=urgency_var, values=["任何", "低", "普通", "重要", "紧急"], state="readonly" ) urgency_options.grid(row=1, column=1, sticky="ew", pady=2) # 时间范围 ttk.Label(condition_frame, text="创建时间:").grid(row=2, column=0, sticky="w", pady=2) time_frame = ttk.Frame(condition_frame) time_frame.grid(row=2, column=1, sticky="ew", pady=2) time_var = tk.StringVar(value="any") ttk.Radiobutton(time_frame, text="任何时间", variable=time_var, value="any").pack(side="left") ttk.Radiobutton(time_frame, text="最近7天", variable=time_var, value="week").pack(side="left") ttk.Radiobutton(time_frame, text="最近30天", variable=time_var, value="month").pack(side="left") # 按钮区域 button_frame = ttk.Frame(search_window) button_frame.pack(fill="x", padx=10, pady=(0, 10)) ttk.Button( button_frame, text="搜索", style='Accent.TButton', command=lambda: self.apply_advanced_search( keyword_entry.get(), urgency_var.get(), time_var.get(), search_window ) ).pack(side="right", padx=5) ttk.Button( button_frame, text="取消", command=search_window.destroy ).pack(side="right", padx=5) def apply_advanced_search(self, keyword, urgency, time_range, window): """应用高级搜索条件""" # 转换紧急程度 urgency_map = {"任何": None, "低": 0, "普通": 1, "重要": 2, "紧急": 3} urgency_level = urgency_map.get(urgency) # 转换时间范围 now = datetime.now() if time_range == "week": cutoff = now - timedelta(days=7) elif time_range == "month": cutoff = now - timedelta(days=30) else: cutoff = None # 构建搜索字符串 search_parts = [] if keyword: search_parts.append(keyword.lower()) if urgency_level is not None: search_parts.append(f"urgency:{urgency_level}") if cutoff: search_parts.append(f"after:{cutoff.strftime('%Y-%m-%d')}") self.search_var.set(" ".join(search_parts)) window.destroy() self.render_notes() def toggle_topmost(self): """切换窗口置顶状态""" self.settings['always_on_top'] = not self.settings['always_on_top'] self.root.attributes('-topmost', self.settings['always_on_top']) self.topmost_btn.config(text="📌" if self.settings['always_on_top'] else "📋") self.save_data() def change_opacity(self, value): """改变窗口透明度""" opacity = float(value) self.root.attributes('-alpha', opacity) self.settings['opacity'] = opacity self.save_data() def run(self): """运行主循环""" self.root.mainloop() if __name__ == "__main__": root = tk.Tk() # 设置DPI感知 if sys.platform == 'win32': from ctypes import windll windll.shcore.SetProcessDpiAwareness(1) app = SmartStickyNote(root) app.run() 再次检查这些代码,包括所有的初始化的值,所有的都能被初始化都能被调用,最重要确保代码能够正确执行,请将修复后的完整的代码给我
05-31
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值