繁体   English   中英

为什么我的 function 执行 MySQL 查询在使用 ttk.combobox 的 postcommand 调用时会出错

[英]Why does my function that executes a MySQL query gives errors when called using ttk.combobox's postcommand

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

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

我试过单独调用 function ,如下所示,它可以工作,但是。 我想在每次单击下拉列表时更新值,而不仅仅是一次。

        sopir_cbox = ttk.Combobox(frame1, state='readonly')
        load_combobox(conn, sopir_cbox)

我对编程还是很陌生,因此非常感谢任何帮助或建议。

GUI框架不像input()那样等待你的决定。 Combobox (和其他小部件)不会等待您的决定。 它只通知tkinter它必须在 window 中显示什么 - 代码移动到下一行 - 到显示 window 的mainloop()

因此,您在with connect()退出后会看到 window ,当您使用 select 选项时,代码已经在with connect()之外。 您必须在load_comoboxwith 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() with connect()放在里面

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)

但是在这里我看到了一个问题——你不能在ttk.Combobox(...)中使用sopir_cbox ,因为它还没有退出。 代码首先执行ttk.Combobox(...) ,然后它创建变量sopir_cbox =...但是当sopir_cbox =...尚未创建时,您需要在sopir_cbox ttk.Combobox(...)中的 sopir_cbox 。 您必须分两步完成

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM