简体   繁体   中英

Update a global python variable inside a function

I have a function inside a method of a class like this:

from tkinter import Frame, Tk, BOTH, Text, Menu, END
from tkinter import filedialog as tkFileDialog 

class Example(Frame):

    def __init__(self, parent):
        Frame.__init__(self, parent)   

        self.parent = parent        
        self.initUI()
        self.path = None
        print(self.path)
    def initUI(self):

        self.parent.title("File dialog")
        self.pack(fill=BOTH, expand=1)

        menubar = Menu(self.parent)
        self.parent.config(menu=menubar)

        fileMenu = Menu(menubar)
        fileMenu.add_command(label="Open_image", command=self.onOpen1)
        menubar.add_cascade(label="File", menu=fileMenu)        

    def onOpen1(self):

        ftypes = [('jpg files','.jpg'),('png files','.png'),('all files','.*')]
        dlg = tkFileDialog.Open(self, filetypes = ftypes)
        path = dlg.show()

        if path != '':
            self.path = path
            print(self.path)
            return self.path


def main():

    root = Tk()
    ex = Example(root)
    root.geometry("300x250+300+300")
    root.mainloop()  


if __name__ == '__main__':
    main() 

When I run the code, the self.path variable inside the function changes. But the self.path global variable outside the function does not change.

I would like self.path to be updated outside of the function. In fact, I want to update the self.path variable with the onOpen1 function. This function opens a window which allows you to select an image. Then, I want to recover the path of this image to update self.path.

The button is just a way to help visualize what is happening. Here is the full code.

from tkinter import Frame, Tk, BOTH, Text, Menu, END, Button
from tkinter import filedialog as tkFileDialog 

class Example(Frame):

    def __init__(self, parent):
        Frame.__init__(self, parent)   

        self.parent = parent        
        self.initUI()
        self.path = None
        print(self.path)

    def initUI(self):
        self.parent.title("File dialog")
        self.pack(fill=BOTH, expand=1)

        menubar = Menu(self.parent)
        self.parent.config(menu=menubar)

        fileMenu = Menu(menubar)
        fileMenu.add_command(label="Open_image", command=self.onOpen1)
        menubar.add_cascade(label="File", menu=fileMenu) 

        button = Button(self.parent, text='test', command=self.test)  
        button.pack()     

    def test(self):
        print(self.path)

    def onOpen1(self):

        ftypes = [('jpg files','.jpg'),('png files','.png'),('all files','.*')]
        dlg = tkFileDialog.Open(self, filetypes = ftypes)
        path = dlg.show()

        if path != '':
            self.path = path
            print(self.path)
            return self.path


def main():

    root = Tk()
    ex = Example(root)
    root.geometry("300x250+300+300")
    root.mainloop()  


if __name__ == '__main__':
    main() 

Run it and watch your console where the print will happen. Hit the button. Notice how self.path is None.

Now select an image with your file dialog box.

Hit the button again. Notice how self.path changed to reflect what the path to the image is?

You stated that you want to update self.path to reflect what you selected. Your code does in fact do that. The point of this visualization is to show you that the question you asked may not be the solution to the problem you're having.

Here is an example of what I think you want.

from tkinter import Frame, Tk, BOTH, Text, Menu, END, Button, Label
from tkinter import filedialog as tkFileDialog
import cv2
from PIL import ImageTk, Image

class Example(Frame):

    def __init__(self, parent):
        Frame.__init__(self, parent)   

        self.parent = parent        
        self.initUI()
        self.path = None
        print(self.path)

    def initUI(self):
        self.parent.title("File dialog")
        self.pack(fill=BOTH, expand=1)

        menubar = Menu(self.parent)
        self.parent.config(menu=menubar)

        fileMenu = Menu(menubar)
        fileMenu.add_command(label="Open_image", command=self.onOpen1)
        menubar.add_cascade(label="File", menu=fileMenu) 

    def test(self):
        print(self.path)

    def onOpen1(self):

        ftypes = [('jpg files','.jpg'),('png files','.png'),('all files','.*')]
        dlg = tkFileDialog.Open(self, filetypes = ftypes)
        path = dlg.show()

        if path != '':
            self.path = path
            self.add_image()

    def add_image(self):
        img = cv2.imread(self.path)
        img = cv2.resize(img,(224, 224), interpolation = cv2.INTER_AREA)
        image1 = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        image1 = Image.fromarray(image1)
        image1 = ImageTk.PhotoImage(image1)
        panelA = Label(self, image=image1)
        panelA.image = image1
        panelA.grid(row=0, column=0, sticky='w')

