Как вы молчите выражения в Python, но все еще выполняете действие? - PullRequest
0 голосов
/ 07 октября 2019

По какой-то причине закрытие всплывающего окна tkinter с помощью кнопки требует, чтобы вы обновили окно, чтобы закрыть его (в противном случае оно просто будет находиться там), но вызов update для закрытия окна вызывает исключение.

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

Button1 = ttk.Button(popupWindow, text="Close", command=popupWindow.destroy)
Button1.pack(expand = Y)
while popupWindow:
      time.sleep(0.1)
      popupWindow.update()

Я также попробовал очевидный метод try / исключением:

Button1 = ttk.Button(popupWindow, text="Close", command=popupWindow.destroy)
Button1.pack(expand = Y)
while popupWindow:
      time.sleep(0.1)
      try:
           popupWindow.update()
      except:
           pass

Это просто вызывает зависание программы и перестает отвечать на запросы, как будто она ожидает вызова popupWindow.update (). Есть ли способ просто заставить замолчать возникшее исключение?

1 Ответ

1 голос
/ 07 октября 2019

Не следует использовать цикл while, sleep и update для ожидания нажатия кнопки или для ожидания закрытия окна. Это основная причина исключения, которое вы видите.

Tkinter имеет функции специально для этой цели. Используя одну из этих функций, вам не нужно пытаться перехватить исключение, поскольку оно не будет выброшено.

В вашем случае оказывается, что вы хотите дождаться уничтожения виджета. Вы можете использовать функцию tkinter 'wait_window`, которая делает именно это - она ​​ожидает разрушения окна.

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

import tkinter as tk

class PopupWindow(tk.Frame):
    def __init__(self, parent, message):
        tk.Frame.__init__(
            self, parent,
            borderwidth=2, relief="raised",
            background="bisque",
        )
        label = tk.Label(self, text=message, bg=self.cget("background"))
        ok_button = tk.Button(self, text="Ok", command=self.destroy)

        ok_button.pack(side="bottom", pady=10)
        label.pack(side="top", padx=20, pady=20)

        # center this widget on parent window
        self.place(relx=.5, rely=.5, anchor="center")

        # wait until the window has been destroyed
        self.wait_window(self)

Вот пример использования этого виджета:

import tkinter as tk

class Example():
    def __init__(self):
        self.root = tk.Tk()
        self.root.geometry("400x400")

        button = tk.Button(self.root, text="Do Something", command=self.do_something)
        button.pack(side="top")

        self.root.mainloop()

    def do_something(self):
        print("doing something...")
        print("waiting...")
        popupWindow = PopupWindow(self.root, "Click button to continue")
        print("done waiting...")

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