简体   繁体   English

变量在两个不同的函数之间不共享相同的值Python 2.7 Tkinter

[英]Variable not sharing same value between two different functions Python 2.7 Tkinter

I would need to create a Python 2.7 script using Tkinter which should do the following: 我需要使用Tkinter创建一个Python 2.7脚本,该脚本应执行以下操作:

When clicking on the "Create the NWs" button in a window -> I should see a field and a "Add network" button near the field. 在窗口中单击“创建NW”按钮->我应该在该字段附近看到一个字段和一个“添加网络”按钮。 If I have more than one field to introduce, then I should press on the "Add network" button and see another field afterwards to fill in. If I have one or more than one field completed => should write in the file according to the "for" described in the define function. 如果要介绍的字段不止一个,则应按“添加网络”按钮,然后再填写其他字段。如果我完成了一个或多个字段,则=>应该根据在定义函数中描述的“用于”。 If I do not have any field completed, the file should not be created 如果我没有完成任何字段,则不应创建该文件

The Tkinter part is doing what it should, but the code is not writing it correctly in the file. Tkinter部分正在执行应做的工作,但是代码未将其正确写入文件中。 Here is the relevant part inside of a class where the problem is: 这是问题所在的类的相关部分:

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")

Now, the file is written just like this, like "s" is not existing: 现在,文件是这样写的,例如“ s”不存在:

--- #
networks:

I have printed the hex id in "render_network_field" and in "networks" functions and it is seems that the "s" IDs are different. 我已经在“ render_network_field”和“网络”功能中打印了十六进制ID,似乎“ S” ID是不同的。 I thought that the "s" has the same value in both functions. 我认为两个函数中的“ s”具有相同的值。 That's the reason that I am getting nothing written in the file. 这就是我没有在文件中写入任何内容的原因。

Any idea how I can correct this? 知道我该如何纠正吗?

PS Please note that I am quite new to programming. PS请注意,我是编程的新手。

Note : In the beginning of this answer, I am describing a cleaner way to accomplish what you are trying to do. 注意 :在此答案的开头,我描述的是一种更干净的方法来完成您尝试做的事情。 However, if you do want to use globals, I have described how that would be done at the end of my answer 但是,如果您确实想使用全局变量,那么我将在回答的最后说明如何做到这一点。

You must first declare the s variable in the class's scope . 您必须首先在类的scope中声明s变量。 If you declare it only in the function, it assumes the function's scope. 如果仅在函数中声明它,则它将假定函数的作用域。

This would be as follows: 如下所示:

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

Or, to be more clear, you could use the self variable. 或者,更明确地说,您可以使用self变量。 Note the lines where s is used. 请注意使用s的行。 This would work as follows 这将如下工作

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")

Finally, if you really wanted it to be global, you must declare it as a global at the top of every function. 最后,如果您确实希望它是全局的,则必须在每个函数的顶部将其声明为全局的。

...
    def networks(self):
        global s
...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM