【问题标题】:Update a global python variable inside a function更新函数内的全局 python 变量
【发布时间】:2020-04-22 03:00:17
【问题描述】:

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

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。

【问题讨论】:

  • 其实我想用onOpen1函数更新self.path变量。此功能打开一个窗口,允许您选择图像。然后,我想恢复这张图片的路径来更新self.path。
  • 你已经在这样做了。 @Jena如果您想证明这一点,请在窗口中添加一个按钮,并将其映射到打印 self.path。将Button 添加到您的导入中。然后将这两行添加到您的 initUI 方法中。 button = Button(self.parent, text='test', command=self.test)button.pack()添加只打印self.path的测试方法。
  • 如果self.path,我将它添加到代码中! = 无:打印('OK')。但它不起作用。
  • 你把代码加到哪里了?
  • 我将它添加到 UI,但它不起作用。我不明白按钮应该做什么。

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


【解决方案1】:

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

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

【讨论】:

  • 是的,它似乎有效。但我想做的是第二个答案。但是这个答案的问题是窗口在启动时会自动打开。而当我们改变图像时,路径不会改变。
  • @Jena 我用我认为你正在寻找的行为编辑了我的答案。
  • 我有最后一个问题要问你。如果你能做到这一点,你会让我的工作更轻松。
  • 当你有像这里stackoverflow.com/questions/7546050/…这样的两个框架,并且你想使用菜单路径在两个框架中显示相同的图像,你有示例代码吗?
  • @Jena 我添加了另一个示例。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-08-02
  • 1970-01-01
  • 2020-09-09
  • 1970-01-01
  • 2022-11-14
  • 2018-10-03
  • 1970-01-01
相关资源
最近更新 更多