Python 在OOP方法中使用Tkinter

Python 在OOP方法中使用Tkinter,python,oop,tkinter,Python,Oop,Tkinter,现在我知道了如何使用在stack overflow(多亏了stack overflow)中找到的代码创建框架并请求目录路径和文件名。我需要路径和文件名(由用户选择)在脚本中的其他位置。代码如下: import Tkinter, Tkconstants, tkFileDialog class TkFileDialogExample(Tkinter.Frame): def __init__(self, root): Tkinter.Frame.__init__(self, root)

现在我知道了如何使用在stack overflow(多亏了stack overflow)中找到的代码创建框架并请求目录路径和文件名。我需要路径和文件名(由用户选择)在脚本中的其他位置。代码如下:

import Tkinter, Tkconstants, tkFileDialog
class TkFileDialogExample(Tkinter.Frame):

  def __init__(self, root):
    Tkinter.Frame.__init__(self, root)

    # define buttons
    Tkinter.Button(self, text='askopenfilename', command=self.askopenfilename).pack()
    Tkinter.Button(self, text='askdirectory', command=self.askdirectory).pack()

  def askopenfilename(self):
    self.file = tkFileDialog.askopenfilename()

  def askdirectory(self):
    self.path = tkFileDialog.askdirectory()

if __name__=='__main__':
    root = Tkinter.Tk()
    TkFileDialogExample(root).pack()
    root.mainloop()
myFileDialog = TkFileDialogExample(root)
print myFileDialog.file
但我不知道的是,如何在类之外使用路径和文件名? 这样我就得到了这个错误:

 Traceback (most recent call last):
  File "C:\Users\xxx .py", line 24, in <module>
    myFileDialog = TkFileDialogExample(root)
  File "C:\Users\xxx.py", line 5, in __init__
    Tkinter.Frame.__init__(self, root)
  File "C:\Python27\ArcGIS10.1\lib\lib-tk\Tkinter.py", line 2453, in __init__
    Widget.__init__(self, master, 'frame', cnf, {}, extra)
  File "C:\Python27\ArcGIS10.1\lib\lib-tk\Tkinter.py", line 1974, in __init__
    (widgetName, self._w) + extra + self._options(cnf))
TclError: can't invoke "frame" command:  application has been destroyed
回溯(最近一次呼叫最后一次):
文件“C:\Users\xxx.py”,第24行,在
myFileDialog=TkFileDialogExample(根目录)
文件“C:\Users\xxx.py”,第5行,在\uuu init中__
Tkinter.Frame.\uuuuu init\uuuuu(self,root)
文件“C:\Python27\ArcGIS10.1\lib\lib-tk\Tkinter.py”,第2453行,在__
Widget.\uuuu init\uuuuuu(self、master、'frame',cnf、{}、extra)
文件“C:\Python27\ArcGIS10.1\lib\lib-tk\Tkinter.py”,第1974行,在__
(widgetName,self._w)+额外+自选项(cnf))
Tcl错误:无法调用“frame”命令:应用程序已被销毁

先谢谢你

一种快速而肮脏的方法是使用脚本主体中定义的
global
变量,然后在
mainloop
期间进行设置。在本例中,我使用字典将所需的所有数据存储在单个变量中

import Tkinter, Tkconstants, tkFileDialog
class TkFileDialogExample(Tkinter.Frame):

  def __init__(self, root):
    Tkinter.Frame.__init__(self, root)

    # define buttons
    Tkinter.Button(self, text='askopenfilename',
                   command=self.askopenfilename).pack()
    Tkinter.Button(self, text='askdirectory',
                   command=self.askdirectory).pack()

    self.file = '' # initialize attributes as empty strings
    self.path = '' #

    global outputValues

  def askopenfilename(self):
    self.file = tkFileDialog.askopenfilename() # set attribute
    outputValues['file'] = self.file           # set element of global variable
    print self.file

  def askdirectory(self):
    self.path = tkFileDialog.askdirectory()    # set attribute
    outputValues['path'] = self.path           # set element of global variable
    print self.path

if __name__=='__main__':
    root = Tkinter.Tk()
    TkFileDialogExample(root).pack()
    myFileDialog = TkFileDialogExample(root)
    outputValues = {}                          # define global variable
    myPath = myFileDialog.path
    root.mainloop()
    for key, val in outputValues.iteritems():  # the mainloop is over, but
        print key, val                         # the data you set is still
                                               # available
缺点是,通常全局变量会“污染”名称空间,使其难以跟踪bug,因此它们通常会受到反对。也许其他用户可以提供更好的方法

第一版 我建议您在
\uuuu init\uuuu
方法中初始化属性
路径
文件
,并在按下按钮时将它们设置为用户输入的值

import Tkinter, Tkconstants, tkFileDialog
class TkFileDialogExample(Tkinter.Frame):

  def __init__(self, root):
    Tkinter.Frame.__init__(self, root)

    # define buttons
    Tkinter.Button(self, text='askopenfilename',
                   command=self.askopenfilename).pack()
    Tkinter.Button(self, text='askdirectory',
                   command=self.askdirectory).pack()

    self.file = '' # initialize attributes as empty strings
    self.path = '' #

  def askopenfilename(self):
    self.file = tkFileDialog.askopenfilename() # set attribute
    print self.file

  def askdirectory(self):
    self.path = tkFileDialog.askdirectory()    # set attribute
    print self.path

