我们正在制作一个程序,将一个图像粘贴到另一个图像的顶部。我们的问题是尝试存储文件名。我们有一个资源管理器功能,可以将文件路径存储到变量哇和眨眼中。然后我们运行程序并得到错误:
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()
答案 0 :(得分:2)
主要问题似乎是这一行:
def test(main_image, logo_image, self):
请注意,self
总是必须是第一个参数,因为如果你调用这样的方法
self.test(wow,wink)
这相当于
TheGUI.test(self, wow, wink)
self
参数并不特殊,因为Python会自动将当前实例分配给任何名为self
的参数。相反,当前实例始终作为第一个参数传递(仅按惯例称为self
)。这意味着,您的想法是main_image
,实际上是self
,即您的UI类的当前实例。
这将我们带到下一个问题。在这一行:
self.btnConvert = Button(self.frmOut,
text='Convert', command=self.test(wow,wink))
当您创建按钮时执行<{1}} 功能然后分配给self.test(wow,wink)
结果那个调用。相反,您必须创建一个匿名函数:
command
另一个问题:在类中使用self.btnConvert = Button(self.frmOut,
text='Convert', command=lambda: self.test(wow,wink))
的方式不起作用。这将不制作global
和wow
变量&#34;静态&#34;以Java方式。如果要使用wink
,则必须将其放入使用这些变量的每个方法中。相反,我建议制作实例的那些变量,即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
检查。无论何时打开Tkinter窗口,都不需要进行此检查,只是为了查看文件是直接执行还是由其他脚本导入。现在的样子,从其他模块导入时UI不起作用。
请注意,我没有尝试运行您的代码;那些只是立即引起我注意的问题。如果您遇到任何后续问题,请随时发表评论。