PySimpleGUI开发的消息群发工具点击submit后冻结,Spin组件箭头无效应如何解决
问题解决及代码优化方案
Spin调节失效问题
sg.Spin的首个入参要求传入可选值的序列,你直接传入单个数字0不符合参数要求,修改为指定取值范围即可生效,示例:
# 消息数量Spin,取值范围1-200,默认值1 sg.Spin(values=[i for i in range(1, 201)], initial_value=1, key="spammer") # 冷却时间Spin,取值范围0-10,默认值0 sg.Spin(values=[i for i in range(0, 11)], initial_value=0, key="cooldown")
点击submit后程序冻结问题
PySimpleGUI的事件循环是单线程运行的,你在submit的回调逻辑里直接写了time.sleep和群发消息的循环逻辑,会阻塞主事件循环,导致界面无法响应操作。解决方案是将群发消息的逻辑放到独立子线程中运行,不要占用主线程资源。
其他基础错误修正
- 布局嵌套错误:所有layout的定义存在多层多余的方括号嵌套,会导致界面排版异常,需要删除多余的嵌套层级。
- 窗口实例化逻辑错误:你提前全局实例化了所有子窗口,窗口关闭后再次触发会报错,应该在触发对应功能时再创建窗口实例。
- Stop按钮逻辑失效:原有代码中Stop按钮的判断位置错误,根本无法触发,需要配合线程终止标识实现停止功能。
修正后完整代码
import time import threading import PySimpleGUI as sg import pyautogui as pyautogui # 全局标识,控制群发任务是否运行 spammer_running = False def spammer_task(msg_count, cooldown, msg, final_msg): global spammer_running spammer_running = True time.sleep(5) for xi in range(msg_count): if not spammer_running: break pyautogui.typewrite(msg) time.sleep(cooldown) pyautogui.press('enter') print(xi) if spammer_running and final_msg.strip(): pyautogui.typewrite(final_msg) pyautogui.press('enter') spammer_running = False # 主窗口布局 main_layout = [ [ sg.Text("What do you want to do?"), sg.Button("Spammer"), sg.Button("Encrypter"), sg.Button("Decrypter"), sg.Button("Password generator"), sg.Button("Exit") ] ] main_window = sg.Window("Multifunctiontool", main_layout) while True: event, values = main_window.read() if event == "Exit" or event == sg.WIN_CLOSED: break if event == "Spammer": # 触发Spammer功能时再创建对应窗口 spammer_layout = [ [sg.Text("Press Start to start the bot.")], [sg.Text("Press Stop to stop the bot.")], [sg.Button("Start"), sg.Button("Stop")] ] spammer_window = sg.Window("spammer", spammer_layout) while True: s_event, s_values = spammer_window.read() if s_event == "Stop" or s_event == sg.WIN_CLOSED: spammer_running = False spammer_window.close() break if s_event == "Start": spammer_config_layout = [ [sg.Text("How many messages do you want to send?"), sg.Spin(values=[i for i in range(1, 201)], initial_value=1, key="spammer")], [sg.Text("How long ist the cooldown? if not there just leave on 0"), sg.Spin(values=[i for i in range(0, 11)], initial_value=0, key="cooldown")], [sg.Text("What is your message?"), sg.Input(key="message")], [sg.Text("Do you want to leave a final message(Write down your message, if no just leave blank)?"), sg.Input(key="final_message")], [sg.Button("submit"), sg.Button("Exit")] ] config_window = sg.Window("spammer config", spammer_config_layout, force_toplevel=True) c_event, c_values = config_window.read() if c_event == "Exit" or c_event == sg.WIN_CLOSED: config_window.close() continue if c_event == "submit": try: msg_count = int(c_values['spammer']) cooldown = int(c_values['cooldown']) msg = c_values['message'] final_msg = c_values['final_message'] except: tip_layout = [ [sg.Text("please enter a valid parameter")], [sg.Button("Continue"), sg.Button("Exit")] ] tip_window = sg.Window("tip", tip_layout) t_event, t_values = tip_window.read() tip_window.close() if t_event == "Exit": config_window.close() spammer_window.close() break else: config_window.close() continue # 启动子线程跑群发任务 threading.Thread(target=spammer_task, args=(msg_count, cooldown, msg, final_msg), daemon=True).start() sg.popup("任务将在5秒后启动,可点击Stop按钮终止任务") config_window.close() main_window.close()
内容的提问来源于stack exchange,提问作者Bz Shifu
相关产品推荐
相关产品推荐