if __name__=='__main__':
    root = Tkinter.Tk()
    TkFileDialogExample(root).pack()         # these lines must be *before*
    myFileDialog = TkFileDialogExample(root) # root.mainloop()
    root.mainloop()
关于您得到的错误,重要的部分是:

TclError: can't invoke "frame" command:  application has been destroyed
它告诉您,一旦关闭窗口(即退出
根对象的
主循环
),您就不能再引用
根对象,因此无法将另一个子对象(
myFileDialog=TkFileDialogExample(root)
)附加到该窗口。

只需将这两行移到
root.mainloop
之前,即对象仍然存在的位置。

一种快速而肮脏的方法是使用脚本主体中定义的
全局
变量,然后在
mainloop
期间设置该变量。在本例中,我使用字典将所需的所有数据存储在单个变量中

import Tkinter, Tkconstants, tkFileDialog
class TkFileDialogExample(Tkinter.Frame):

  def __init__(self, root):
    Tkinter.Frame.__init__(self, root)

    # define buttons
    Tkinter.Button(self, text='askopenfilename',
                   command=self.askopenfilename).pack()
    Tkinter.Button(self, text='askdirectory',
                   command=self.askdirectory).pack()

    self.file = '' # initialize attributes as empty strings
    self.path = '' #

    global outputValues

  def askopenfilename(self):
    self.file = tkFileDialog.askopenfilename() # set attribute
    outputValues['file'] = self.file           # set element of global variable
    print self.file

  def askdirectory(self):
    self.path = tkFileDialog.askdirectory()    # set attribute
    outputValues['path'] = self.path           # set element of global variable
    print self.path

if __name__=='__main__':
    root = Tkinter.Tk()
    TkFileDialogExample(root).pack()
    myFileDialog = TkFileDialogExample(root)
    outputValues = {}                          # define global variable
    myPath = myFileDialog.path
    root.mainloop()
    for key, val in outputValues.iteritems():  # the mainloop is over, but
        print key, val                         # the data you set is still
                                               # available
缺点是,通常全局变量会“污染”名称空间,使其难以跟踪bug,因此它们通常会受到反对。也许其他用户可以提供更好的方法

第一版 我建议您在
\uuuu init\uuuu
方法中初始化属性
路径
文件
,并在按下按钮时将它们设置为用户输入的值

import Tkinter, Tkconstants, tkFileDialog
class TkFileDialogExample(Tkinter.Frame):

  def __init__(self, root):
    Tkinter.Frame.__init__(self, root)

    # define buttons
    Tkinter.Button(self, text='askopenfilename',
                   command=self.askopenfilename).pack()
    Tkinter.Button(self, text='askdirectory',
                   command=self.askdirectory).pack()

    self.file = '' # initialize attributes as empty strings
    self.path = '' #

  def askopenfilename(self):
    self.file = tkFileDialog.askopenfilename() # set attribute
    print self.file

  def askdirectory(self):
    self.path = tkFileDialog.askdirectory()    # set attribute
    print self.path

if __name__=='__main__':
    root = Tkinter.Tk()
    TkFileDialogExample(root).pack()         # these lines must be *before*
    myFileDialog = TkFileDialogExample(root) # root.mainloop()
    root.mainloop()
关于您得到的错误,重要的部分是:

TclError: can't invoke "frame" command:  application has been destroyed
它告诉您,一旦关闭窗口(即退出
根对象的
主循环
),您就不能再引用
根对象,因此无法将另一个子对象(
myFileDialog=TkFileDialogExample(root)
)附加到该窗口。

只需将这两行移到
root.mainloop
之前,即对象仍然存在的位置。

要在类之外使用文件名,只需将其保存为属性,然后调用instace即可:

#Here we are outside the class

if __name__=='__main__':
   root = Tkinter.Tk()
   myFileDialog = TkFileDialogExample(root)
   myFileDialog.pack()
   print myFileDialog.file
   root.mainloop()

要在类外使用文件名,只需将其另存为属性,然后调用instace即可获得:

#Here we are outside the class

if __name__=='__main__':
   root = Tkinter.Tk()
   myFileDialog = TkFileDialogExample(root)
   myFileDialog.pack()
   print myFileDialog.file
   root.mainloop()

将它们保存为属性,如
self.path=
,然后询问类实例:
myFileDialog=TkFileDialogExample(root);myFileDialog.path
@Pier Paolo非常感谢您。我照你说的做了,修改了密码。但我还是有错误。我在上面的主要问题中显示了错误消息。将它们保存为属性,如
self.path=
,然后询问类实例:
myFileDialog=TkFileDialogExample(root);myFileDialog.path
@Pier Paolo非常感谢您。我照你说的做了,修改了密码。但我还是有错误。我在上面的主要问题中显示了错误消息。非常感谢您抽出时间。代码是有效的。但是我需要的是在类之外使用路径(self.path)。当我合上相框的时候。非常感谢你抽出时间。代码是有效的。但是我需要的是在类之外使用路径(self.path)。当我合上相框时。