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

PySimpleGUI点击Connect后Quit按钮无法响应的问题求助

问题解决:PySimpleGUI中Connect按钮触发循环导致Quit失效

你的核心问题是主线程被Connect按钮内的while True循环阻塞,无法回到主事件循环处理Quit按钮或窗口关闭事件。解决思路是用多线程把耗时的数据库循环操作从主线程剥离,让主线程专注处理GUI交互。

修改后的完整代码

import PySimpleGUI as sg
import pyodbc
import time
import threading

# 全局标志:控制数据库检查线程的启停
stop_thread = False

def run_sql_check(server_name, db_name, username, password):
    global stop_thread
    trys = 0
    while not stop_thread:
        trys += 1
        print(f"This is try {trys}!")
        print("Connection establishment is starting...")

        # 捕获数据库连接异常,避免程序崩溃
        try:
            conn = pyodbc.connect(
                'DRIVER={ODBC Driver 17 for SQL Server};'
                f'SERVER={server_name};'
                f'DATABASE={db_name};'
                f'UID={username};'
                f'PWD={password}'
            )
            time.sleep(0.5)
            print("The connection was established successfully!")
            cursor = conn.cursor()

            time.sleep(0.5)
            print("Data write in is starting...")
            # 创建test_users表
            try:
                cursor.execute('''CREATE TABLE test_users
                            (id INT PRIMARY KEY NOT NULL, 
                            name VARCHAR(255) NOT NULL,
                            age INT NOT NULL);''')
                time.sleep(0.5)
                print("Table test_users created successfully!")

                # 插入数据
                for i in range(5):
                    cursor.execute(f"INSERT INTO test_users (id, name, age) VALUES ({i}, 'user{i}', {10 + i})")
            except:
                time.sleep(0.5)
                print("Table test_users already exists!")

            # 创建test_items表
            try:
                cursor.execute('''CREATE TABLE test_items
                            (id INT PRIMARY KEY NOT NULL,
                            name VARCHAR(255) NOT NULL,
                            price REAL NOT NULL);''')
                time.sleep(0.5)
                print("Table test_items created successfully!")
                # 插入数据
                for i in range(5):
                    cursor.execute(f"INSERT INTO test_items (id, name, price) VALUES ({i}, 'item{i}', {100 + i})")
            except:
                time.sleep(0.5)
                print("Table test_items already exists!")

            # 提交并关闭连接
            conn.commit()
            conn.close()
            time.sleep(0.5)
            print("Connection was closed successfully!")

            # 再次连接并删除表
            time.sleep(0.5)
            print("Connection establishment is starting...")
            conn = pyodbc.connect(
                'DRIVER={ODBC Driver 17 for SQL Server};'
                f'SERVER={server_name};'
                f'DATABASE={db_name};'
                f'UID={username};'
                f'PWD={password}'
            )
            time.sleep(0.5)
            print("The connection was established successfully!")
            cursor = conn.cursor()
            time.sleep(0.5)
            print("Data dropping is starting...")

            # 删除test_users表
            try:
                cursor.execute('''DROP TABLE test_users;''')
                time.sleep(0.5)
                print("Table test_users dropped successfully!")
            except:
                time.sleep(0.5)
                print("Table test_users doesn't exist!")

            # 删除test_items表
            try:
                cursor.execute('''DROP TABLE test_items;''')
                time.sleep(0.5)
                print("Table test_items dropped successfully!")  # 修复原代码的拼写错误
            except:
                time.sleep(0.5)
                print("Table test_items doesn't exist!")
            time.sleep(1)

            conn.commit()
            conn.close()
            time.sleep(0.5)
            print("The connection was closed successfully!")
            time.sleep(1)

        except Exception as e:
            time.sleep(0.5)
            print(f"The connection attempt wasn't successful. Error: {str(e)}")
            time.sleep(1)

sg.theme('DarkBlue')   

layout = [  [sg.Text('Welcome to the SQL Availability Checker.')],
            [sg.Text('Please insert the name of the Database Server')], 
            [sg.Input(key='server_name')],
            [sg.Text('Please insert the name of the Database')], 
            [sg.Input(key='db_name')],
            [sg.Text('Please insert the name of the Username to connect to the database')], 
            [sg.Input(key='Username')],
            [sg.Text('Please insert the password for the Username to connect to the database')], 
            [sg.Input(key='password', password_char='*')],  # 密码框隐藏输入
            [sg.Button('Connect'), sg.Button('Quit')] ,
            [sg.Text(text="Output")],
            [sg.Multiline(size=(60,15), font='Courier 8', expand_x=True, expand_y=True, write_only=True,
                reroute_stdout=True, reroute_stderr=True, echo_stdout_stderr=True, autoscroll=True, auto_refresh=True)]
              ]

window = sg.Window('SQL Availability Checker', layout)

while True:
    event, values = window.read()
    if event == sg.WIN_CLOSED or event == 'Quit':
        stop_thread = True  # 设置停止标志,让子线程退出循环
        break
    
    if event == 'Connect':
        stop_thread = False  # 重置停止标志
        server_name = values['server_name']
        db_name = values['db_name']
        username = values['Username']
        password = values['password']
        # 启动数据库检查线程,daemon=True表示主线程退出时自动终止子线程
        threading.Thread(target=run_sql_check, args=(server_name, db_name, username, password), daemon=True).start()

window.close()

关键改动说明

  1. 引入线程模块:添加import threading,用多线程分离GUI和业务逻辑,避免主线程被阻塞。
  2. 全局停止标志:定义stop_thread变量,用来控制子线程的循环启停。点击Quit时设为True,子线程会在下一次循环开始前退出。
  3. 封装业务逻辑:把原Connect按钮内的循环代码封装成run_sql_check函数,作为子线程的执行目标。
  4. 异常捕获:给数据库连接和操作添加try-except,避免连接失败导致程序崩溃。
  5. 线程启动方式:点击Connect时,启动子线程并设置daemon=True,确保主线程退出时子线程自动结束,避免残留进程。
  6. 细节优化:
    • 密码框添加password_char='*'隐藏输入内容
    • 修复原代码中删除test_items表时的打印错误(原打印成test_users)
    • 用f-string替代字符串拼接,代码更简洁易读

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 10:50:16