tkinter открывает второе окно при открытии диалога или создании окна - PullRequest
0 голосов
/ 13 июня 2018

У меня следующая проблема.Я создал графический интерфейс с Tkinter, и когда я запускаю его в моей IDE (Spyder), все работает отлично, но когда я сохраняю файл как и хочу запустить его, просто выполняя .py, каждый раз, когда создается окно илиоткрывается диалоговое окно, всплывает второе окно Tkinter .Та же проблема возникает, когда я сохраняю код как .pyw.Я опубликовал короткий пример, который длится в той же проблеме.

import tkinter as tk
from tkinter import messagebox


class test_GUI(tk.Frame):
    def __init__(self,master=None):
        super().__init__(master)
        self._initializeWindow()
        self._window.protocol("WM_DELETE_WINDOW", self.__on_closing)
        self._window.mainloop()

    def _initializeWindow(self):
        self._window=tk.Tk()
        self._window.title("The window I initzialized")

    def __on_closing(self):
        if(messagebox.askokcancel("Quit", "Quit program?")):
            self._window.destroy()
            self._window.quit()        

app=test_GUI()

Ответы [ 2 ]

0 голосов
/ 13 июня 2018

Вы определяете свой класс как

class test_GUI(tk.Frame):

, поэтому ваш класс наследует от tk.Frame, что означает, что ваш класс в основном является фреймом с дополнительными функциями.
Когда вы делаете

super().__init__(master)

Вы инициализируете класс, от которого наследуетесь, то есть tk.Frame.В настоящее время нет объекта tk.Tkmaster=None).Поскольку фрейм (или любой другой виджет tkinter) не может существовать без экземпляра tk.Tk, tkinter автоматически создаст его для вас.Это ваше первое окно.
После этого вы вызываете

self._window = tk.Tk()

, чтобы сделать tk.Tk экземпляр самостоятельно.Это ваше второе окно.Кроме того, что вам не нужны два окна, вы никогда не должны запускать более одного экземпляра tk.Tk (или, точнее, связанного интерпретатора Tcl) одновременно, потому что это приводит к неожиданному поведению.

Итаккак вы можете это исправить?
У вас в основном есть два варианта: удалить наследование или инициировать tk.Tk перед инициацией вашего класса.

Без наследования ваше приложение может быть структурировано как

import tkinter as tk

class test_GUI():
    def __init__(self):
        self._window=tk.Tk()
        self._window.title("The window I initzialized")

        self.button = tk.Button(self._window, text='Test button')
        self.button.pack()

        ...
        self._window.mainloop()

С наследованием вы можете сделать это следующим образом

import tkinter as tk

class test_GUI(tk.Frame):
    def __init__(self, master=None):
        super().__init__(master)

        self.master = master
        self.master.title("The window I initzialized")

        self.button = tk.Button(self, text='Test button')
        self.button.pack()


root = tk.Tk()
app=test_GUI(root)
app.pack(fill='both', expand=True)
root.mainloop()

Оба способа работают нормально.Мне лично нравится версия с наследованием.Также ознакомьтесь с публикацией Брайана Оукли о структурировании приложения tkinter здесь .

0 голосов
/ 13 июня 2018
def _initializeWindow(self):
        self._window=tk.Tk()
        self._window.title("The window I initzialized")
        self._window.withdraw()

self._window.withdraw () удалит второе окно.

super () .__ init __ (master) фактически отвечает запервое окноПрокомментируйте это.В этом случае вам не нужно отзывать окно, созданное вами в _initializeWindow.

import tkinter as tk
from tkinter import messagebox


class test_GUI(tk.Frame):
    def __init__(self,master=None):
        #super().__init__(master)
        self._initializeWindow()
        self._window.protocol("WM_DELETE_WINDOW", self.__on_closing)
        self._window.mainloop()

    def _initializeWindow(self):
        self._window=tk.Tk()
        self._window.title("The window I initzialized")
        #self._window.withdraw()

    def __on_closing(self):
        if(messagebox.askokcancel("Quit", "Quit program?")):
            self._window.destroy()
            self._window.quit()        

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