update existing rectangle source using python

370 views
Skip to first unread message

Grant

unread,
Aug 27, 2014, 2:40:07 PM8/27/14
to kivy-...@googlegroups.com
I have a widget in kv lang:

<FileWidget>:
    canvas.before:
        Rectangle:
            size: self.size
            pos: self.pos
            
    size_hint: None, None
    size: 49, 75 
    pos_hint: {'x':0,'center_y': 0.5}

I am loading the file in python using Builder.
Then I am importing using 'from <kv filename> import FileWidget

Then I am trying to update the source of the rectangle in python:

file_image = FileWidget(…)

I can change its size using:

file_image = FileWidget(size=(49, 75))

But cannot update the canvas.before, Rectangle, source path.

I have tried using:

with file_image.canvas.before:
    Rectangle(source='filename.png')

But this adds a new rectangle and does not update the source of the existing one.

Is there a way to update the existing rectangle?

Thanks.
Message has been deleted

ZenCODE

unread,
Aug 27, 2014, 3:25:59 PM8/27/14
to kivy-...@googlegroups.com
Hi


"I can change its size using:
    file_image = FileWidget(size=(49, 75))"

That just creates a new FileWidget. It does not update the existing one. For that you need to create a reference to the original Rectangle, or use Kivy's property binding. Something like:

<FileWidget>:

    canvas.before:
        Rectangle:
            size: self.size
            pos: self.pos
            source: self.image_source


Then, in your python file:

class FileWidget(Widget):
    image_source
= StringProperty("images/my_image.png")
   
....

Or suchlike. If you're still stuck, please post a runnable, minimal example that we can help get running..;-)

Peace



Grant

unread,
Aug 27, 2014, 3:45:10 PM8/27/14
to kivy-...@googlegroups.com
Hi,

A little difficult to provide a runnable post, as I am using Builder and importing of widgets etc…

I have a file with name widgets.kv that has all of the widgets I use in the application:

<MyFileView>:
 <code>

others

<FileWidget>:
    canvas.before:
        Rectangle:
            size: self.size
            pos: self.pos
            
    size_hint: None, None
    size: 49, 75 
    pos_hint: {'x':0,'center_y': 0.5}

But the main application python file imports those widgets and loads the file using Builder:

from widgets import FileWidget, MyFileView, MyFileLabel

Builder.load_file('widgets.kv')

Then under a class HomeScreen(Screen):
    <code>

I have a function to add widgets together.
    
    def <function>(self, args):
        main_layout = MyFileView() <--- customized Boxlayout
        file_info = MyFileLabel(text=self.file_info(filename))
        file_image = FileWidget()

        main_layout.add_widget(file_image)
        main_layout.add_widget(file_info)
        archive_grid.add_widget(main_layout)

This works fine, except there is no source defined for the FileWidget, its a blank white box.

Thanks,

Grant.

Brian MacDiarmuide

unread,
Aug 27, 2014, 3:51:29 PM8/27/14
to kivy-...@googlegroups.com
What about something like this:

<FileWidget>:
    source: ""

    canvas.before:
        Rectangle:
            size: self.size
            pos: self.pos
            source: root.source

Then in your python code:

file_image = FileWidget()
file_image.source = "newsource.png" # etc.

There may be a mistake here, but you get the idea

Grant

unread,
Aug 27, 2014, 3:57:35 PM8/27/14
to kivy-...@googlegroups.com
Wow that worked!!!!

So the canvas root is the widget, and you created your own property named source. Then accessed it in python like you would size_hint etc…
Hopefully I am understanding the logic correctly.

Thanks for the help!!!

Brian MacDiarmuide

unread,
Aug 27, 2014, 4:05:35 PM8/27/14
to kivy-...@googlegroups.com
Yes, I created a property called source, which, seems to be treated just like a kivy StringProperty... but I'm not sure about that.
The way I understand it, you have three keywords for the kv language when it comes to referring to different scopes: self, root and app

Now, I may be wrong about some of this, but it has been working for me thus far thinking this way:

self:
refers to the immediate parent, in your case, that would be Rectangle.

root:
refers to the root widget, of which there is only ever one. It's the one between the angle brackets. In your case <FileWidget>
I don't think where you refer to this from be it within a canvas block or not etc. if always refers to that root widget.

app:
refers to the app instance, which I have rarely used. But you could read up on all of this to cement the differences.

Hope this helps
Brian
Reply all
Reply to author
Forward
0 new messages