用python表白, 程序员的浪漫
![]() python用来表白也是很可以的,很浪漫哦。之前弄了一版我这边没有设置分组结果关闭的时候崩溃死了,后来加上了一个关闭操作。一键关闭所有的。 import tkinter as tkimport randomimport threadingimport timefrom queue import Queue# -------------------------- 弹窗参数 --------------------------FIRST_WIN_WIDTH = 300FIRST_WIN_HEIGHT = 140FIRST_WIN_BG = '#f0f8ff' # 外层背景色FIRST_FRAME_BG = '#fff0f5' # 内层框架色FIRST_TEXT = 'Hi,有点想你了!'FIRST_TEXT_FONT = ('微软雅黑', 18, 'bold')FIRST_TEXT_COLOR = '#d85c8a'BUTTON_TEXT = '我也想你了'BUTTON_FONT = ('微软雅黑', 14)BUTTON_BG = '#ffccd5'BUTTON_FG = '#a62639'# 随机提示窗参数TIP_WIN_WIDTH = 250TIP_WIN_HEIGHT = 60TIP_COUNT = 250 # 弹窗总数TIP_INTERVAL = 0.04 # 弹窗间隔(秒),控制总时长# 提示文字与颜色列表TIP_TEXT_LIST = [ '多喝水哦~', '保持微笑呀', '元气满满', '记得吃水果', '保持好心情', '好好爱自己', '我想你了', '偷个小懒', '期待见面', '天冷加衣', '顺顺利利', '早点休息', '烦恼消失', '别熬夜', '开心吗', '多穿衣服', '你超棒', '别焦虑', '加油', '你很特别', '会好的', '要自信', '笑一个', '摸鱼快乐']TIP_BG_COLORS = [ 'skyblue', 'lightgreen', 'lavender', 'lightyellow', 'plum', 'coral', 'bisque', 'aquamarine']# -------------------------- 核心逻辑实现 --------------------------class TipWindowManager: """提示窗口管理器,统一处理窗口创建逻辑""" def __init__(self): self.queue = Queue() # 线程通信队列 self.root = None # 主线程Tk实例 self.all_tip_windows = [] # 记录所有创建的提示窗口,用于统一关闭 self.producer_done = False # 标记生产者线程是否完成 self.final_popup_shown = False # 标记最终弹窗是否已显示 def create_tip_window(self, params): """在主线程创建单个提示窗口""" x, y = params window = tk.Toplevel(self.root) # 绑定到主线程TK实例 window.title('嘻嘻~') # 将窗口加入列表,方便后续关闭 self.all_tip_windows.append(window) # 确保窗口在屏幕内 screen_width = window.winfo_screenwidth() screen_height = window.winfo_screenheight() x = max(0, min(x, screen_width - TIP_WIN_WIDTH)) y = max(0, min(y, screen_height - TIP_WIN_HEIGHT)) window.geometry(f"{TIP_WIN_WIDTH}x{TIP_WIN_HEIGHT}+{int(x)}+{int(y)}") # 随机内容与样式 tip_text = random.choice(TIP_TEXT_LIST) bg_color = random.choice(TIP_BG_COLORS) tk.Label( window, text=tip_text, bg=bg_color, font=('微软雅黑', 16), width=30, height=3 ).pack() window.attributes('-topmost', True) def process_queue(self): """主线程循环处理队列中的窗口创建请求""" # 处理队列中剩余的窗口创建请求 while not self.queue.empty(): params = self.queue.get() self.create_tip_window(params) self.queue.task_done() # 检查:生产者线程完成 + 队列为空 + 未显示最终弹窗 → 显示最终弹窗 if self.producer_done and self.queue.empty() and not self.final_popup_shown: self.show_final_popup() self.final_popup_shown = True else: # 继续监听,直到满足条件 self.root.after(100, self.process_queue) def start_tip_producer(self, screen_width, screen_height): """启动子线程生成随机窗口参数""" def producer(): # 生成所有弹窗参数 for _ in range(TIP_COUNT): x = random.randrange(0, screen_width - TIP_WIN_WIDTH) y = random.randrange(0, screen_height - TIP_WIN_HEIGHT) self.queue.put((x, y)) time.sleep(TIP_INTERVAL) # 生产者线程完成,标记状态 self.producer_done = True # 启动守护线程(主程序退出时自动结束) producer_thread = threading.Thread(target=producer, daemon=True) producer_thread.start() def start_main_loop(self, screen_width, screen_height): """启动主线程TK循环""" self.root = tk.Tk() self.root.withdraw() # 隐藏主窗口(仅用于事件循环) self.process_queue() # 启动队列处理 self.start_tip_producer(screen_width, screen_height) self.root.mainloop() def show_final_popup(self): """显示最终的提示弹窗,点击后关闭所有窗口""" # 创建最终弹窗 final_win = tk.Toplevel(self.root) final_win.title('结束啦~') final_win.attributes('-topmost', True) # 置顶显示,确保能看到 # 弹窗居中 screen_width = final_win.winfo_screenwidth() screen_height = final_win.winfo_screenheight() win_width = 280 win_height = 120 x = int((screen_width - win_width) / 2) y = int((screen_height - win_height) / 2) final_win.geometry(f"{win_width}x{win_height}+{x}+{y}") final_win.configure(bg='#f0f8ff') # 内层框架 frame = tk.Frame( final_win, bg='#fff0f5', relief=tk.RIDGE, bd=3 ) frame.pack(fill=tk.BOTH, expand=True, padx=5, pady=5) # 核心提示文字 tk.Label( frame, text='我想你了,你可以关闭了', bg='#fff0f5', font=('微软雅黑', 18, 'bold'), fg='#d85c8a', pady=10 ).pack() # 关闭所有窗口的函数 def close_all_windows(): # 1. 关闭所有随机提示窗口 for win in self.all_tip_windows: try: win.destroy() except Exception: pass # 忽略已关闭的窗口 # 2. 关闭最终弹窗 final_win.destroy() # 3. 关闭主窗口,退出程序 self.root.quit() self.root.destroy() # 关闭按钮(醒目设计) tk.Button( frame, text='关闭所有', font=('微软雅黑', 14, 'bold'), bg='#ff6b8b', fg='white', relief=tk.RAISED, padx=20, pady=5, cursor='hand2', command=close_all_windows ).pack(pady=5)def create_first_popup(manager): """创建第一阶段带淡入淡出的问候弹窗""" first_win = tk.Tk() first_win.overrideredirect(True) # 无标题栏 first_win.attributes('-topmost', True) first_win.attributes('-alpha', 0) # 初始透明 first_win.configure(bg=FIRST_WIN_BG) # 居中定位 screen_width = first_win.winfo_screenwidth() screen_height = first_win.winfo_screenheight() x = int((screen_width - FIRST_WIN_WIDTH) / 2) y = int((screen_height - FIRST_WIN_HEIGHT) / 2) first_win.geometry(f"{FIRST_WIN_WIDTH}x{FIRST_WIN_HEIGHT}+{x}+{y}") # 内层框架(模拟边框) frame = tk.Frame( first_win, bg=FIRST_FRAME_BG, relief=tk.RIDGE, bd=3 ) frame.pack(fill=tk.BOTH, expand=True, padx=5, pady=5) # 问候文字 tk.Label( frame, text=FIRST_TEXT, bg=FIRST_FRAME_BG, font=FIRST_TEXT_FONT, fg=FIRST_TEXT_COLOR, pady=10 ).pack() # 淡入动画(500ms完成) def fade_in(): current_alpha = first_win.attributes('-alpha') if current_alpha < 1.0: first_win.attributes('-alpha', current_alpha + 0.1) first_win.after(50, fade_in) # 淡出动画(500ms完成) def fade_out(): current_alpha = first_win.attributes('-alpha') if current_alpha > 0: first_win.attributes('-alpha', current_alpha - 0.1) first_win.after(50, fade_out) else: first_win.destroy() # 启动提示窗口逻辑 manager.start_main_loop(screen_width, screen_height) # 按钮点击事件 tk.Button( frame, text=BUTTON_TEXT, font=BUTTON_FONT, bg=BUTTON_BG, fg=BUTTON_FG, relief=tk.FLAT, padx=15, pady=5, cursor='hand2', command=fade_out ).pack(pady=5) fade_in() # 启动淡入 first_win.mainloop()if __name__ == "__main__": # 初始化管理器并启动程序 tip_manager = TipWindowManager() create_first_popup(tip_manager)复制代码 |



