Просмотрите мои изменения внизу, теперь эта проблема связана с ОС.
GIF-изображение проблемы в действии
Итак, у меня проблема с экземпляром ttk.OptionMenu. Я успешно реализовал этот виджет и раньше, однако я пытаюсь использовать его здесь как раскрывающийся список для доступных файлов во всплывающем окне, и мне кажется, что он не работает правильно.
Проблема
- Виден только первый вариант в меню, другие варианты недоступны.
- Он не реагирует на мышь, кроме того, что он затемняется при нажатии
- Когда на него нажимают, в терминале не отображаются ошибки или вывод, что затрудняет отслеживание
Код
Фактический вызов выполняется из другого файла, скажем myproject/main.py
from classes.load_window import *
start_load_menu()
Класс для этого хранится в файле по адресу myproject/classes/load_window.py
, и он обращается к файлам сохранения, хранящимся в myproject/saved/
import tkinter
import tkinter.ttk as ttk
from os import listdir
from os.path import join, isfile
class LoadMenu(object):
def __init__(self):
root = self.root = tkinter.Tk()
root.title("Save Manager")
root.overrideredirect(True)
""" MAIN FRAME """
frm_1 = ttk.Frame(root)
frm_1.pack(ipadx=2, ipady=2)
""" MESSAGE LABEL """
self.msg = str("Would you like to load from a save file?")
message = ttk.Label(frm_1, text=self.msg)
message.pack(padx=8, pady=8)
""" INNER FRAME """
frm_2 = ttk.Frame(frm_1)
frm_2.pack(padx=4, pady=4)
""" TEST IMPLEMENTAITON [DOES NOT WORK] """
mylist = ['1', '2', '3', '4', '5', '6', '7']
test_var = tkinter.StringVar(frm_2)
test_var.set(mylist[3])
test_dropdown = ttk.OptionMenu(frm_2, test_var, *mylist)
test_dropdown.pack(padx=4, pady=4)
print(mylist) # Results in ['1', '2', '3', '4', '5', '6', '7']
""" REAL IMPLEMENTATION [ALSO DOES NOT WORK] """
files = [f for f in listdir('saved') if isfile(join('saved', f))]
file_var = tkinter.StringVar(frm_2)
file_var.set(files[3])
file_dropdown = ttk.OptionMenu(frm_2, file_var, *files)
file_dropdown.pack(padx=4, pady=4)
print(files) # Results in ['DS_Store', 'test1', 'test2', 'test3']
""" BUTTON FUNCTIONALITY """
btn_1 = ttk.Button(frm_2, width=8, text="Load File")
btn_1['command'] = self.b1_action
btn_1.pack(side='left')
btn_2 = ttk.Button(frm_2, width=8, text="Cancel")
btn_2['command'] = self.b2_action
btn_2.pack(side='left')
btn_3 = ttk.Button(frm_2, width=8, text="Create New")
btn_3['command'] = self.b3_action
btn_3.pack(side='left')
btn_2.bind('<KeyPress-Return>', func=self.b3_action)
root.update_idletasks()
""" Position the window """
xp = (root.winfo_screenwidth() // 2) - (root.winfo_width() // 2)
yp = (root.winfo_screenheight() // 2) - (root.winfo_height() // 2)
geom = (root.winfo_width(), root.winfo_height(), xp, yp)
root.geometry('{0}x{1}+{2}+{3}'.format(*geom))
root.protocol("WM_DELETE_WINDOW", self.close_mod)
root.deiconify()
def b1_action(self, event=None):
print("B1")
def b2_action(self, event=None):
self.root.quit()
def b3_action(self, event=None):
print("B3")
def nothing(self):
print("nothing")
def close_mod(self):
pass
def time_out(self):
print ("TIMEOUT")
def to_clip(self, event=None):
self.root.clipboard_clear()
self.root.clipboard_append(self.msg)
def start_load_menu():
menu = LoadMenu()
menu.root.mainloop()
menu.root.destroy()
return menu.returning
Примечания
Этот код основан на ответе здесь для всплывающего окна, которое я адаптирую для конкретной цели (меню загрузки).
Я сократил этот код до минимума, чтобы воспроизвести проблему, но вы, вероятно, можете игнорировать определения функций и геометрию окна.
Все работает отлично, кроме этого; окно отображается в центре экрана, а кнопка с фактическими функциями закрывает окно, это просто странная причуда с OptionMenu, с которой я не могу найти никого, с кем еще борются ни здесь, ни на других форумах.
Если вы не видели ссылку вверху, вы можете найти демонстрацию проблемного поведения по этой ссылке. а>
Я использую Python 3.6.4 в OSX 10.12.6
ИЗМЕНИТЬ:
С тех пор я протестировал этот код на виртуальной машине под управлением Hydrogen Linux, , и он отлично работает. Тогда мой вопрос немного изменится:
Как я могу убедиться, что этот код хорошо транслируется в OSX? Есть ли сведения о расхождениях между запуском TKinter на разных платформах?
Я нашел эту страницу по вопросам, связанным с Python, TKinter и OSX, но даже при использовании рекомендованных пакетов TCL с последней стабильной версией Python эта проблема сохраняется.
ИЗМЕНИТЬ 2:
Просто чтобы обновить, с тех пор я нашел способ решения проблемы. Это не отвечает на вопрос о странном поведении OptionMenu, но я решил, что буду редактировать. Честно говоря, я думаю, что Listbox, вероятно, лучше подходит для того, чем я хотел заниматься. Вот оно в действии.
Пожалуйста, дайте мне знать, если мне нужно внести какие-либо изменения для ясности или предоставить дополнительную информацию. Поскольку я новичок в stackoverflow, у меня нет особых проблем с обменом опытом. Спасибо!
ttk.OptionMenu
(3-й параметр - значение по умолчанию), но эта ошибка обычно приводит к отсутствию первого параметра, а не к тому, что он является единственным элементом в меню. - person jasonharper   schedule 14.03.2018