Python ткинтер несколько windows - PullRequest
1 голос
/ 04 апреля 2020

Я могу запустить оба файла по отдельности. Основной файл - prj.py. Когда я импортирую cfg в prj.py для запуска cfg.py, я получаю NameError: name 'root' is not defined. Попытка доступа к опции cfg.py, если это необходимо. Если необходимо cfg.py, уничтожьте prj.py, продолжите / запустите cfg.py

prj.py

import cfg
import tkinter as tk

class Application(tk.Frame):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)
        self.GetChk()        
    def GetChk(self):
        print ('PRJ')
        opn_cfg = tk.Button(root, text='CFG', width=10, command=self.GetCfg)
        opn_cfg.place(x=50, y=50)
    def GetCfg(self):
        print ('prj')
        root.destroy()
        cfg.Configuration()

if __name__ == "__main__":   
    root = tk.Tk()
    root.title('PRJ')
    root.geometry('500x250')
    root.resizable(0,0)
    app = Application(root)
    root.mainloop()

cfg.py

import tkinter as tk

class Configuration(tk.Frame):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self)
        #self.root = tk.Tk()
        #self.root.title('CFG')
        #self.root.geometry('250x125')
        #self.root.resizable(0,0)
        self.GetChk()
    def GetChk(self):
        print('CFG')      #(self.root, text='OUT', width=10, command=self.GetPrj)
        opn_prj = tk.Button(root, text='OUT', width=10, command=self.GetPrj)
        opn_prj.place(x=50, y=50)
    def GetPrj(self):
        print('cfg')

if __name__ == "__main__":   
    root = tk.Tk()              #comment out if in init
    root.title('CFG')           #comment out if in init       
    root.geometry('250x125')    #comment out if in init
    root.resizable(0,0)         #comment out if in init
    app = Configuration(root)
    root.mainloop()

1 Ответ

0 голосов
/ 04 апреля 2020

Код

if __name__ == "__main__":

- это специальная конструкция, позволяющая выполнять некоторый код только при непосредственном запуске сценария, а теперь при его импорте.

И это ваша главная проблема. Вы должны поместить этот код в функцию, которую вы можете выполнить вручную во втором скрипте - cfg.create_window()

Но это создает другую проблему. Теперь root является локальной переменной, поэтому она недоступна внутри класса, и вы не можете использовать ее в Button(). Но вы указываете root в качестве аргумента app = Configuration(root), поэтому, если вы используете

tk.Frame().__init__(super, *args, **kwargs)

или короче (объявление предпочтительно в Python 3)

super().__init__(*args, **kwargs)

, тогда Frame получит root и присвойте self.master, и вы можете использовать self.master в Button

cfg.py

import tkinter as tk

class Configuration(tk.Frame):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.get_chk()

    def get_chk(self):
        print('CFG')
        opn_prj = tk.Button(self.master, text='OUT', width=10, command=self.get_prj)
        opn_prj.place(x=50, y=50)

    def get_prj(self):
        print('cfg')

def create_window():
    root = tk.Tk()
    root.title('CFG')
    root.geometry('250x125')
    root.resizable(0, 0)
    app = Configuration(root)
    root.mainloop()

if __name__ == "__main__":   
    create_window()

prj.py

import cfg
import tkinter as tk

class Application(tk.Frame):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.get_chk()

    def get_chk(self):
        print ('PRJ')
        opn_cfg = tk.Button(self.master, text='CFG', width=10, command=self.get_cfg)
        opn_cfg.place(x=50, y=50)

    def get_cfg(self):
        print ('prj')
        self.master.destroy()
        cfg.create_window()

def create_window():
    root = tk.Tk()
    root.title('PRJ')
    root.geometry('500x250')
    root.resizable(0, 0)
    app = Application(root)
    root.mainloop()

if __name__ == "__main__":   
    create_window()

Кстати: Я изменил имена функций на lower_case_names на базе PEP 8 - Руководство по стилю для Python Код

КСТАТИ: Если вы планируете уничтожить Configuration и создать заново Application, тогда у вас будет большая проблема сделать это - так что это не очень хорошая идея. Вы должны скорее заменить контент в одном окне. Или создайте конфигурацию как Toplevel и скройте Application вместо того, чтобы уничтожать ее.

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