(1) By using the following kv file version was able to place BorderImage
widget at the specified position..
<Screen>:
ProgressBar:
max: 100
pos_hint: {'top':0.86, 'x':0.01}
size_hint_x: 0.49
size_hint_y: 0.1
canvas:
BorderImage:
border: (10, 10, 10, 10)
pos: self.x, self.center_y
size: self.width, 8
source: '0.png'
(2) But, the following Pure Python code that should realize the same function as (1) doesn't work properly.BorderImage
widget is placed at the bottom of the screen.
pos_hint={'top':0.86,'x':0.01}
doesn't work.
I think that how to specify pos=(bar.x, bar.center_y)
is not good because bar.center_y
value is different from the code of (1).
class BarWidget(FloatLayout):
def __init__(self, **kwargs):
super(BarWidget, self).__init__(**kwargs)
self.build()
def build(self):
bar = ProgressBar(pos_hint={'top':0.86,'x':0.01}, max=100, size_hint_x=0.49, size_hint_y=0.1)
with bar.canvas:
BorderImage(border=(10, 10, 10, 10), pos=(bar.x, bar.center_y), size=(self.width/2, 8), source='0.png')
self.add_widget(bar)
How should I modify bar.center_y
?
In the kv language, when you set an attribute like size: self.size
, this attribute is automatically updated whenever the 'self' widget changes size of shape. When things are loading up in a screen/layout, they start with funky positions and sizes then move to be correct. Since things automatically update upon changing sizes/positions if you work in kv, it works as you expect.
In python, you have to explicitly bind some function to update the canvas if the size or position of the widget it's inheriting its size and pos from changes. You can do that by using the bind
function (available in most/all kivy widgets). Using bind
, you can say bind(<attribute>=<function>)
which means anytime the widget's <attribute>
, aka size or pos, is changed, it calls the <function>
I didn't test this exactly with your code since not all of it is posted, but this is what I do for my projects. Let me know how it works. If it doesn't work, edit your answer to be a snippet of code that I can copy/paste to work with and I'll update my answer.
class BarWidget(FloatLayout):
def __init__(self, **kwargs):
super(BarWidget, self).__init__(**kwargs)
self.build()
def build(self):
# Make it so you can reference the bar and border image later
self.bar = ProgressBar(pos_hint={'top':0.86,'x':0.01}, max=100, size_hint_x=0.49, size_hint_y=0.1)
with self.bar.canvas:
# Make it so you can reference the border image
self.border_image = BorderImage(border=(10, 10, 10, 10), pos=(bar.x, bar.center_y), size=(self.width, 8), source='0.png')
self.add_widget(self.bar)
# Make it so whenever the widget's pos or size changes, we update the border image
self.bar.bind(pos=self.update_border_image, size=self.update_border_image)
# make a function to update border image
def update_border_image(self, *args):
self.border_image.size = (self.width, 8) # Should this 8 be 0.8 by the way?
self.border_image.pos = (self.bar.x, self.bar.center_y)