Python 为什么我执行MySQL查询的函数在使用ttk.combobox';s邮政编码

Python 为什么我执行MySQL查询的函数在使用ttk.combobox';s邮政编码,python,mysql,tkinter,Python,Mysql,Tkinter,我有一个连接到phpmyadmin MySQL数据库的程序。它有一个组合框,每当单击下拉箭头时,我都要更新其值。我使用combobox的postcommand参数来调用执行查询并更新值的函数。以下是我的简化代码: from mysql.connector import connect, Error from tkinter import * from tkinter import ttk root = Tk() root.title('Program') root.geometry('600x

我有一个连接到phpmyadmin MySQL数据库的程序。它有一个组合框,每当单击下拉箭头时,我都要更新其值。我使用combobox的postcommand参数来调用执行查询并更新值的函数。以下是我的简化代码:

from mysql.connector import connect, Error
from tkinter import *
from tkinter import ttk

root = Tk()
root.title('Program')
root.geometry('600x600+100+100')

def load_combobox(conn, cbox):
    query = 'SELECT nama_sopir FROM sopir'
    with conn.cursor() as cursor:
        cursor.execute(query)
        result = cursor.fetchall()
        cbox.config(values=result)

try:
    with connect(
        host = 'localhost',
        user = 'root',
        password = '',
        database = 'sinar_express_database'
    ) as conn:
        frame1 = Frame(root)
        frame1.pack(fill='both', expand=1)

        # I want to call the function on postcommand. This calls the function but an error occurs
        sopir_cbox = ttk.Combobox(frame1, state='readonly', postcommand=lambda : load_combobox(conn, sopir_cbox))
        sopir_cbox.pack()
except Error as e:
    print(e)

root.mainloop()
这会产生一个错误:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\Winston\AppData\Local\Programs\Python\Python37\lib\tkinter\__init__.py", line 1705, in __call__
    return self.func(*args)
  File "d:\Documents\Usaha Papa Mama\Program Uang Jalan\Baru\stackoverflow.py", line 27, in <lambda>
    sopir_cbox = ttk.Combobox(frame1, state='readonly', postcommand=lambda : load_combobox(conn, sopir_cbox))
  File "d:\Documents\Usaha Papa Mama\Program Uang Jalan\Baru\stackoverflow.py", line 11, in load_combobox
    with conn.cursor() as cursor:
  File "C:\Users\Winston\AppData\Local\Programs\Python\Python37\lib\site-packages\mysql\connector\connection.py", line 1025, in cursor
    raise errors.OperationalError("MySQL Connection not available.")
mysql.connector.errors.OperationalError: MySQL Connection not available

我对编程还是个新手,因此非常感谢您的帮助或建议。

GUI
框架不像
input()
那样等待您的决定<代码>组合框(以及其他小部件)不会等待您的决定。它只通知
tkinter
它必须在窗口中显示的内容-并且代码移动到下一行-到显示窗口的
mainloop()

所以,在窗口退出
with connect()
后,您会看到该窗口,当您选择该选项时,代码已经在
with connect()
之外。您必须将
与connect()一起使用
加载框内

from mysql.connector import connect, Error
from tkinter import *
from tkinter import ttk

# --- functions ---

def load_combobox():
    try:
        with connect(
                host = 'localhost',
                user = 'root',
                password = '',
                database = 'sinar_express_database'
            ) as conn:
            query = 'SELECT nama_sopir FROM sopir'
            with conn.cursor() as cursor:
                cursor.execute(query)
                result = cursor.fetchall()
                sopir_cbox.config(values=result)
    except Error as e:
        print(e)

# --- main ---

root = Tk()
root.title('Program')
root.geometry('600x600+100+100')

frame1 = Frame(root)
frame1.pack(fill='both', expand=1)

# I want to call the function on postcommand. This calls the function but an error occurs
sopir_cbox = ttk.Combobox(frame1, state='readonly', postcommand=load_combobox)
sopir_cbox.pack()

root.mainloop()
或者您必须将
mailoop()
与connect()一起放入


但是这里我看到了一个问题-您不能在
ttk.Combobox(…)
内部使用
sopir\u cbox
,因为它还没有退出。代码首先执行ttk.Combobox(…),然后创建变量sopir\u cbox=…,但在sopir\u cbox=…尚未创建时,需要sopir\u cbox(…)内部ttk.Combobox(…)。你必须分两步来做

sopir_cbox = ttk.Combobox(frame1, state='readonly')
sopir_cbox["postcommand"] = lambda : load_combobox(conn, sopir_cbox)

GUI框架的工作原理不同于
input()
-Combobox不会等待您的决定-它只会通知tkinter在窗口中显示什么,并且
mainloop()
启动窗口-所以您可以在它退出后看到窗口`with connect()
。您必须将函数分配到
Combobox,并在此函数内运行`with connect()`。或者您应该将
root.mainloop()
放在`with connect()`中,因为您已经将
with connect(…)用作conn:
,所以数据库连接将在
with
语句之后关闭。因此,当执行
load\u combobox()
时,数据库连接已经关闭。
with connect(
    host = 'localhost',
    user = 'root',
    password = '',
    database = 'sinar_express_database'
) as conn:
    frame1 = Frame(root)
    frame1.pack(fill='both', expand=1)

    # I want to call the function on postcommand. This calls the function but an error occurs
    sopir_cbox = ttk.Combobox(frame1, state='readonly', postcommand=lambda : load_combobox(conn, sopir_cbox))
    sopir_cbox.pack()

    root.mainloop()
except Error as e:
    print(e)
sopir_cbox = ttk.Combobox(frame1, state='readonly')
sopir_cbox["postcommand"] = lambda : load_combobox(conn, sopir_cbox)