community icon indicating copy to clipboard operation
community copied to clipboard

Cant pickle object with SoundLoader

Open YoshioKobayashi opened this issue 1 year ago • 2 comments

Piano C1.zip Software Versions

  • Python: 3.8
  • OS: Win10
  • Kivy: 2.3

Describe the bug Crash occurs when trying to pickel an object that contains a SoundLoader.Sound instance ->

    huh = pickle.dumps(withSL)
   File "<stringsource>", line 2, in kivy._event.EventDispatcher.__reduce_cython__
 TypeError: no default __reduce__ due to non-trivial __cinit__

Expected behavior Not crashing.

To Reproduce Run this code ->

import pickle
import random

from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.widget import Widget
from kivy.uix.stencilview import StencilView
from kivy.graphics import Color, Rectangle
from kivy.core.audio import SoundLoader


class ObjectContainingSoundLoader():
    def __init__(self):
        self.filename = "./piano/Piano C1.mp3"
        self.SL = SoundLoader.load(self.filename)



class leStencil(StencilView):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.size_hint = (None, None)
        self.pos_hint = {}

        # Button ->
        self.btnPosSrc = Button()
        self.btnPosSrc.text = "Play Piano"
        self.btnPosSrc.size_hint = (None, None)
        self.btnPosSrc.pos_hint = {}
        self.btnPosSrc.bind(on_press=self.lePickle)

        self.add_widget(self.btnPosSrc)

        # Debug Color for visibility ->
        with self.canvas:
            self.reqtcolor = Color(0, 1, 0, 0.2)
            self.reqt = Rectangle()
            self.reqt.pos = self.pos
            self.reqt.size = self.size

        self.bind(pos=self.setDebugColorPos)
        self.bind(size=self.setDebugColorPos)

    # Button Moving

    def lePickle(self, x):
        withSL = ObjectContainingSoundLoader()
        huh = pickle.dumps(withSL)
        return


    # GUI Stuff

    def setDebugColorPos(self, x, y):
        self.reqt.pos = self.pos
        self.reqt.size = self.size

    def positionContent(self):
        self.btnPosSrc.x = self.x + (self.width / 2) - self.btnPosSrc.width * 2 / 2
        self.btnPosSrc.y = self.top - self.btnPosSrc.height

    def sizeMyself(self, w, h):
        self.width = w
        self.height = h

    def sizeContent(self):
        self.btnPosSrc.width = self.width * 0.1
        self.btnPosSrc.height = self.height * 0.1


class leMain(Widget):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.stencil = leStencil()
        self.add_widget(self.stencil)

        self.bind(size=self.initSizeAndPos)

    def initSizeAndPos(self, x, y):
        self.stencil.sizeMyself(self.width, self.height / 2)
        self.stencil.positionContent()


class MyApp(App):

    def build(self):
        return leMain()


if __name__ == '__main__':
    MyApp().run()

YoshioKobayashi avatar Feb 29 '24 10:02 YoshioKobayashi

Do we expect pickle to work? I am not sure what it means to pickle a SoundLoader.

Julian-O avatar Apr 14 '24 12:04 Julian-O

I am not sure what it means to pickle a SoundLoader.

Maybe they want to save the SoundLoader object with state(ie. SoundLoader object with sound file loaded)?

baseplate-admin avatar Apr 14 '24 16:04 baseplate-admin