def main():

    root = Tk()
    ex = Example(root)
    root.geometry("300x250+300+300")
    root.mainloop()  


if __name__ == '__main__':
    main() 

Here's some sample code for 2 frames.

from tkinter import Frame, Tk, BOTH, Text, Menu, END, Button, Label
from tkinter import filedialog as tkFileDialog
import cv2
from PIL import ImageTk, Image

class Example(Frame):

    def __init__(self, parent):
        Frame.__init__(self, parent)

        self.parent = parent
        self.initUI()
        self.current_window = 0
        self.path = None
        self.panelA = None
        self.panelB = None
        print(self.path)

    def initUI(self):
        self.parent.title("File dialog")
        #self.pack(fill=BOTH, expand=1)

        menubar = Menu(self.parent)
        self.parent.config(menu=menubar)

        fileMenu = Menu(menubar)
        fileMenu.add_command(label="Open Image 1", command=lambda: self.onOpen1(1))
        fileMenu.add_command(label="Open Image 2", command=lambda: self.onOpen1(2))
        menubar.add_cascade(label="File", menu=fileMenu)

        self.button_1 = Button(self.parent, text='Window 1', command=lambda: self.switch_window(1))
        self.button_2 = Button(self.parent, text='Window 2', command=lambda: self.switch_window(2))
        self.back_button = Button(self.parent, text='Back', command=lambda: self.switch_window(0))

        self.button_1.grid(sticky='w')
        self.button_2.grid(sticky='w')

    def switch_window(self, window):
        self.current_window = window
        if window == 0:
            self.back_button.grid_forget()
            self.button_1.grid(sticky='w')
            self.button_2.grid(sticky='w')
        else:
            self.button_1.grid_forget()
            self.button_2.grid_forget()
            self.back_button.grid(row=1, sticky='w')

        self.repopulate_windows()

    def onOpen1(self, image_selection):
        ftypes = [('jpg files','.jpg'),('png files','.png'),('all files','.*')]
        dlg = tkFileDialog.Open(self, filetypes = ftypes)
        path = dlg.show()

        if path != '':
            self.path = path
            self.add_image(image_selection)

    def add_image(self, image_selection):
        img = cv2.imread(self.path)
        img = cv2.resize(img,(224, 224), interpolation = cv2.INTER_AREA)
        image1 = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        image1 = Image.fromarray(image1)
        image1 = ImageTk.PhotoImage(image1)

        if image_selection == 1:
            self.panelA = Label(self.parent, image=image1)
            self.panelA.image = image1
        else:
            self.panelB = Label(self.parent, image=image1)
            self.panelB.image = image1

        if self.current_window != 0:
            self.repopulate_windows()

    def repopulate_windows(self):
        if self.current_window == 1:
            if self.panelB is not None:
                self.panelB.grid_forget()
            if self.panelA is not None:
                self.panelA.grid(row=0, column=0, sticky='w')
        elif self.current_window == 2:
            if self.panelA is not None:
                self.panelA.grid_forget()
            if self.panelB is not None:
                self.panelB.grid(row=0, column=0, sticky='w')
        else:
            if self.panelA is not None:
                self.panelA.grid_forget()
            if self.panelB is not None:
                self.panelB.grid_forget()

def main():

    root = Tk()
    ex = Example(root)
    root.geometry("300x250+300+300")
    root.mainloop()


if __name__ == '__main__':
    main()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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