-1

I am having trouble to reload picture or profile of user. The widget that I want to reload is included in the ScreenOne, I create the function for reloading in this class and try to call it from the function in the class Change.

Thank you in advance !

Here is my main.py:

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.image import Image
import readtable
import Readpictureadress
import sizetable
import Match
import nbofpictures
import random
from kivy.uix.screenmanager import ScreenManager, Screen, NoTransition
from kivy.properties import ObjectProperty, NumericProperty, StringProperty
import kivy


size = sizetable.main()
Iduserp = (random.randint(1, size))
imagenb=0
picadress= Readpictureadress.main(Iduserp, 0)

class Manager(ScreenManager):

    screen_one = ObjectProperty(None)
    screen_two = ObjectProperty(None)

class ScreenTwo(Screen):
    print('screentwo')
    pass

class ScreenOne(Screen):
    img = StringProperty()
    global picadress
    global Iduserp


    def __init__(self, **kwargs):
        super(ScreenOne, self).__init__(**kwargs)
        self.img = picadress


    def displayScreenThenLeave(self):
        print('Displayscreen')

        self.changeScreen()

    def changeScreen(self):
        print('changescreen')

        if self.Manager.current == 'screen1':
            self.Manager.current = 'screen2'
        else:
            self.Manager.current = 'screen1'
    pass

    def reloadprofile(self):
        self.img = picadress
        self.ids.a1.reload()


class Change():
    global Iduserp
    global imagenb
    global picadress

    def changeuser(self):

        size = sizetable.main()
        Iduserp = (random.randint(1, size))
        app = App.get_running_app()
        app.screenone.reloadprofile()

    def changepicturenb (self):

        nbofpic = nbofpictures.main(Iduserp)
        if imagenb < nbofpic:
            imagenb += 1
        else:
            imagenb = 0
        app = App.get_running_app()
        app.screenone.reloadprofile()

class ScreensApp(App):
    print('ScreensApp')
    screenone=ScreenOne()
    varChange= Change()
    def build(self):
        m = Manager(transition=NoTransition())
        return m

if __name__ == "__main__":
    ScreensApp().run()

My kivy file:

#:kivy 1.8.0

<ScreenTwo>:

<ScreenOne>:
    stuff_a: a1
    BoxLayout:
        orientation: 'vertical'
        rows: 4
        BoxLayout:
            orientation: 'vertical'
            rows: 1
            size_hint_y: 0.8
            AsyncImage
                id:a1
                source:root.img
                on_touch_down: app.varChange.changepicturenb()

        BoxLayout:
            padding: 10,10,10,0
            spacing: 10
            size_hint: 1,0.3
            orientation: "horizontal"
            Button:
                text: "Clear"
                on_touch_down: app.varChange.changeuser()
            Button:
                text: "Remove"
            Button:
                text: "Group"
            Button:
                text: "Color"
            Button:
                text: "Gestures"


<Manager>:
    id: screen_manager

    screen_one: screen_one
    screen_two: screen_two

    ScreenOne:
        id: screen_one
        name: "screen1"
        manager: screen_manager

    ScreenTwo:
        id: screen_two
        name: "screen2"
        manager: screen_manager

and my error file:

> File "main7.py", line 105, in changeuser
>      app.screenone.reloadprofile()    File "main7.py", line 60, in reloadprofile
>      self.ids.a1.reload()    File "kivy\properties.pyx", line 839, in kivy.properties.ObservableDict.__getattr__ (kivy\properties.c:12654) 
> AttributeError: 'super' object has no attribute '__getattr__'
Fabien
  • 13
  • 6

1 Answers1

1

As @eyllanesc said: please provide a Minimal, Complete, and Verifiable example. It takes much more work for us to figure out what your problem is if we first must just debug your code to get to the point where we can see your problem. But since I am in the mood to play with Kivy:

You have several problems. First, change your ScreensApp

class ScreensApp(App):

    def build(self):
        self.varChange = Change()
        self.m = Manager(transition=NoTransition())
        return self.m

Note that your creation of a ScreenOne is eliminated, because that is created by your <Manager> rule in the kv file. The other statements are moved into the build method and saved as instance variables, since you need them elsewhere. This also allows your reference to app.varChange in your kv file to work.

Also, you need to modify your Change class:

class Change():
    global Iduserp
    global imagenb
    global picadress

    def changeuser(self):

        size = sizetable.main()
        Iduserp = (random.randint(1, size))
        app = App.get_running_app()
        app.m.screen_one.reloadprofile()

    def changepicturenb (self):

        nbofpic = nbofpictures.main(Iduserp)
        if imagenb < nbofpic:
            imagenb += 1
        else:
            imagenb = 0
        app = App.get_running_app()
        app.m.screen_one.reloadprofile()

The reference to ScreenOne is saved in your <Manager> rule in the kv file as screen_one, so to access it you can go through the app, to the m (Manager) reference that was saved in the build method, and then to the screen_one property that was also defined in the <Manager> rule. I think that might fix your problem, but I can't be positive since I had to make changes to the example to get it to the "problem".

John Anderson
  • 35,991
  • 4
  • 13
  • 36
  • Thank you so much for this perfect modification. As soon as I will get more time later, I will modify my post to make a clear example. If I understood clearly, all the screens in my case are accessible from the app since the build method (self.m). Is the self is important in this case? – Fabien Oct 31 '18 at 03:15
  • Yes, the `self` is important. If you just do `m=Manager()` and `return m` in the `build` method, then that `m` is scoped to just the `build` method and is not accessible outside that method. Making it `self.m` creates an instance variable in the `App` instance, that is always available through a reference to the `App` instance. Note that the `Manager` instance is also accessible from either of your `Screen` instances through the `manager` property of any `Screen` instance that has been added to that `Manager`. – John Anderson Oct 31 '18 at 03:34