更新函数内部的全局python变量

时间:2020-01-03 14:35:01

标签: python python-3.x function tkinter global-variables

我在类似这样的类的方法中有一个函数:

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

运行代码时,函数内的self.path变量会更改。但是函数外部的self.path全局变量不会更改。

我希望self.path在函数之外进行更新。实际上,我想使用onOpen1函数更新self.path变量。此功能会打开一个窗口,您可以选择一个图像。然后,我想恢复该图像的路径以更新self.path。

1 个答案:

答案 0 :(得分:0)

按钮只是帮助可视化正在发生的事情的一种方式。这是完整的代码。

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

运行它,然后在控制台上进行打印。 点击按钮。请注意self.path如何为None。

现在通过文件对话框选择图像。

再次点击按钮。请注意self.path如何更改以反映图像的路径是什么?

您表示要更新self.path以反映您选择的内容。您的代码实际上就是这样做的。该可视化的目的是向您显示您所提出的问题可能不是您所遇到的问题的解决方案。

这是我想要的例子。

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

这里有一些2帧示例代码。

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()
相关问题