Tkinter OptionMenu Портативное окно сообщений - PullRequest
1 голос
/ 14 апреля 2011

Я пытаюсь создать облегченное кроссплатформенное окно сообщения, содержащее список элементов.В идеале он имеет API, который позволяет передавать сообщение для отображения, заголовок и набор вариантов.При нажатии OK будет возвращен текущий выбранный вариант.Также было бы желательно, чтобы требуемые модули были частью стандартных дистрибутивов Python.

У Easygui есть то, что я ищу, называется выбором, найденным в http://easygui.sourceforge.net/download/version0.95/tutorial/index.html#contents_item_10.1. Однако всплывающее окно чудовищноон всегда сортирует ваш список вариантов в алфавитном порядке.Из-за этих «особенностей» easygui не идеален.

Я также изучил bwidgets, pmw и Tix.Пробуя это, я столкнулся с несколькими проблемами, включая: трудный поиск рабочих примеров и сбоев на разных платформах.

Моя рабочая модель использует OptionMenu от Tkinter и pickle для возврата данных (см. Примеры кода ниже).Хотя это работает, довольно сложно сохранить выбор в файловой системе, чтобы избежать использования глобальных переменных. Есть ли способ вернуть выборку после уничтожения графического интерфейса?

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

Модуль управления состоянием

import pickle

def store(pkl_path, data_to_store):
    try:
        fid = open(pkl_path, 'w')
        pickle.dump(data_to_store, fid)
    except:
        print 'Unable to store data in ' + pkl_path
    else:
        fid.close()

def load(pkl_path):
    try:
        fid = open(pkl_path, 'r')
        loaded_state = pickle.load(fid)
        fid.close()
    except:
        loaded_state = None
    else:
        fid.close()

    return loaded_state

Модуль меню

from Tkinter import *

def Prompt_Dropdown_Ok_Cancel(title, options, pickle_file, default_selection=0):
    master = Tk()
    master.title(title)

    var = StringVar(master)
    var.set(options[default_selection]) # default value

    w = OptionMenu(master, var, *options)
    w.pack()

    def ok():
        state.store(pickle_file, var.get())
        master.quit()

    def cancel():
        state.store(pickle_file, None)
        master.quit()

    button = Button(master, text="OK", command=ok)
    button.pack()
    b2 = Button(master, text="Cancel", command=cancel)
    b2.pack()

    mainloop()

Пример использования

from menu_module import *

def display_com_selection():
    pkl_path = '.tmp/comm_selection'

    title = 'COM Port Selection'
    Prompt_Dropdown_Ok_Cancel(title,get_available_com(),pkl_path)

    selection = state.load(pkl_path)

    return selection

EDIT

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

Ниже приведен переработанный модуль меню

from Tkinter import *
Prompt_Dropdown_Ok_Cancel_Selection = None

def Prompt_Dropdown_Ok_Cancel(title, message, options, default_selection=0):
    master = Tk()
    master.title(title)
    var = StringVar(master)
    var.set(options[default_selection]) # default value
    l = Label(master, text=message)
    l.pack()
    w = OptionMenu(master, var, *options)
    w.pack(fill=BOTH, expand=1)

    def ok():
        global Prompt_Dropdown_Ok_Cancel_Selection
        Prompt_Dropdown_Ok_Cancel_Selection = str(var.get())
        master.destroy()

    def cancel():
        global Prompt_Dropdown_Ok_Cancel_Selection
        Prompt_Dropdown_Ok_Cancel_Selection = str(var.get())
        master.destroy()

    button = Button(master, text="OK", command=ok)
    button.pack(side=LEFT)
    b2 = Button(master, text="Cancel", command=cancel)
    b2.pack(side=LEFT)

    mainloop()

    return Prompt_Dropdown_Ok_Cancel_Selection

1 Ответ

1 голос
/ 14 апреля 2011

Обычный способ работы диалогов - это что-то вроде этого:

mydialog = SomeDialogClass(...)
result = mydialog.Show()
if  result == "OK":
    print "you clicked OK; dialog value is", mydialog.GetValue()
else:
    print "you clicked cancel"
mydialog.Destroy()

Это псевдокод, предназначенный для независимой от GUI инструментария (хотя, по общему признанию, он очень похож на wxPython). Основная идея заключается в том, что вы создаете диалоговое окно как объект, просите объект показать себя, ждете, пока пользователь завершит работу (посредством нажатия «ОК» или «Отмена»), затем запрашиваете у объекта его данные, а затем, наконец, уничтожить объект (или сохранить его для повторного использования).

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

mydialog = SomeDialogClass(..., callback=self.foo)
....
def foo(self, button, result):
    if button == "OK":
        print "you clicked OK; result is", result
    elif button == "Cancel":
        print "you clicked Cancel"

Этот второй метод хорошо работает, если ваш диалог не является модальным (то есть: ваша программа продолжает работать, пока диалоговое окно присутствует).

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