You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python Tkinter便签程序:点击新建按钮打开新窗口的实现方法

嘿,我来帮你搞定新建便签窗口的问题,顺便给你提些代码优化的建议~

实现新建便签窗口的方案

完全不需要导入同类文件哦!你的StickyNotes类已经在当前文件里定义好了,直接在点击事件里创建新的窗口实例并初始化类就行。

只需要修改原来的another_window函数(我后面优化时把它改成了更语义化的create_new_note方法),具体逻辑是:创建一个新的Tk窗口,然后给它绑定置顶属性,最后实例化新的StickyNotes对象。

代码优化建议

看了你的代码,有几个地方可以调整得更规范、更好维护:

  • 别用通配符导入:把from tkinter import *改成import tkinter as tk,避免命名冲突,代码可读性也更高。
  • 抛弃全局root依赖:原代码里标题栏用Frame(root,...)创建,会导致所有新建窗口的标题栏都绑定到最初的全局窗口上,要改成用每个窗口自己的master实例。
  • 内部函数转类方法:把get_pos、move_window这些操作从__init__里移出来,作为类的方法,代码结构更清晰。
  • 用Button替代Label做交互:+和X用Label虽然能点击,但Button是专门的交互组件,有更好的点击反馈,语义也更准确。
  • 修复阴影组件问题:你重复赋值self.shadow,但pack()返回None,这些变量其实没用。可以直接创建Frame后pack,不用赋值。
  • 添加窗口最小尺寸:设置master.minsize(200,200),避免用户把窗口拉得太小影响使用。
  • 优化关闭按钮交互:给关闭按钮加悬停变色效果,比点击时临时修改样式更自然。
修改后的完整代码
import tkinter as tk
import tkinter.scrolledtext as tkst
from tkinter import messagebox
from tkinter import font

class StickyNotes:
    def __init__(self, master):
        self.master = master
        self.xclick = 0
        self.yclick = 0

        # 窗口基础配置
        master.overrideredirect(True)
        master.geometry('250x250')
        master.config(bg='#838383')
        master.resizable(True, True)
        master.minsize(200, 200)  # 限制最小尺寸
        master.attributes('-topmost', 'true')

        # 标题栏
        self.titlebar = tk.Frame(master, bg='#F8F796', relief='flat', bd=2)
        self.titlebar.bind('<Button-1>', self.get_pos)
        self.titlebar.bind('<B1-Motion>', self.move_window)
        self.titlebar.pack(fill=tk.X, expand=1, side=tk.TOP)

        # 新建按钮
        self.newbutton = tk.Button(self.titlebar, text='+', bg='#F8F7B6', relief='flat', bd=0, command=self.create_new_note)
        self.newbutton.pack(side=tk.LEFT)

        # 关闭按钮(带悬停效果)
        self.closebutton = tk.Button(self.titlebar, text='X', bg='#F8F7B6', relief='flat', bd=0, command=self.quit_window)
        self.closebutton.bind('<Enter>', lambda e: self.closebutton.config(bg='#ff6b6b'))
        self.closebutton.bind('<Leave>', lambda e: self.closebutton.config(bg='#F8F7B6'))
        self.closebutton.pack(side=tk.RIGHT)

        # 主文本区域
        self.mainarea = tkst.ScrolledText(master, bg='#FDFDCA', font=('Comic Sans MS', 14, 'italic'), relief='flat', padx=5, pady=10)
        self.mainarea.pack(fill=tk.BOTH, expand=1)

        # 阴影框架
        tk.Frame(master, bg='#838383', width=3).pack(side=tk.RIGHT, fill=tk.Y)
        tk.Frame(master, bg='#838383', height=3).pack(side=tk.BOTTOM, fill=tk.X)

    def get_pos(self, event):
        self.xclick = event.x
        self.yclick = event.y

    def move_window(self, event):
        self.master.geometry(f'+{event.x_root - self.xclick}+{event.y_root - self.yclick}')

    def create_new_note(self):
        # 创建新的独立便签窗口
        new_note = tk.Tk()
        StickyNotes(new_note)

    def quit_window(self):
        if messagebox.askyesno('Delete Note?', 'Are you sure you want to delete this note?'):
            self.master.destroy()

if __name__ == '__main__':
    root = tk.Tk()
    sticky = StickyNotes(root)
    root.mainloop()
效果说明

现在点击+按钮就能创建独立的便签窗口了,每个窗口都是单独的实例,互不影响;关闭按钮添加了悬停变色的交互,体验更流畅;同时修复了原代码中标题栏绑定全局窗口的bug,每个窗口的拖动都只控制自己。

内容的提问来源于stack exchange,提问作者Pratik Parikh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:12:45