Получение NameError при попытке изменить переменную класса во внешней функции - PullRequest
0 голосов
/ 05 декабря 2018

В настоящее время я работаю над созданием музыкального автомата / музыкального проигрывателя на python.Чтобы сделать код более организованным, я разбил его на определенные классы.Некоторые из внешних функций требуют доступа к переменным класса и их обновления.Однако программа выдает следующую ошибку:

 File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/tkinter/__init__.py", line 1702, in __call__
    return self.func(*args)
  File "jukeboxDraft.py", line 77, in nextSong
    constructGUI.index += 1
NameError: name 'constructGUI' is not defined

Классы и функции, обращающиеся к переменным класса, находятся в следующем блоке кода:

import os
import pygame
from tkinter.filedialog import askdirectory
from tkinter import *
import eyed3

class JukeboxContent:
    def __init__(self):
        listOfSongs = []
        songTitles = []
        directory = askdirectory()
        self.listOfSongs = listOfSongs
        self.songTitles = songTitles
        self.directoryAsk = directory
        self.Error_NoMP3s = "No \".mp3\" files found."

    def directoryChooser(self):
        self.directoryAsk
        os.chdir(self.directoryAsk)

        for files in os.listdir(self.directoryAsk):
            if files.endswith(".mp3"):
                realdir = os.path.realpath(files)
                audioTag = eyed3.load(realdir)
                self.songTitles.append(audioTag.tag.title)
                self.listOfSongs.append(files)
                #print(files)

        pygame.mixer.init()
        pygame.mixer.music.load(self.listOfSongs[0])
        pygame.mixer.music.play()



class JukeboxGUI(JukeboxContent):
    index = 0
    def __init__(self, window):
        JukeboxContent.__init__(self)
        self.back = Frame(master = window, width=500, height=500,  bg='pink')
        self.label = Label(window, text = "Jukebox")
        self.listBox = Listbox(window)
        self.nextButton = Button(window, text = "Next Song")
        self.previousButton = Button(window, text = "Previous Song")
        self.stopButton = Button(window, text = "Stop")
        self.labelVar = StringVar()
        self.songLabel= Label(window, textvariable = self.labelVar, width = 50)

    def constructButtons(self):
        self.back.pack()
        self.label.pack()
        self.listBox.pack()
        for items in self.listOfSongs:
            self.listBox.insert(END, items)
        self.nextButton.pack()
        self.previousButton.pack()
        self.stopButton.pack()

    def updateLabel(self):
        self.labelVar.set(self.songTitles[self.index])

#-------------------------JUKEBOX FUNCTIONS-------------------------------------


def main():
    window = Tk()
    window.title("Jukebox")
    initiateJukebox = JukeboxContent()
    initiateJukebox.directoryChooser()
    constructGUI = JukeboxGUI(window)
    constructGUI.constructButtons()
    constructGUI.nextButton.bind("<Button-1>", nextSong)
    constructGUI.previousButton.bind("<Button-1>", previousSong)
    constructGUI.stopButton.bind("<Button-1>", stopSong)
    window.mainloop()

def nextSong(event):
    constructGUI.index += 1
    pygame.mixer.music.load(initiateJukebox.listOfSongs[constructGUI.index])
    pygame.mixer.music.play()
    constructGUI.updateLabel()

def previousSong(event):
    constructGUI.index -= 1
    pygame.mixer.music.load(initiateJukebox.listOfSongs[constructGUI.index])
    pygame.mixer.music.play()
    constructGUI.updateLabel()

def stopSong(event):
    pygame.mixer.music.stop()
    constructGUI.labelVar.set("")



if __name__ == '__main__':
    main()

Как мне отредактировать мой "JukeboxGUI "класс или переменная" constructGUI ", чтобы решить эту проблему?Есть идеи?

Ответы [ 2 ]

0 голосов
/ 05 декабря 2018

constructGUI только существует в пределах main().Вы не передаете его другим функциям, чтобы они не знали, что это такое.

Делаете constructGUI объектом уровня модуля, чтобы каждый может видеть это.

if __name__ == '__main__':
    #main()
    window = Tk()
    window.title("Jukebox")
    initiateJukebox = JukeboxContent()
    initiateJukebox.directoryChooser()
    constructGUI = JukeboxGUI(window)
    constructGUI.constructButtons()
    constructGUI.nextButton.bind("<Button-1>", nextSong)
    constructGUI.previousButton.bind("<Button-1>", previousSong)
    constructGUI.stopButton.bind("<Button-1>", stopSong)
    window.mainloop()

Вот некоторые вещи из документов для чтения: Именование и связывание , Слово об именах и объектах и ​​Области Python и пространства имен.

0 голосов
/ 05 декабря 2018

constructGUI определено в main, поэтому оно не будет доступно вне этой функции.

Сделать constructGUI глобальной переменной, поместив заполнитель вне функции в глобальную область.Если вам нужно изменить его внутри функции (которая выглядит так, как вы), обязательно добавьте global constructGUI в начало этой функции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...