我的256天创作纪念日
目录
欢迎认识,我是扑克中的黑桃A
扑克中的黑桃A的个人主页
前言:与 CSDN 的第二次相遇
沉淀:在基础领域凿出技术深井
量化成长:从 0 到 1 的扎实积累
头衔增加:技术能力的突破
日常
成就
憧憬
欢迎认识,我是扑克中的黑桃A
扑克中的黑桃A的256天创作纪念日
扑克中的黑桃A的个人主页
前言:与 CSDN 的第二次相遇
当鼠标点击 “发布” 按钮的那一刻,距离我在 CSDN 写下第一篇博客《Pycharm 的好用设置和插件》已经过去了 256 天。如果说 128 天是创作旅程的起点,那么此刻的我更像是站在技术成长的半山腰,回望来时的路,每一步都刻着代码的温度与社区的回响。这封报告不仅是对 256 天创作历程的复盘,更是一次与技术、与自我、与社区的深度对话。
沉淀:在基础领域凿出技术深井
量化成长:从 0 到 1 的扎实积累
内容矩阵:累计发布68篇原创,其中金仓数据库征文-政务领域国产化数据库更替:金仓 KingbaseES 应用实践这篇征文阅读量更是高达39580,这是以前没有想过的数据。
热榜排名:也有许多文章上了热榜,其中,AI对话高效输入指令攻略(一):了解AI对话指令更是在榜一霸榜三天
今天的数据和128天前的纪念日时相比,已经有一个层的变化了。
这 256天的创作,是一场充满惊喜的旅程。粉丝数量逐步增长,目前已有4546位朋友关注,他们的每一次关注,都让我深感责任重大。文章总阅读量已经到了253,108人次,排名从5333到了2150,让我备受鼓舞。
文章累计收获4779个赞、2904条评论和4014的收藏量。评论区里,既有新手的感谢,也有同行的建议。 甚至成了Python领域新星创作者,还入选了作者榜。
头衔增加:技术能力的突破
这128天,继续获得了阿里云专家博主,腾讯云TDP先锋会员,腾讯云创作之星,华为云初级校园大使等多个名号。
日常
创作已经在我大学生活中扮演着重要的角色。每当课余时间到来,我都会先回顾当天学到的知识,思考如何将所学运用到我的创作之中。有时灵感乍现,即便是在课间休息的短暂片刻,我也会迅速将思路记录在笔记本上。
晚上完成作业后,我会静坐在电脑前,投入一到两个小时的时间整理素材、编写代码、撰写文章。周末则是我专门留给创作的时间,更深入地学习新的 Python 库和框架,为我的创作积累更多内容和技巧。
虽然在创作与其他学业之间保持平衡并不容易,但我总是制定详细的学习计划,合理分配时间。例如,我会在周一到周五集中精力完成课程学习,而将周末的特定时段专门用于创作和深度学习,确保两者都得到充分的关注和发展。这样的安排让我能够保持学业与创作的双赢,让我在学习和创作之间找到了完美的平衡点。
成就
128天前写的是跳动的爱心(李洵同款),现在的是秒序任务待办清单。
import tkinter as tk
from tkinter import filedialog, colorchooser, messagebox
from PIL import Image, ImageTk
import json
from pathlib import Path
from datetime import datetime
from tkinter import ttkclass AdvancedTaskManager:def __init__(self, root):self.root = rootself.root.title("秒序任务待办清单")self.tasks = []self.data_file = Path("tasks.json")self.drag_start_index = Noneself.sort_mode = tk.StringVar(value="auto")self.sort_criteria = tk.StringVar(value="priority") # 新增排序依据self.custom_order = []self.checkbox_width = 4self.bg_image = Noneself.bg_photo = None# 初始化背景self.background_label = tk.Label(self.root)self.background_label.place(relx=0, rely=0, relwidth=1, relheight=1)# 样式管理 Combobox 背景色self.combo_style = ttk.Style()self.combo_style.map('Custom.TCombobox',fieldbackground=[('readonly', 'white')],selectbackground=[('readonly', 'white')],selectforeground=[('readonly', 'black')])# 创建界面组件self.create_widgets()# 加载任务数据self.load_tasks()# 初始更新列表显示self.update_lists()# 设置窗口关闭事件self.root.protocol("WM_DELETE_WINDOW", self.on_close)def create_widgets(self):# ================== 左侧任务列表区域 ==================list_container = tk.Frame(self.root, bd=2, relief=tk.GROOVE)list_container.pack(side=tk.LEFT, padx=10, pady=10, fill=tk.BOTH, expand=True)# 分割线标签 - 未完成任务tk.Label(list_container, text="未完成任务", font=("微软雅黑", 12, "bold")).pack(anchor='w', pady=(5, 0))# 未完成任务列表ongoing_frame = tk.Frame(list_container)ongoing_frame.pack(fill=tk.BOTH, expand=True)ongoing_scrollbar = tk.Scrollbar(ongoing_frame)ongoing_scrollbar.pack(side=tk.RIGHT, fill=tk.Y)self.ongoing_list = tk.Listbox(ongoing_frame,yscrollcommand=ongoing_scrollbar.set,font=('微软雅黑', 11),selectbackground="#1E90FF",selectforeground="white",selectmode=tk.SINGLE,height=8,width=50,activestyle="none",bg="white")self.ongoing_list.pack(fill=tk.BOTH, expand=True)ongoing_scrollbar.config(command=self.ongoing_list.yview)# 分隔空间tk.Frame(list_container, height=10).pack()# 已完成任务标题tk.Label(list_container, text="已完成任务", font=("微软雅黑", 12, "bold")).pack(anchor='w', pady=(5, 0))# 已完成任务列表completed_frame = tk.Frame(list_container)completed_frame.pack(fill=tk.BOTH, expand=True)completed_scrollbar = tk.Scrollbar(completed_frame)completed_scrollbar.pack(side=tk.RIGHT, fill=tk.Y)self.completed_list = tk.Listbox(completed_frame,yscrollcommand=completed_scrollbar.set,font=('微软雅黑', 11),selectbackground="#1E90FF",selectforeground="white",selectmode=tk.SINGLE,height=7,width=50,activestyle="none",bg="white")self.completed_list.pack(fill=tk.BOTH, expand=True)completed_scrollbar.config(command=self.completed_list.yview)# 绑定事件self.ongoing_list.bind('<Button-1>', self.on_click)self.ongoing_list.bind('<Button-3>', self.show_context_menu)self.completed_list.bind('<Button-1>', self.on_click)self.completed_list.bind('<Button-3>', self.show_context_menu)# ================== 右侧控制面板区域 ==================control_frame = tk.Frame(self.root)control_frame.pack(side=tk.RIGHT, padx=10, pady=10, fill=tk.Y)# 输入表单input_frame = tk.LabelFrame(control_frame, text="任务详情", padx=10, pady=10, bg="white")input_frame.pack(pady=10)tk.Label(input_frame, text="任务名称:", bg="white").grid(row=0, column=0, sticky='w')self.task_entry = tk.Entry(input_frame, width=25, bg="white")self.task_entry.grid(row=1, column=0, pady=5, sticky='we')tk.Label(input_frame, text="优先级(1-5):", bg="white").grid(row=2, column=0, sticky='w')# 使用自定义样式组合框self.priority_combo = ttk.Combobox(input_frame,width=23,values=[1, 2, 3, 4, 5],style='Custom.TCombobox')self.priority_combo.grid(row=3, column=0, pady=5)tk.Label(input_frame, text="截止日期(yyyy.mm.dd):", bg="white").grid(row=4, column=0, sticky='w')self.due_date_entry = tk.Entry(input_frame, width=25, bg="white")self.due_date_entry.grid(row=5, column=0, pady=5)# 操作按钮btn_frame = tk.Frame(control_frame, bg=self.root.cget('bg'))btn_frame.pack(pady=15)self.add_btn = self.create_button(btn_frame, "添加任务", "#4CAF50", self.add_task)self.add_btn.grid(row=0, column=0, padx=5)self.del_btn = self.create_button(btn_frame, "删除任务", "#ff4444", self.delete_task)self.del_btn.grid(row=0, column=1, padx=5)# 移动控制move_frame = tk.Frame(control_frame, bg=self.root.cget('bg'))move_frame.pack(pady=10)self.move_up_btn = self.create_button(move_frame, "↑ 上移", "#2196F3", self.move_up, width=10)self.move_down_btn = self.create_button(move_frame, "↓ 下移", "#2196F3", self.move_down, width=10)self.move_up_btn.pack(side=tk.LEFT, padx=5)self.move_down_btn.pack(side=tk.RIGHT, padx=5)# 排序模式选择mode_frame = tk.Frame(control_frame)mode_frame.pack(pady=5)tk.Label(mode_frame, text="排序模式:", bg=self.root.cget('bg')).pack(side=tk.LEFT)tk.Radiobutton(mode_frame,text="自动排序",variable=self.sort_mode,value="auto",command=self.update_move_buttons_visibility).pack(side=tk.LEFT)tk.Radiobutton(mode_frame,text="手动排序",variable=self.sort_mode,value="manual",command=self.update_move_buttons_visibility).pack(side=tk.LEFT)# 排序依据选择(仅自动排序时可用)criteria_frame = tk.Frame(control_frame)criteria_frame.pack(pady=5)self.criteria_priority_rb = tk.Radiobutton(criteria_frame,text="按优先级",variable=self.sort_criteria,value="priority",command=self.sort_tasks)self.criteria_due_date_rb = tk.Radiobutton(criteria_frame,text="按截止日期",variable=self.sort_criteria,value="due_date",command=self.sort_tasks)self.criteria_priority_rb.pack(side=tk.LEFT)self.criteria_due_date_rb.pack(side=tk.LEFT)# 设置背景按钮bg_frame = tk.Frame(control_frame, bg=self.root.cget('bg'))bg_frame.pack(pady=10)self.create_button(bg_frame, "设置模块颜色", "#808080", self.set_background_color, width=20).pack(pady=2)self.create_button(bg_frame, "上传背景图片", "#808080", self.upload_background_image, width=20).pack(pady=2)self.create_button(bg_frame, "恢复默认背景", "#808080", self.reset_background, width=20).pack(pady=2)# 初始化控件状态self.update_move_buttons_visibility()def create_button(self, parent, text, color, command, width=12):return tk.Button(parent,text=text,command=command,bg=color,fg="white",width=width,relief="flat",activebackground=color,highlightthickness=0)def update_move_buttons_visibility(self):if self.sort_mode.get() == "manual":self.move_up_btn.pack(side=tk.LEFT, padx=5)self.move_down_btn.pack(side=tk.RIGHT, padx=5)self.criteria_priority_rb.config(state=tk.DISABLED)self.criteria_due_date_rb.config(state=tk.DISABLED)else:self.move_up_btn.pack_forget()self.move_down_btn.pack_forget()self.criteria_priority_rb.config(state=tk.NORMAL)self.criteria_due_date_rb.config(state=tk.NORMAL)self.sort_tasks()def set_background_color(self):color = colorchooser.askcolor()[1]if color:if hasattr(self, 'bg_image'):del self.bg_imageself.background_label.configure(image='')self.root.configure(bg=color)for widget in self.root.winfo_children():widget_type = widget.winfo_class()if widget_type not in ('Listbox', 'Entry', 'TCombobox', 'LabelFrame'):widget.configure(bg=color)if isinstance(widget, tk.Scrollbar):widget.configure(troughcolor=color)self.task_entry.configure(bg="white")self.due_date_entry.configure(bg="white")self.ongoing_list.configure(bg="white")self.completed_list.configure(bg="white")# 修改 Combobox 样式self.combo_style.configure('Custom.TCombobox', fieldbackground="white", background="white")def upload_background_image(self):file_path = filedialog.askopenfilename(filetypes=[("Image Files", "*.png *.jpg *.jpeg *.gif *.bmp")])if file_path:try:# 打开图像并删除可能存在的错误 ICC Profileimage = Image.open(file_path)if "icc_profile" in image.info:icc_data = image.info.get("icc_profile", b'')if icc_data:# 创建一个不带 ICC 的新图像副本image_data = list(image.getdata())image = Image.new(image.mode, image.size)image.putdata(image_data)self.bg_image = image.convert("RGBA")self.update_background_image()self.root.bind("<Configure>", self.resize_background)except Exception as e:messagebox.showerror("错误", f"无法加载背景图: {str(e)}")def resize_background(self, event=None):if hasattr(self, 'bg_image'):resized = self.bg_image.resize((self.root.winfo_width(), self.root.winfo_height()), Image.Resampling.LANCZOS)self.bg_photo = ImageTk.PhotoImage(resized)self.background_label.configure(image=self.bg_photo)self.background_label.lower()def update_background_image(self):self.resize_background()def reset_background(self):default_color = "#f0f0f0"self.root.configure(bg=default_color)for widget in self.root.winfo_children():widget_type = widget.winfo_class()if widget_type not in ('Listbox', 'Entry', 'TCombobox', 'LabelFrame'):widget.configure(bg=default_color)if isinstance(widget, tk.Scrollbar):widget.configure(troughcolor=default_color)self.task_entry.configure(bg="white")self.due_date_entry.configure(bg="white")self.ongoing_list.configure(bg="white")self.completed_list.configure(bg="white")self.combo_style.configure('Custom.TCombobox', fieldbackground="white", background="white")if hasattr(self, 'bg_image'):del self.bg_imageself.background_label.configure(image='')def on_click(self, event):ongoing_selected = self.ongoing_list.nearest(event.y)completed_selected = self.completed_list.nearest(event.y)if ongoing_selected >= 0:task_idx = ongoing_selectedif event.x < self.checkbox_width * 8:self.toggle_task_status(task_idx, is_ongoing=True)else:self.select_task(task_idx, is_ongoing=True)elif completed_selected >= 0:task_idx = completed_selectedif event.x < self.checkbox_width * 8:self.toggle_task_status(task_idx, is_ongoing=False)else:self.select_task(task_idx, is_ongoing=False)def toggle_task_status(self, index, is_ongoing=True):if is_ongoing:task_idx = indexelse:offset = len([t for t in self.tasks if not t["completed"]])task_idx = offset + indexif 0 <= task_idx < len(self.tasks):current_state = self.tasks[task_idx]["completed"]self.tasks[task_idx]["completed"] = not current_stateif self.tasks[task_idx]["completed"]:self.tasks[task_idx]["completion_date"] = datetime.now().strftime("%Y.%m.%d %H:%M")else:self.tasks[task_idx].pop("completion_date", None)self.update_lists()self.save_tasks()def select_task(self, index, is_ongoing=True):self.clear_selections()if is_ongoing:self.ongoing_list.select_set(index)else:self.completed_list.select_set(index)def clear_selections(self):self.ongoing_list.select_clear(0, tk.END)self.completed_list.select_clear(0, tk.END)def update_lists(self):self.ongoing_list.delete(0, tk.END)self.completed_list.delete(0, tk.END)for idx, task in enumerate(self.tasks):status = "[✓]" if task["completed"] else "[ ]"name = task["name"]due_date = f" 📅 {task['due_date']}" if task['due_date'] else ""priority = f"🔢 优先级:{task['priority']}"create_date = f"🕒 创建于:{task['create_date']}"if task["completed"]:completion_info = f"✅ 完成于:{task.get('completion_date', '')}"lines = [f"{status} {name}",f" {priority}{due_date}",f" {create_date}",f" {completion_info}"]self.completed_list.insert(tk.END, "\n".join(lines))self.completed_list.itemconfig(tk.END, fg="#666666")else:lines = [f"{status} {name}",f" {priority}{due_date}",f" {create_date}"]self.ongoing_list.insert(tk.END, "\n".join(lines))self.ongoing_list.itemconfig(tk.END, fg="#000000")def get_selected_index(self):ongoing_sel = self.ongoing_list.curselection()completed_sel = self.completed_list.curselection()if ongoing_sel:return ongoing_sel[0], Trueelif completed_sel:return completed_sel[0], Falseelse:messagebox.showwarning("操作错误", "请先选择任务!")return None, Nonedef delete_task(self):index, is_ongoing = self.get_selected_index()if index is None:returnif is_ongoing:task_idx = indexelse:offset = len([t for t in self.tasks if not t["completed"]])task_idx = offset + indexdel self.tasks[task_idx]self.update_lists()self.save_tasks()def move_up(self):index, is_ongoing = self.get_selected_index()if index is None:returnif is_ongoing and index > 0:task_idx = indexprev_idx = index - 1elif not is_ongoing and index > 0:offset = len([t for t in self.tasks if not t["completed"]])task_idx = offset + indexprev_idx = task_idx - 1else:returnself.tasks[task_idx], self.tasks[prev_idx] = self.tasks[prev_idx], self.tasks[task_idx]self.sort_mode.set("custom")self.update_lists()self.save_tasks()def move_down(self):index, is_ongoing = self.get_selected_index()if index is None:returnif is_ongoing and index < self.ongoing_list.size() - 1:task_idx = indexnext_idx = index + 1elif not is_ongoing and index < self.completed_list.size() - 1:offset = len([t for t in self.tasks if not t["completed"]])task_idx = offset + indexnext_idx = task_idx + 1else:returnself.tasks[task_idx], self.tasks[next_idx] = self.tasks[next_idx], self.tasks[task_idx]self.sort_mode.set("custom")self.update_lists()self.save_tasks()def add_task(self):task_name = self.task_entry.get().strip()priority = self.priority_combo.get().strip()due_date = self.due_date_entry.get().strip()create_date = datetime.now().strftime("%Y.%m.%d %H:%M")if not self.validate_input(task_name, priority, due_date):returnnew_task = {"name": task_name,"priority": int(priority),"create_date": create_date,"due_date": self.format_due_date(due_date),"completed": False}if self.sort_mode.get() == "manual":self.tasks.insert(0, new_task)self.custom_order.insert(0, 0)else:self.insert_sorted(new_task)self.update_lists()self.save_tasks()self.clear_inputs()def validate_input(self, name, priority, due_date):if not name:messagebox.showwarning("错误", "请输入任务名称!")return Falsetry:if not 1 <= int(priority) <= 5:raise ValueErrorexcept ValueError:messagebox.showwarning("错误", "优先级必须是1-5的整数!")return Falseif due_date and not self.is_valid_date(due_date):messagebox.showwarning("错误", "日期格式无效,请使用 yyyy.mm.dd 格式!")return Falsereturn Truedef is_valid_date(self, date_str):try:datetime.strptime(date_str, "%Y.%m.%d")return Trueexcept ValueError:return Falsedef format_due_date(self, date_str):if not date_str:return ""try:return datetime.strptime(date_str, "%Y.%m.%d").strftime("%Y.%m.%d")except:return ""def insert_sorted(self, new_task):criteria = self.sort_criteria.get()insert_pos = 0for idx, task in enumerate(self.tasks):if task["completed"]:breakif criteria == "priority":if new_task["priority"] > task["priority"]:breakelif new_task["priority"] == task["priority"]:if (new_task["due_date"] or "9999.99.99") < (task["due_date"] or "9999.99.99"):breakelif criteria == "due_date":if (new_task["due_date"] or "9999.99.99") < (task["due_date"] or "9999.99.99"):breakelif new_task["due_date"] == task["due_date"]:if new_task["priority"] > task["priority"]:breakinsert_pos += 1self.tasks.insert(insert_pos, new_task)def sort_tasks(self):if self.sort_mode.get() != "auto":returnongoing_tasks = [t for t in self.tasks if not t["completed"]]completed_tasks = [t for t in self.tasks if t["completed"]]criteria = self.sort_criteria.get()if criteria == "priority":ongoing_tasks.sort(key=lambda x: (-x['priority'], x['due_date'] or "9999.99.99"))elif criteria == "due_date":ongoing_tasks.sort(key=lambda x: (x['due_date'] or "9999.99.99", -x['priority']))self.tasks = ongoing_tasks + completed_tasksself.sync_custom_order()self.update_lists()def sync_custom_order(self):self.custom_order = list(range(len(self.tasks)))def clear_inputs(self):self.task_entry.delete(0, tk.END)self.priority_combo.set('')self.due_date_entry.delete(0, tk.END)def save_tasks(self):try:data = {'tasks': self.tasks,'sort_mode': self.sort_mode.get(),'sort_criteria': self.sort_criteria.get(),'custom_order': self.custom_order}with open(self.data_file, 'w', encoding='utf-8') as f:json.dump(data, f, ensure_ascii=False, indent=2)except Exception as e:messagebox.showwarning("保存错误", f"数据保存失败: {str(e)}")def load_tasks(self):try:if self.data_file.exists():with open(self.data_file, 'r', encoding='utf-8') as f:data = json.load(f)self.tasks = data.get('tasks', [])self.sort_mode.set(data.get('sort_mode', 'auto'))self.sort_criteria.set(data.get('sort_criteria', 'priority'))if self.sort_mode.get() == "manual" and 'custom_order' in data:self.custom_order = data.get('custom_order')else:self.sort_tasks()except Exception as e:messagebox.showwarning("加载错误", f"数据加载失败: {str(e)}")self.tasks = []self.custom_order = []def show_context_menu(self, event):menu = tk.Menu(self.root, tearoff=0)menu.add_command(label="删除任务", command=self.delete_task)menu.add_command(label="置顶", command=lambda: self.move_to_top(event))ongoing_selected = self.ongoing_list.nearest(event.y)completed_selected = self.completed_list.nearest(event.y)if completed_selected >= 0:task_idx = len([t for t in self.tasks if not t["completed"]]) + completed_selectedif self.tasks[task_idx]["completed"]:menu.add_command(label="撤销完成", command=lambda: self.undo_complete_task(task_idx))try:menu.tk_popup(event.x_root, event.y_root)finally:menu.grab_release()def move_to_top(self, event):passdef undo_complete_task(self, task_idx):if 0 <= task_idx < len(self.tasks):self.tasks[task_idx]["completed"] = Falseself.tasks[task_idx].pop("completion_date", None)self.update_lists()self.save_tasks()def on_close(self):self.save_tasks()self.root.destroy()if __name__ == "__main__":root = tk.Tk()root.geometry("1000x700")root.configure(bg="#f0f0f0")root.resizable(True, True)app = AdvancedTaskManager(root)root.mainloop()
演示如下
秒序任务待办清单
憧憬
在过去的 256 天里,我深刻领悟到成为一个真正的 "技术高手" 并不是靠追求复杂性和华丽的技巧,而是将基础概念理解得非常透彻,并且能够将其应用于实际场景中。从最简单的 range(1, 10, 2)
中延伸出 "步长在数据采样中的应用",让我感到比运行复杂神经网络更有成就感。这种能够将抽象编程概念转化为通俗易懂生活场景的能力,正是我未来想要继续专注的方向。
我愿意将自己定位为基础技术的 "解读者",致力于将那些看似晦涩难懂的概念转化为人人皆可理解的形式,让更多初学者在编程的学习起点就能看到技术之树的延伸方向。我相信,只有打好扎实的基础,才能在技术的道路上走得更远。
最后,我要衷心感谢每一位在评论区留下足迹的读者。正是因为有了你们的反馈和支持,这些关于基础技术的内容才变得生动有趣。我希望我们在代码的世界里,每一个 print
、每一个循环都能成为通往技术深处的路标,引领更多人走进编程的奇妙世界。未来的每一天,让我们一起努力,共同成长,共同探索,让技术之树在我们手中茁壮成长!