Диалог, который возвращает значение, затем уничтожает себя, не используя вспомогательные функции в вызывающем классе? - PullRequest
0 голосов
/ 07 января 2019

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

Очень урезанный код:

from tkinter import *
from tkinter.ttk import *

class Tab_ProjectDesigner:

    def __init__(self):    
        self.proceed = BooleanVar(self.page, False, "proceed")

        self.str_messages = StringVar(self.page, name="str_messages")
        #Contains information about possible errors, if any

        ##self.page is Frame containing all widgets in this class##

    def warning(self):
        #creates dialog warning user of possible errors before proceeding

        warningBox = WarningBox(self.page, self, self.str_messages.get())

    def createObject(self):
        #if errors present:
             self.warning()
        #if self.proceed.get() == True:
             #proceed to create object
        return

class WarningBox(Toplevel):
    def __init__(self, parentWidget, parentClass, warningText):
        super().__init__(parentWidget)

        self.proceed = parentClass.proceed

        lbl    = Label (self, text=warningText + "\nAre you sure you want to proceed?")
        btnYes = Button(self, text="Yes", command=self.true)
        btnNo  = Button(self, text="No",  command=self.false)

        return

    def true(self):
        self.proceed.set(True)
        self.destroy()
        return

    def false(self):
        self.proceed.set(False)
        self.destroy()
    return

createObject () вызывает warning () при наличии возможных ошибок. warning () создает WarningBox , который запрашивает пользователя и изменяет self.proceed в Tab_ProjectDesigner экземпляре, из которого он вызывается. WarningBox затем уничтожается.

Код работает, но меня это удивляет. Есть ли способ для WarningBox обрабатывать свое собственное поведение / события, а затем просто возвращать значение функции, которая его создала? Как:

def warning(Self):
    #if erorrs:
        proceed = WarningBox():
    if proceed == True:
        #proceed to object creation

1 Ответ

0 голосов
/ 07 января 2019

Класс не может возвращать значение, он всегда возвращает экземпляр класса.

Что вы можете сделать, это заставить свой код ждать, пока диалоговое окно не закроется. Затем, когда вы делаете WarningBox(...).proceed, сначала выполняется WarningBox(...), который возвращается только после закрытия окна, затем после закрытия диалога читается свойство proceed, которое равно True, False или None, в зависимости от того, как закрыто диалоговое окно.

from tkinter import *
from tkinter.ttk import *

class Tab_ProjectDesigner:

    def __init__(self):    
        self.page = Tk()

        self.str_messages = StringVar(self.page, name="str_messages")
        self.str_messages.set('test string')

        self.createObject()

        self.page.mainloop()

    def createObject(self):
        if WarningBox(self.page, self, self.str_messages.get()).proceed:
            print('Continue')
        else: 
            print('Stop')

class WarningBox(Toplevel):
    def __init__(self, parentWidget, parentClass, warningText):
        super().__init__(parentWidget)

        # Let the toplevel be transient:
        # A transient window is always drawn on top of its master,
        # and is automatically hidden when the master is iconified or withdrawn.
        # Under Windows, transient windows don’t show show up in the task bar.
        self.transient(parentWidget)

        # Set default value in case of closing the Toplevel instead of pciking an option
        self.proceed = None

        Label (self, text=warningText + "\nAre you sure you want to proceed?").pack()
        Button(self, text="Yes", command=self.true).pack()
        Button(self, text="No",  command=self.false).pack()

        # Route all events for this application to this widget
        self.grab_set()
        # wait until the Toplevel window is destroyed before returning
        self.wait_window(self)

    def true(self):
        self.proceed = True
        self.destroy()

    def false(self):
        self.proceed = False
        self.destroy()

Tab_ProjectDesigner()

P.S. Я настоятельно рекомендую вам не использовать импорт подстановочных знаков (from ... import *) для tkinter и ttk. В этих модулях много виджетов с одинаковыми именами, что может привести к путанице относительно того, из какого модуля приходит используемый вами виджет.

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