Forum Archive

How to make a loading bar?

ccb_2k18

Hi all. I tried to demo a loading bar using a ShapeNode class. I used self.w as a variable for the width but it won’t update its width when I run the code. What must I change/add?

```
from scene import *
import scene
import ui

class load_bar(scene.ShapeNode):
def init(self, kwargs):
self.w = 0
super().init(path=ui.Path.rect(0,0,self.w,5), fill_color='white', stroke_color=None, shadow=None,
kwargs)

class MyScene (Scene):
def setup(self):
self.background_color = 'grey'
self.load = load_bar(position=(200,200), parent=self)
self.load.anchor_point = (0,0)
self.load.w = 0
def update(self):
while self.load.w < 100.0:
self.load.w += 1

if name == 'main':
run(MyScene(), show_fps=False)```

cvp

@ccb_2k18 little error: your while forces to perform the 100 iterations in the same update, thus instantly, use if instead while

    def update(self):
        if self.load.w < 100.0:
ccb_2k18

@cvp Thanks, but it doesn’t seem to make a difference either way. But I did figure it out using the line() function which is much more simple. However the layer it draws on is always behind the spritenode background. How could I bring it to the front using scene or ui? I looked at a few examples similar to mine years ago but the functions they called seemed to have been removed from pythonista.

cvp

@ccb_2k18 Sure it does à difference.
With this if instead of the while, the script runs ok

cvp

Please post your code with the line(), I don't understand

ccb_2k18

I don’t know why it is the case, but even when I run it with the if statement you posted, nothing happens. It is like I cannot modify self.w after the init function, because I attempted altering it in setup with self.load.w but it did not affect the rectangle.

```
from scene import *
import scene
import ui

class load_bar(scene.ShapeNode):
def init(self, kwargs):
self.w = 0
super().init(path=ui.Path.rect(0,0,self.w,5), fill_color='white', stroke_color=None, shadow=None,
kwargs)

class MyScene (Scene):
def setup(self):
self.background_color = 'grey'
self.load = load_bar(position=(200,200), parent=self)
self.load.anchor_point = (0,0)
self.load.w = 0
def update(self):
if self.load.w < 100.0:
self.load.w += 1

if name == 'main':
run(MyScene(), show_fps=False)```

ccb_2k18

Here is the code for the alternate method. The line moves like a loading bar but it draws behind the sprite image.

```
from scene import *
import scene
import ui

class MyScene (Scene):
def setup(self):
self.background_color = 'grey'
self.sprite = SpriteNode('test:Boat', position=(self.size.w/2, self.size.h/2), scale=3.0, parent=self)
self.x = 200
def draw(self):
stroke('white')
stroke_weight(2)
line(200, 200, self.x, 200)
self.x += 1
if self.x > 400:
self.x = 400

if name == 'main':
run(MyScene(), show_fps=False)```

JonB

ShapeNodes do not have an attribute w. You defines some attribute, abd it was incremented, but you didn't like it to anything that affects the actual width of the node.

Try self.size.width, and self.load.size.width

Also, you realize that update runs every 1/60 of a second, so your bar will take just under 2 seconds to work.

cvp

Sorry', I did forget I also added one line in my code

    def update(self):
        if self.load.w < 100.0:
            self.load.w += 1
            self.load.size = (self.load.w,5)
ccb_2k18

@cvp Thanks it worked perfectly! And yeah I realized @JonB, now i can adjust parameters since it works. Thank you both very much :)