Python-Tkinter - Ttk ComboBox - 获取函数返回空字符串(长度=0)

Python-Tkinter - Ttk ComboBox - get function returning empty string (length=0)

Objective: 使用 self.cbo_assign.get()

检索用户在组合框中编辑的值 select

问题: self.cbo_assign.get() 是 returning 空字符串(长度=0)

附加信息

我有一个可以动态生成小部件的表单。我正在使用组合框来获取用户输入。组合框绑定到使用 widget.bind 的方法。

  1. 这只是我遇到问题的部分代码
  2. 所有变量和函数都已 defined.Imports 已正确声明。我遇到了问题,而用户正在 cbo_assign 中 selecting 值。调用了回调函数,调用并更新了数据库,但是 cbo_assign 的值为空字符串(长度=0)。
  3. 我不能使用属性 textvariable,因为小部件是为列表 mail_list 中的所有记录生成的。从功能上讲,我不能将多个小部件标记为相同的文本变量
  4. 我正在使用 self.cbo_assign.get() 来获取 selected 值,但是它是 returning 空字符串(长度= 0)
  5. 我在另一个文件中尝试了相同的代码(我有一个 test.py,我在其中尝试了一些小片段)并且代码运行正常。我将该文件与当前代码进行了比较,没有发现任何差异。然而在 test.py 中,我没有使用 class 来设计 window。不确定,是否有任何意义
  6. GUI 工作正常,它显示小部件,让用户 select 值,调用回调,更新数据库。但是标记到组合框的值是空的(长度=0)。

Github link - https://github.com/tusharacc/python-read-outlook-mails/tree/master

GUI 位于 gui.py 中,是应用程序的入口点。

期望值self.cbo_assign.get() 应该 return 用户编辑的值 select . self.cbo_assign.get 在 update_assignment_details 回调中被调用。我也尝试将 self.cbo_assign.get 作为参数传递,但即使那样它也没有用

模拟行为的代码

from tkinter import *
from tkinter import ttk

class Application(Frame):
    def __init__(self, master=None):
        super().__init__(master)
        self.grid(row=0,column=0,sticky=N+E+S+W)
        self.user_names = [['ABC','THDG'],['GHI','ANBC'],['DEF','SODM'],['CMF','CMH'],['KDH','APE']]
        self.create_widgets()

    def create_widgets(self):
        self.mail_frame = Frame(self, bg='green')
        self.mail_frame.grid(row=20,column=0,sticky=N + E + S + W,padx=10,pady=10)
        self.mail_frame.rowconfigure(0, weight=1)
        self.mail_frame.columnconfigure(0, weight=1)
        self.initiate_mail_process()

    def initiate_mail_process(self):
        self.mail_list = [['ABC']]*6
        row = 5
        for _ in self.mail_list:
            col = 0
            self.cbo_assign = ttk.Combobox(self.mail_frame, values=self.user_names)
            self.cbo_assign.grid(row=row, column=col, columnspan=5, sticky=N + S + W + E)
            self.cbo_assign.bind("<<ComboboxSelected>>", lambda x: self.update_assignment_details(x))       
            col += 5
            row += 5

    def update_assignment_details(self,event):
        print (self.cbo_assign.get())

root = Tk()
root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)
root.title("TICKET ASSIGNMENT")
app = Application(master=root)
app.mainloop()

我能够找出根本原因。组合框在循环中生成。因此 self.cbo_assign 引用最后添加的组合框。所以 self.cbo_assign.get() 总是在最后一个组合框中获取选定的值。因此它是空的。如果为最后一个组合框触发事件,它将获取值。

我找到的最简单的解决方案(可能不是正确的方法)是将 cbo 作为参数传递给事件 handler.The 修改后的代码如下 -

def initiate_mail_process(self):
    self.mail_list = [['ABC']]*6
    row = 5
    for _ in self.mail_list:
        col = 0
        self.cbo_assign = ttk.Combobox(self.mail_frame, values=self.user_names)
        self.cbo_assign.grid(row=row, column=col, columnspan=5, sticky=N + S + W + E)
        self.cbo_assign.bind("<<ComboboxSelected>>", lambda x,arg=self.cbo_assign: self.update_assignment_details(x,arg))
        col += 5
        row += 5

感谢@Bryan 的指点。在生成最少的代码时,我找到了问题所在。