Переменная, не разделяющая одно и то же значение между двумя разными функциями Python 2.7 Tkinter - PullRequest
1 голос
/ 09 июля 2019

Мне нужно было бы создать скрипт Python 2.7 с использованием Tkinter, который должен делать следующее:

При нажатии на кнопку «Создать NW» в окне -> я должен увидеть поле и «Добавить»сеть »рядом с полем.Если у меня есть более одного поля для ввода, то я должен нажать на кнопку «Добавить сеть» и потом посмотреть другое поле для заполнения. Если у меня есть одно или несколько заполненных полей => следует записать в файл в соответствии с«для» описано в функции определения.Если у меня нет заполненного поля, файл не должен быть создан

Часть Tkinter делает то, что должна, но код записывает его неправильно в файл.Вот соответствующая часть внутри класса, где проблема:

class Networks(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)
        self.create_widgets()

    def create_widgets(self):
        label = tk.Label(self, text="Insert the name of the networks")
        start_button = tk.Button(self, text="Return to start page", command=lambda: master.switch_frame(StartPage))
        new_network_button = tk.Button(self, text="Add network", command=self.add_network)
        new_network_button.bind("<Return>", self.add_network)
        new_network_button.grid(row=len(self.master.networks), column=3, padx=4, pady=6, sticky="W")
        next_button=tk.Button(self, text="Next", command=self.networks)
        next_button.grid(row=1500, column=5,padx=4, pady=6, sticky="W")
        label.pack(side="top", fill="x", pady=10)
        start_button.pack()
        new_network_button.pack()
        next_button.pack()
        for index, network in enumerate(self.master.networks):
            self.render_network_field(network, index)

    def add_network(self):
        self.master.networks.append({'variable': tk.StringVar(self.master)})
        self.master.switch_frame(Networks)

    def render_network_field(self, network, index):
        entry_field = tk.Entry(self, textvariable=network['variable'])
        entry_field.grid(row=index, column=0, columnspan=2, padx=4, pady=6, sticky="NEWS")
        entry_field.pack()
        global s
        s=entry_field.get()  
        print hex(id(s)) 

    def networks(self):
        with open("/home/dante/networks.yml", "w") as f:
             f.write("--- #" + "\n")
             f.write("networks:" + "\n")
             print hex(id(s))
             for ent in s:
                 if ent:
                    f.write("- { cloud: cloud1, network: "+str(ent)+ " }"+ "\n")

Теперь файл записан так, как, например, "s" не существует:

--- #
networks:

Я напечатал шестнадцатеричный идентификатор в функциях "render_network_field" и в "сетях", и кажется, что идентификаторы "s" разные.Я думал, что «с» имеет одинаковое значение в обеих функциях.Вот почему я ничего не пишу в файле.

Есть идеи, как мне это исправить?

PS Обратите внимание, что я новичок в программировании.

1 Ответ

0 голосов
/ 09 июля 2019

Примечание : В начале этого ответа я описываю более чистый способ достижения того, что вы пытаетесь сделать.Однако, если вы do хотите использовать глобальные переменные, я описал, как это будет сделано в конце моего ответа

Сначала вы должны объявить переменную s в классе * 1008.* Объем .Если вы объявляете это только в функции, она принимает область действия функции.

Это будет выглядеть следующим образом:

class Networks(tk.Frame):
    # Dummy definition. The real value will be filled in later
    s = None

Или, чтобы быть более понятным, вы можете использовать selfпеременная.Обратите внимание на строки, где используется s.Это будет работать следующим образом:

class Networks(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)
        self.create_widgets()

    def create_widgets(self):
        label = tk.Label(self, text="Insert the name of the networks")
        start_button = tk.Button(self, text="Return to start page", command=lambda: master.switch_frame(StartPage))
        new_network_button = tk.Button(self, text="Add network", command=self.add_network)
        new_network_button.bind("<Return>", self.add_network)
        new_network_button.grid(row=len(self.master.networks), column=3, padx=4, pady=6, sticky="W")
        next_button=tk.Button(self, text="Next", command=self.networks)
        next_button.grid(row=1500, column=5,padx=4, pady=6, sticky="W")
        label.pack(side="top", fill="x", pady=10)
        start_button.pack()
        new_network_button.pack()
        next_button.pack()
        for index, network in enumerate(self.master.networks):
            self.render_network_field(network, index)

    def add_network(self):
        self.master.networks.append({'variable': tk.StringVar(self.master)})
        self.master.switch_frame(Networks)

    def render_network_field(self, network, index):
        entry_field = tk.Entry(self, textvariable=network['variable'])
        entry_field.grid(row=index, column=0, columnspan=2, padx=4, pady=6, sticky="NEWS")
        entry_field.pack()
        self.s=entry_field.get()  
        print hex(id(self.s)) 

    def networks(self):
        with open("/home/dante/networks.yml", "w") as f:
             f.write("--- #" + "\n")
             f.write("networks:" + "\n")
             print hex(id(self.s))
             for ent in self.s:
                 if ent:
                    f.write("- { cloud: cloud1, network: "+str(ent)+ " }"+ "\n")

Наконец, если вы действительно хотите, чтобы он был глобальным, вы должны объявить его как глобальный в верхней части каждой функции.

...
    def networks(self):
        global s
...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...