Python-Tkinter - Ttk ComboBox - получить функцию, возвращающую пустую строку (длина = 0) - PullRequest
0 голосов
/ 25 августа 2018

Цель : получить значение, выбранное пользователем в выпадающем списке, с помощью self.cbo_assign.get ()

Issue : self.cbo_assign.get () isвозвращение пустой строки (длина = 0)

Дополнительная информация

У меня есть форма, на которой динамически генерируются виджеты.Я использую комбинированный список, чтобы получить пользовательский ввод.Поле со списком привязано к методу, использующему widget.bind.

  1. Это всего лишь часть кода, в которой я сталкиваюсь с проблемой
  2. Все переменные и функции были определены. Импорт был правильно объявлен.Я столкнулся с проблемой, когда пользователь выбирает значение в cbo_assign .Вызывается функция обратного вызова, база данных вызывается и обновляется, но значение cbo_assign является пустой строкой (длина = 0).
  3. Я не могу использовать атрибут textvariable, потому что виджет генерируется для всехзаписи в списке mail_list.Функционально я не могу иметь несколько виджетов, помеченных одной и той же текстовой переменной
  4. Я использую self.cbo_assign.get () , чтобы получить выбранное значение, однако возвращается пустая строка (длина = 0)
  5. Я попробовал тот же код в другом файле (у меня есть test.py, где я пробую небольшие фрагменты), и код работает правильно.Я сравнил этот файл с текущим кодом и не смог найти никакой разницы.Однако в test.py я не использовал класс для проектирования окна.Не уверен, если это может иметь какое-либо отношение
  6. Графический интерфейс работает правильно, он отображает виджет, позволяет пользователю выбрать значение, вызывает обратный вызов, обновляет базу данных.Однако значение, помеченное для выпадающего списка, пусто (длина = 0).

ссылка Github - https://github.com/tusharacc/python-read-outlook-mails/tree/master

Графический интерфейс находится в gui.py и являетсяточка входа для приложения.

Ожидание : self.cbo_assign.get () должно возвращать значение, выбранное пользователем.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()

1 Ответ

0 голосов
/ 26 августа 2018

Мне удалось определить основную причину. Поле со списком генерируется в цикле. Следовательно, self.cbo_assign ссылается на последнее добавленное поле со списком. Поэтому self.cbo_assign.get () всегда выбирает выбранное значение в последнем поле со списком. Отсюда и пусто. Если событие вызвано для последнего выпадающего списка, оно получит значение.

Самое простое решение, которое я нашел (может быть, это неправильный способ), - передать cbo в качестве параметра обработчику событий. Измененный код приведен ниже -

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 за указатели. При создании минимального кода я смог найти проблему.

...