TheGui实例没有属性'read'
TheGui instance has no attribute 'read'
我们正在制作一个程序,将一张图片粘贴到另一张图片上。我们的问题是试图存储文件名。我们有一个资源管理器函数,它将文件路径存储到变量 wow 和 wink 中。然后我们 运行 程序并得到错误:
AttributeError: TheGui instance has no attribute 'read'
这是我们的代码:
import Tkinter
from Tkinter import *
import subprocess
import sys
import tkFileDialog
import PIL
import matplotlib.pyplot as plt # single use of plt is commented out
import os.path
import PIL.ImageDraw
import PIL.Image
bg_size = [1080,1920]
logo_size = [200,200]
seal_size = [200,200]
seal = 0
class TheGui:
global wow
global wink
wow = ""
wink = ""
global in_path
global in_path1
def __init__(self, parent):
#------- frmSetup ----------#
self.frmSetup = Frame(parent, bd=5)
self.frmSetup.pack()
self.inChoices = ('Text', 'Midi')
self.varRadio = IntVar()
self.r1 = Radiobutton(self.frmSetup, text="Convert Text INPUT into Midi OUTPUT",
variable=self.varRadio, value=0, command=self.selRadio)
self.r1.pack(anchor=W)
self.r2 = Radiobutton(self.frmSetup, text="Convert Midi INPUT into Text OUTPUT",
variable=self.varRadio, value=1, command=self.selRadio)
self.r2.pack(anchor=W)
#------- frmSetup ----------#
sep = Frame(parent, width=1, bd=5, bg='black')
sep.pack(fill=X, expand=1)
#------- frmIn ----------#
# http://effbot.org/tkinterbook/tkinter-widget-styling.htm
self.frmIn = Frame(parent, bd=5)
self.frmIn.pack()
self.lblIn = Label(self.frmIn, text='Campaign Background', width=20)
self.lblIn.pack(side=LEFT)
self.inFilePath = StringVar() # http://effbot.org/tkinterbook/entry.htm
self.entIn = Entry(self.frmIn, width=20, textvariable=self.inFilePath)
self.entIn.pack(side=LEFT)
self.btnIn = Button(self.frmIn, text='Browse', command=self.OpenExplorer)
self.btnIn.pack(side=LEFT)
#------- frmIn ----------#
#------- frmOut ----------#
self.frmOut = Frame(parent, bd=5)
self.frmOut.pack()
self.lblOut = Label(self.frmOut, text='Logo Path', width=20)
self.lblOut.pack(side=LEFT)
self.outFilePath = StringVar()
self.entOut = Entry(self.frmOut, width=20, textvariable=self.outFilePath)
self.entOut.pack(side=LEFT)
self.btnOut = Button(self.frmOut, text='Browse', command=self.OpenExplorer1)
self.btnOut.pack(side=LEFT)
#------- frmOut ----------#
sep = Frame(parent, width=1, bd=5, bg='black')
sep.pack(fill=X, expand=1)
#------- frmButtons ----------#
self.frmOut = Frame(parent, bd=5)
self.frmOut.pack()
self.btnConvert = Button(self.frmOut,
text='Convert', command=self.test(wow,wink))
self.btnConvert.pack()
#------- handle commands ----------#
def selRadio(self):
self.lblIn.config(text = self.inChoices[self.varRadio.get()]
+ ' Input File Path')
self.lblOut.config(text = self.inChoices[(self.varRadio.get()+1)%2]
+ ' Output File Path')
print str(self.varRadio.get())
def btnInBrowseClick(self):
rFilepath = askopenfilename(defaultextension='*',
initialdir='.', initialfile='', parent=self.frmIn, title='select a file')
self.inFilePath.set(rFilepath)
print self.entIn.get()
def btnOutBrowseClick(self):
rFilepath = asksaveasfilename(defaultextension='*',
initialdir='.', initialfile='', parent=self.frmIn, title='select a file')
self.outFilePath.set(rFilepath)
print self.entOut.get()
def btnConvertClick(self):
if self.varRadio.get() == 0:
inputTextFilePath = str(self.inFilePath.get())
outputMidiFilePath = str(self.outFilePath.get())
print 'midi 4 txt', inputTextFilePath, outputMidiFilePath
midi24txt.mid4txt(inputTextFilePath, outputMidiFilePath)
else:
inputMidiFilePath = str(self.inFilePath.get())
outputTextFilePath = str(self.outFilePath.get())
print 'midi 2 txt', inputMidiFilePath, outputTextFilePath
midi24txt.mid2txt(inputMidiFilePath, outputTextFilePath)
def OpenExplorer(self):
def main():
Tkinter.Tk().withdraw() # Close the root window
in_path = tkFileDialog.askopenfilename()
wow = in_path
print wow , "\n"
outFilePath.insert(wow)
if __name__ == "__main__":
main()
def OpenExplorer1(self):
def main():
Tkinter.Tk().withdraw() # Close the root window
in_path1 = tkFileDialog.askopenfilename()
wink = in_path1
print wink , "\n"
if __name__ == "__main__":
main()
def test(main_image, logo_image, self):
logo = PIL.Image.open(main_image)
main = PIL.Image.open(logo_image)
img_w, img_h = main_image.size
if seal == 0:
print("We converting a banner its lit")
offset = (0,780)
main.paste(logo, offset)
main.save('out.png')
main.show()
else:
logo.resize(seal_size)
offset = (0,600)
print("We are converting a seal over here")
root = Tk()
my_gui = TheGui(root)
root.mainloop()
主要问题似乎是这一行:
def test(main_image, logo_image, self):
注意 self
总是 必须是第一个参数,因为如果你调用这样的方法
self.test(wow,wink)
这等同于
TheGUI.test(self, wow, wink)
self
参数并不特殊,因为 Python 会自动将当前实例分配给调用 self
的任何参数。相反,当前实例总是作为 first 参数传递(仅按照惯例称为 self
)。这意味着,您 认为 是 main_image
,实际上是 self
,即您的 UI class 的当前实例。
这给我们带来了下一个问题。在这一行中:
self.btnConvert = Button(self.frmOut,
text='Convert', command=self.test(wow,wink))
当您 创建 按钮然后分配给 command
时,您执行函数 self.test(wow,wink)
一次 该调用的结果。相反,您必须创建一个匿名函数:
self.btnConvert = Button(self.frmOut,
text='Convert', command=lambda: self.test(wow,wink))
另一个问题:您在 class 中使用 global
的方式不起作用。这将使 而不是 以 Java 方式使 wow
和 wink
变量 "static"。如果你想使用 global
,你必须将它放入每个使用这些变量的方法中。相反,我建议制作实例的那些变量,即 self.wow
和 self.wink
:
self.btnConvert = Button(self.frmOut,
text='Convert', command=self.test(self.wow, self.wink))
因此在 OpenExplorer
和其他方法中:
def OpenExplorer(self):
Tkinter.Tk().withdraw() # Close the root window
in_path = tkFileDialog.askopenfilename()
self.wow = in_path
print self.wow , "\n"
outFilePath.insert(self.wow)
此外,这些方法不需要 main
方法和 if __name__ == "__main__"
检查。每当你打开一个 Tkinter window 时都不需要这个检查,它只是看文件是直接执行的还是由另一个脚本导入的。现在的情况是,UI 从另一个模块导入时将不起作用。
请注意,我没有尝试 运行 您的代码;这些正是立即引起我注意的问题。如果后续遇到什么问题,欢迎大家留言。
我们正在制作一个程序,将一张图片粘贴到另一张图片上。我们的问题是试图存储文件名。我们有一个资源管理器函数,它将文件路径存储到变量 wow 和 wink 中。然后我们 运行 程序并得到错误:
AttributeError: TheGui instance has no attribute 'read'
这是我们的代码:
import Tkinter
from Tkinter import *
import subprocess
import sys
import tkFileDialog
import PIL
import matplotlib.pyplot as plt # single use of plt is commented out
import os.path
import PIL.ImageDraw
import PIL.Image
bg_size = [1080,1920]
logo_size = [200,200]
seal_size = [200,200]
seal = 0
class TheGui:
global wow
global wink
wow = ""
wink = ""
global in_path
global in_path1
def __init__(self, parent):
#------- frmSetup ----------#
self.frmSetup = Frame(parent, bd=5)
self.frmSetup.pack()
self.inChoices = ('Text', 'Midi')
self.varRadio = IntVar()
self.r1 = Radiobutton(self.frmSetup, text="Convert Text INPUT into Midi OUTPUT",
variable=self.varRadio, value=0, command=self.selRadio)
self.r1.pack(anchor=W)
self.r2 = Radiobutton(self.frmSetup, text="Convert Midi INPUT into Text OUTPUT",
variable=self.varRadio, value=1, command=self.selRadio)
self.r2.pack(anchor=W)
#------- frmSetup ----------#
sep = Frame(parent, width=1, bd=5, bg='black')
sep.pack(fill=X, expand=1)
#------- frmIn ----------#
# http://effbot.org/tkinterbook/tkinter-widget-styling.htm
self.frmIn = Frame(parent, bd=5)
self.frmIn.pack()
self.lblIn = Label(self.frmIn, text='Campaign Background', width=20)
self.lblIn.pack(side=LEFT)
self.inFilePath = StringVar() # http://effbot.org/tkinterbook/entry.htm
self.entIn = Entry(self.frmIn, width=20, textvariable=self.inFilePath)
self.entIn.pack(side=LEFT)
self.btnIn = Button(self.frmIn, text='Browse', command=self.OpenExplorer)
self.btnIn.pack(side=LEFT)
#------- frmIn ----------#
#------- frmOut ----------#
self.frmOut = Frame(parent, bd=5)
self.frmOut.pack()
self.lblOut = Label(self.frmOut, text='Logo Path', width=20)
self.lblOut.pack(side=LEFT)
self.outFilePath = StringVar()
self.entOut = Entry(self.frmOut, width=20, textvariable=self.outFilePath)
self.entOut.pack(side=LEFT)
self.btnOut = Button(self.frmOut, text='Browse', command=self.OpenExplorer1)
self.btnOut.pack(side=LEFT)
#------- frmOut ----------#
sep = Frame(parent, width=1, bd=5, bg='black')
sep.pack(fill=X, expand=1)
#------- frmButtons ----------#
self.frmOut = Frame(parent, bd=5)
self.frmOut.pack()
self.btnConvert = Button(self.frmOut,
text='Convert', command=self.test(wow,wink))
self.btnConvert.pack()
#------- handle commands ----------#
def selRadio(self):
self.lblIn.config(text = self.inChoices[self.varRadio.get()]
+ ' Input File Path')
self.lblOut.config(text = self.inChoices[(self.varRadio.get()+1)%2]
+ ' Output File Path')
print str(self.varRadio.get())
def btnInBrowseClick(self):
rFilepath = askopenfilename(defaultextension='*',
initialdir='.', initialfile='', parent=self.frmIn, title='select a file')
self.inFilePath.set(rFilepath)
print self.entIn.get()
def btnOutBrowseClick(self):
rFilepath = asksaveasfilename(defaultextension='*',
initialdir='.', initialfile='', parent=self.frmIn, title='select a file')
self.outFilePath.set(rFilepath)
print self.entOut.get()
def btnConvertClick(self):
if self.varRadio.get() == 0:
inputTextFilePath = str(self.inFilePath.get())
outputMidiFilePath = str(self.outFilePath.get())
print 'midi 4 txt', inputTextFilePath, outputMidiFilePath
midi24txt.mid4txt(inputTextFilePath, outputMidiFilePath)
else:
inputMidiFilePath = str(self.inFilePath.get())
outputTextFilePath = str(self.outFilePath.get())
print 'midi 2 txt', inputMidiFilePath, outputTextFilePath
midi24txt.mid2txt(inputMidiFilePath, outputTextFilePath)
def OpenExplorer(self):
def main():
Tkinter.Tk().withdraw() # Close the root window
in_path = tkFileDialog.askopenfilename()
wow = in_path
print wow , "\n"
outFilePath.insert(wow)
if __name__ == "__main__":
main()
def OpenExplorer1(self):
def main():
Tkinter.Tk().withdraw() # Close the root window
in_path1 = tkFileDialog.askopenfilename()
wink = in_path1
print wink , "\n"
if __name__ == "__main__":
main()
def test(main_image, logo_image, self):
logo = PIL.Image.open(main_image)
main = PIL.Image.open(logo_image)
img_w, img_h = main_image.size
if seal == 0:
print("We converting a banner its lit")
offset = (0,780)
main.paste(logo, offset)
main.save('out.png')
main.show()
else:
logo.resize(seal_size)
offset = (0,600)
print("We are converting a seal over here")
root = Tk()
my_gui = TheGui(root)
root.mainloop()
主要问题似乎是这一行:
def test(main_image, logo_image, self):
注意 self
总是 必须是第一个参数,因为如果你调用这样的方法
self.test(wow,wink)
这等同于
TheGUI.test(self, wow, wink)
self
参数并不特殊,因为 Python 会自动将当前实例分配给调用 self
的任何参数。相反,当前实例总是作为 first 参数传递(仅按照惯例称为 self
)。这意味着,您 认为 是 main_image
,实际上是 self
,即您的 UI class 的当前实例。
这给我们带来了下一个问题。在这一行中:
self.btnConvert = Button(self.frmOut,
text='Convert', command=self.test(wow,wink))
当您 创建 按钮然后分配给 command
时,您执行函数 self.test(wow,wink)
一次 该调用的结果。相反,您必须创建一个匿名函数:
self.btnConvert = Button(self.frmOut,
text='Convert', command=lambda: self.test(wow,wink))
另一个问题:您在 class 中使用 global
的方式不起作用。这将使 而不是 以 Java 方式使 wow
和 wink
变量 "static"。如果你想使用 global
,你必须将它放入每个使用这些变量的方法中。相反,我建议制作实例的那些变量,即 self.wow
和 self.wink
:
self.btnConvert = Button(self.frmOut,
text='Convert', command=self.test(self.wow, self.wink))
因此在 OpenExplorer
和其他方法中:
def OpenExplorer(self):
Tkinter.Tk().withdraw() # Close the root window
in_path = tkFileDialog.askopenfilename()
self.wow = in_path
print self.wow , "\n"
outFilePath.insert(self.wow)
此外,这些方法不需要 main
方法和 if __name__ == "__main__"
检查。每当你打开一个 Tkinter window 时都不需要这个检查,它只是看文件是直接执行的还是由另一个脚本导入的。现在的情况是,UI 从另一个模块导入时将不起作用。
请注意,我没有尝试 运行 您的代码;这些正是立即引起我注意的问题。如果后续遇到什么问题,欢迎大家留言。