Verschiedene mp3 auf Knopf abspielen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Kampfgummibaerlie
User
Beiträge: 27
Registriert: Freitag 18. Juni 2021, 14:44

Also, ich bin einmal wieder dran, und beschäftige mich jetzt bereits ein wenig mti OOP...

Mein Problem derzeit wäre, dass er mir einen Fehler ausgibt, wenn ich einen anderen als den zuerst gewählten Knopf wähle =(

Hier mein aktueller Code:

Code: Alles auswählen

import tkinter as tk
import playsound as playsound


class Tier:
    def __init__(self, name, lebensraum):
        self.name = name
        self.lebensraum = lebensraum

    def ton(self):
        print("Noch kein Ton vorhanden!")


class Katze(Tier):
    def __init__(self):
        super().__init__("Katze", "Land")

    def ton(self):
        print("Miau")
        playsound.playsound("miau.mp3")


class Hund(Tier):
    def __init__(self):
        super().__init__("Hund", "Land")

    def ton(self):
        print("Wuff Wuff")
        playsound.playsound("bellen.mp3")


root = tk.Tk()

katze = Katze()
katzebtn = tk.Button(root, text="Katze", command=katze.ton)
katzebtn.pack()

hund = Hund()
hundebtn = tk.Button(root, text="Hund", command=hund.ton)
hundebtn.pack()

root.mainloop()
Hier der ausgegebene Fehler:

Code: Alles auswählen

playsound.PlaysoundException: 
    Error 263 for command:
        open bellen.mp3
    Gerät ist nicht geöffnet oder wird vom MCI nicht erkannt.
Ich denke mir, dass ich die zuerst ausgeführte Datei irgendwie schließen muss (?)
Ansonsten frage ich mich, wieso das Gerät zuerst gefunden wird, dann aber nichtmehr...

Ich freue mich auch auf andere Lösungswege, weil ich denke, dass es nicht zwangshaft notwendig wäre, die 2 Objekte am Ende (bei mir die Variablen katze und hund) zu erstellen, bevor man deren Funktion aufrufen kann ;)

Danke, Kampfgummibaerlie
Benutzeravatar
__blackjack__
User
Beiträge: 13270
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Kampfgummibaerlie: Das Problem hat ja eher weniger mit OOP oder GUI zu tun, sondern mit `playsound()` das mehrfach aufgerufen wird.
Please call it what it is: copyright infringement, not piracy. Piracy takes place in international waters, and involves one or more of theft, murder, rape and kidnapping. Making an unauthorized copy of a piece of software is not piracy, it is an infringement of a government-granted monopoly.
imonbln
User
Beiträge: 149
Registriert: Freitag 3. Dezember 2021, 17:07

Ich denke, auch das es ein Problem mit playsound ist und nicht OOP bedingt.
Playsound sollte eigentlich Blockieren währen es einen Sound spielt. Aber da esfür Mac/Windows/Linux intern sehr unterschiedliche Codepfade gibt, wirst du das wahrscheinlich selbst runter debuggen dürfen.

Was eine Basisklasse angeht, warum implementieren Hund und Katze die Methode "ton" selbst, kann man das nicht in der Basisklasse einmal generisch implementieren? Spontan würde ich ungefähr sowas implementieren, mit der Annahme das es auch nicht nur Landlebewesen in deinem Programm geben kann, sondern auch Fische die Stumm sind. Sollte die Annahme falsch sein, würde ich die Methode "ton" in der Basisklasse selbst implementieren.

Code: Alles auswählen

from abc import ABC, abstractmethod
from dataclasses import dataclass


@dataclass
class Stimme:
    laut: str 
    soundfile: str 


class Tier(ABC):

    def __init__(self, name: str):
        self.name = name

    @property
    @abstractmethod
    def lebensraum(self) -> str:
        ...


class LandTier(Tier):

    def __init__(self, name: str, stimme: Stimme):
        super().__init__(name)
        self.stimme = sound

    @property
    def lebensraum(self) -> str:
        return "Land"

    def ton(self):
        print(self.stimme.laut)
        playsound.playsound(self.stimme.soundfile)


class Katze(LandTier):

    def __init__(self):
        stimme = Stimme("Miau", "miau.mp3")
        super().__init__("Katze", stimme)


class Hund(LandTier):

    def __init__(self):
        stimme = Stimme("Wuff Wuff", "bellen.mp3")
        super().__init__("Hund", stimme)

Abgesehen davon, haben Hund & Katze genau die gleichen Eigenschaften, wenn diese nicht noch eigene Methode bekommen. Würde ich beide als (Land)Tier instanziieren und keine eigene Klasse für beide erzeugen.
Sirius3
User
Beiträge: 17844
Registriert: Sonntag 21. Oktober 2012, 17:20

Ziemlich viel Code, dafür dass die Klassen nichts machen.

Code: Alles auswählen

class Tier:
    def __init__(self, name, lebensraum, laut, soundfile):
        self.name = name
        self.lebensraum = lebensraum
        self.laut = laut
        self.soundfile = soundfile

    def ton(self):
        print(self.laut)
        playsound.playsound(self.soundfile)

def maim():
    katze = Tier("Katze", "Land", "Miau", "miau.mp3")
    hund = Tier("Hund", "Land", "Wuff Wuff", "bellen.mp3")
    root = tk.Tk()
    tk.Button(root, text="Katze", command=katze.ton).pack()
    tk.Button(root, text="Hund", command=hund.ton).pack()
    root.mainloop()
    
if __name__ = "__main__":
    main()
Der Fehler ist in den Issues auf github beschrieben. Vielleicht suchst Du dir einfach ein anderes Modul zum Soundabspielen.
imonbln
User
Beiträge: 149
Registriert: Freitag 3. Dezember 2021, 17:07

Sirius3 hat geschrieben: Dienstag 26. April 2022, 19:09 Ziemlich viel Code, dafür dass die Klassen nichts machen.
Kommt darauf an (TM), wenn es darum geht das praktisch zu implementieren bin ich bei dir. Da würde ich es auch mit einer Klasse und mehren Instanzen der gleichen Klasse machen, aber Kampfgummibaerlie will OOP lernen und da ist Vererbung eine wichtige Lektion.
Und weißt du, ob es nicht noch andere Methoden gibt, die in diesem simplen Beispiel einfach nicht gezeigt worden sind? Denn vererben ist nur sinnvoll, wenn es, nachdem SOLID-Prinzip Erweiterungen in geerbten Klassen gibt.
Kampfgummibaerlie
User
Beiträge: 27
Registriert: Freitag 18. Juni 2021, 14:44

Danke für eure Kommentare!

Mit dem Modul "pygame" habe ich es zum laufen gebracht :D

Danke euch ;)

Dachte, es liegt aus irgendeinem Grund, weil ich die Datei am Ende nicht schließe, oder so, lag aber offenbar am Modul ;)

Wenn ich das Ganze auch mit dem modul pygame schreiben sollte (45 Zeilen), einfach nachfragen ;)
Antworten