Несколько операторов трассировки опциональных меню в Python tkinter не работает - PullRequest
0 голосов
/ 10 сентября 2018

Я написал программу на Python для Windows, которая отображает в таблице исходящие IP-адреса устройства, объединенного с процессом, программой и другими данными, которые его используют.

Я использую отдельные Listbox виджеты для IP-адресов, процессов и программ.

Поскольку в каждом окне много информации, я пытаюсь получитьФильтруйте каждый список, чтобы пользователь мог просматривать конкретные процессы и IP-адреса, которые они используют.

Я попытался реализовать фильтры с помощью виджета optionmenu .Таким образом, для каждого списка есть опциональное меню, а значения в опциональном меню определяются выходными данными этого списка.Если значение выбрано из опционного меню для этого списка, то в этом списке должны отображаться только выбранные значения вместе с соответствующими значениями в других списках.

Часть кода показана ниже:

def change_dropdown(term, listboxValues):

    fill_in_listboxes.change = True

    deleteListbox()

    change_dropdown.ind_list = getIndex(term, listboxValues)

    #print(change_dropdown.ind_list)

    insert(fill_in_listboxes.processList, processListbox, change_dropdown.ind_list)
    insert(fill_in_listboxes.programList, programListbox, change_dropdown.ind_list)


processVar.trace('w', lambda *args: change_dropdown(processVar.get(), fill_in_listboxes.processList))
programVar.trace('w', lambda *args: change_dropdown(programVar.get(), fill_in_listboxes.programList))

Функция change_dropdown первоначально удаляет все значения в списках, вызывая отдельную функцию:

deleteListbox()

Вызывает функцию, которая создает список глобальных переменных чисел, которые соответствуют индексамвыбранные значения;это основано на значении, выбранном из опционного меню, и проверяет его по всему списку значений из списка:

change_dropdown.ind_list = getIndex(term, listboxValues))

Затем он использует весь набор данных для каждого списка (который является глобальной переменной, созданнойв другой функции), сам объект списка и созданный выше список индексов для вставки данных отфильтрованных значений в списки:

insert(fill_in_listboxes.processList, processListbox, change_dropdown.ind_list)
insert(fill_in_listboxes.programList, programListbox, change_dropdown.ind_list)

При использовании опциональных меню мне известно, что функция трассировки (?) нуждается вбыть созданным для прослушивания в любое время, когда изменяется опциональное меню.

Я не хотел создавать отдельные функции для каждого вызова трассировки, поэтому я нашел информацию со страницы stackoverflow, которая, казалось, обеспечивала способ вызывать вызовы трассировкикаждое опциональное меню, которое вызывало одну и ту же функцию:

processVar.trace('w', lambda *args: change_dropdown(processVar.get(), fill_in_listboxes.processList))
programVar.trace('w', lambda *args: change_dropdown(programVar.get(), fill_in_listboxes.programList))

Страница Stackoverflow:

Получение выбора опционного меню сразу после выбора Python

с помощьюответ Кевина.

Это изображение первых двух столбцов без фильтра:

Нефильтрованныйстолбцы

Вот как это выглядит при фильтрации по первому столбцу:

Первый фильтрованный столбец

Вот как это выглядитпри попытке фильтрации по второму столбцу:

Попытки фильтрации по второму столбцу

Я знаю, что происходит не так, но не знаю почему.В этой строке:

programVar.trace('w', lambda *args: change_dropdown(programVar.get(), fill_in_listboxes.programList))

Вторая переменная относится ко всем значениям в списке programList .Список значений, связанных с этим списком, представляет собой глобальную переменную с именем fill_in_listboxes.programList .Однако, когда я проверил, используя команды print () для аргументов, чтобы увидеть, что на самом деле было передано в функцию change_dropdown, он фактически передал значения из списка процесса ( fill_in_listboxes.processList )

Я запутался, потому что когда я проверял переданные значения в функцию change_dropdown () , значение из programVar, get () является правильным, но fill_in_listboxes.processList был передан в качестве второго аргумента.

Это означает, что когда я пытаюсь получить индексы моего выбранного значения из второго списка, он не найден, потому что он пытается найти это значение изпервый список!

Я полагаю, что проблема может иметь отношение к лямбде и замыканиям, но я недостаточно хорошо разбираюсь в python, чтобы понять, где я ошибся.Я надеялся, что кто-то сможет оказать некоторую помощь.

1 Ответ

0 голосов
/ 11 сентября 2018

Я нашел ответ на свой вопрос.

Первоначально при создании OptionMenus я добавил только одну строковую переменную «All» в качестве заполнителя.

Впоследствии, когда соответствующий список был заполнен значениями, меню параметров, связанное с этим списком, было заполнено отдельными уникальными значениями из списка.

Это последующее заполнение атрибута optionmenu ['menu'] было достигнуто с помощью следующей функции:

def changeMenu(value, listSet, menuObj):

if not(value in listSet):
    listSet.add(value)
    menuObj.add_command(label=value, command=lambda s=value: processVar.set(s))

«Значение» - это индивидуальное значение, которое будет добавлено в опциональное меню, как взято из списка. Он был проверен с помощью набора Python уже добавленных значений для этого параметра меню (аргумент 'listset'). Если его не было, я использовал функцию add_command виджета меню, чтобы добавить значение в список. Однако в приведенном выше коде функция, связанная со значением, была связана с переменной var processVar. Это соответствует processListBox и меню параметров, связанных со списком.)

Теперь я думаю, что это означало, что всякий раз, когда генерировались опции в других меню, он всегда смотрел на след, относящийся к processVar. Из-за этого я изменил приведенный выше код на:

def changeMenu(value, listSet, menuObj, varObj):

if not(value in listSet):
    listSet.add(value)
    menuObj.add_command(label=value, command=lambda s=value: varObj.set(s))

И когда вызывается функция changeMenu, аргумент varObj будет относиться к связанной переменной var для optionmenu.

Последующее тестирование показало, что решение работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...