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 方式使 wowwink 变量 "static"。如果你想使用 global,你必须将它放入每个使用这些变量的方法中。相反,我建议制作实例的那些变量,即 self.wowself.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 从另一个模块导入时将不起作用。


请注意,我没有尝试 运行 您的代码;这些正是立即引起我注意的问题。如果后续遇到什么问题,欢迎大家留言。