community icon indicating copy to clipboard operation
community copied to clipboard

Kivy ProgressBar-value doesn't get updated when kwargs' position switched.

Open ApuCoder opened this issue 4 years ago • 12 comments

I'm using Kivy (v-2.0.0) [Python (v-3.9.7)].

The problem I noticed the unexpected behaviour (behavior) when initialized the ProgressBar with the attrs. max and value with different order such as ProgressBar(max = 1000, value = 450) or ProgressBar(value = 450, max = 1000). They both render different result.

What I tried but didn't work I tried to bind the attr. "max" with the AliasProperty value, setting different cache values, but none of them seem to work for me. I think (not quite sure) this problem arises due to the setter method.

What seems to work I changed the attr. value to BoundedNumericProperty as BoundedNumericProperty(0.0, min = 0, errorvalue = 0) and redefine it in the init as

    def __init__(self, **kwargs):
        #self._value = 0.
        super(ProgressBar, self).__init__(**kwargs)
        self.value = min(self.max, self.value) # To limit the upper-value of the attr: value within attr: max.

Now I got the result in both cases as expected.

Executable (for the original problem)

from kivy.app import runTouchApp
from kivy.uix.progressbar import ProgressBar

pb = ProgressBar(max = 1000, value = 450) # This works as intended.
#pb = ProgressBar(value = 450, max = 1000) # This does not work as intended.
print(f"{pb.max = }, {pb.value = }")

runTouchApp(pb)

ApuCoder avatar Jan 24 '22 16:01 ApuCoder

Well, I noticed again this doesn't solve the issue completely, as the attr. value can be (made) unbounded above at runtime.

ApuCoder avatar Jan 24 '22 19:01 ApuCoder

Looks to me like you are calling the super() in the wrong class. You should be seeing something in the logs about this.

kuzeyron avatar Jan 26 '22 16:01 kuzeyron

No, actually I did it in source code of ProgressBar after observing that odd behaviour. Did you also notice that same behaviour after altering the position of kwargs ?

ApuCoder avatar Jan 26 '22 18:01 ApuCoder

No, actually I did it in source code of ProgressBar after observing that odd behaviour. Did you also notice that same behaviour after altering the position of kwargs ?

Not the best practice on editing the source code of Kivy. Here is one example that works:

from kivy.app import App
from kivy.properties import NumericProperty
from kivy.uix.progressbar import ProgressBar


class MyProgressBar(ProgressBar):
    max = NumericProperty(20)
    value = NumericProperty(50)
    default = NumericProperty(1)

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.value = min(self.max, self.value) if self.value <= self.max else self.default


class ProgressBarTest(App):

    def build(self):

        return MyProgressBar()


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

kuzeyron avatar Jan 27 '22 11:01 kuzeyron

It looks like I failed to describe the problem properly. I ran the above code (Executable (for the original problem)) as described in the source code of ProgressBar. But when change the kwargs (as above) I noticed that behaviour.

ApuCoder avatar Jan 27 '22 16:01 ApuCoder

Not a problem on my end:

from kivy.app import App
from kivy.properties import NumericProperty
from kivy.uix.progressbar import ProgressBar


class MyProgressBar(ProgressBar):
    max = NumericProperty(20)
    value = NumericProperty(50)
    default = NumericProperty(1)

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.value = min(self.max, self.value) if self.value <= self.max else self.default


class ProgressBarTest(App):

    def build(self):

        return MyProgressBar(value=20, max=50)


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

Now try changing the direction. If there are other variables/functions you need from ProgressBar you just add them in there. Or write it like this:

from kivy.app import App
from kivy.properties import NumericProperty
from kivy.uix.progressbar import ProgressBar


class MyProgressBar(ProgressBar):
    max = NumericProperty(20)
    value = NumericProperty(50)
    default = NumericProperty(1)

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.value = min(self.max, self.value) if self.value <= self.max else self.default


class ProgressBarTest(App):

    def build(self):
        root = MyProgressBar()
        root.value = 20
        root.max = 70

        return root


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

kuzeyron avatar Jan 27 '22 17:01 kuzeyron

Alas ! Yet again I failed to describe the problem,

Ok, when I run,

from kivy.app import runTouchApp
from kivy.uix.progressbar import ProgressBar

pb = ProgressBar(max = 1000, value = 450) # This works as intended.
print(f"{pb.max = }, {pb.value = }")

runTouchApp(pb)

I got, pb.max = 1000, pb.value = 450.

But when I did,

from kivy.app import runTouchApp
from kivy.uix.progressbar import ProgressBar

pb = ProgressBar(value = 450, max = 1000) # This does not work as intended.
print(f"{pb.max = }, {pb.value = }")

runTouchApp(pb)

I got, pb.max = 1000, pb.value = 100.0

Please, just let me know if this is an error from my side or really a bug.

ApuCoder avatar Jan 27 '22 17:01 ApuCoder

Thank you! Now I understand the problem. I will look into the source code. But for now you can use:

from kivy.app import runTouchApp
from kivy.uix.progressbar import ProgressBar
from kivy.properties import NumericProperty

class MyProg(ProgressBar):
    value = NumericProperty(0)


if __name__ == '__main__':
    pb = MyProg(value=450, max=1000) # This does not work as intended.
    print(f"{pb.max = }, {pb.value = }")

    runTouchApp(pb)

kuzeyron avatar Jan 27 '22 18:01 kuzeyron

Yes that's why I tried changing AliasProperty by BoundedNumericProperty.

ApuCoder avatar Jan 27 '22 18:01 ApuCoder

As I had a conversation on Discord with the Core-Devs. They suggested updating the documentation page and being specific about what you said about placing the arguments in the right order.

kuzeyron avatar Feb 14 '22 18:02 kuzeyron

I will argue that value should be allowed to be modified by user i.e. it should be a NumericProperty (or at least BoundedNumericProperty with min = 0 maybe) instead of the current AliasProperty.

ApuCoder avatar Mar 02 '22 14:03 ApuCoder

This issue has been automatically closed because there has been no response to our request for more information from the original author. With only the information that is currently in the issue, we don't have the means to take action. Please reach out if you have or find the answers we need so that we can investigate further.

github-actions[bot] avatar Dec 14 '23 20:12 github-actions[bot]