eric paris
eric paris

Reputation: 61

screen update in screen manager

i'm using kivy for building an app screen with 3 screens. my main screen ( class Base) is showing data from a SQL request. i would like the user to be able to update these data using a button. first this class Base is called in the screen manager which is itself called in my root class. So my question is , how do i clear the data in my class Base and update it with the new data?

i tried to clear the data in my class screen manager. the refresh function is called from the root class. i have the below error: 'ScreenManager uses remove_widget only for removing Screens'

from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from sql import runsql2
from kivy.core.window import Window

    class Manager(ScreenManager):
        def __init__(self):
            super(Manager, self).__init__()

            for i in range(2):
                txt = 'Screen {}'.format(i)
                lbl = Label(text=txt)
                screen = Screen(name=txt)
                screen.add_widget(lbl)
                self.add_widget(screen)

            base=Base('main')
            self.add_widget(base)

        def refresh(self):
            self.clear_widgets(screens='main')
            base=Base('main')
            self.add_widget(base)


    class Nav(GridLayout):

        def __init__(self,sm=None):
            super(Nav, self).__init__()

            self.sm = sm
            self.cols =3
            self.size_hint = (1,0.1)
            self.add_widget(Button(text="Clearing Screen", on_release=self.change))
            self.add_widget(Button(text="Go screen 2", on_release=self.goscreen))
            self.add_widget(Button(text="Quit", on_release=self.quit))

        def change(self, btn):
            #self.sm.current = btn.text
            self.sm.current='main'

        def quit(self,ins):
            exit()

        def goscreen(self,ins):
            self.sm.current='Screen 1'

    class Base(Screen):
        def __init__(self,name):
            super(Base, self).__init__()
            self.lay=GridLayout()
            self.name=name
            self.bout=['[color=33ff99]Refresh[/color]','',"","","","","","","","",""]
            self.data=runsql2()
            self.lay.cols = 11
            self.titre=['[color=ff9900]Market[/color]', '[color=ff9900]B/S[/color]', '[color=ff9900]Volume[/color]', '[color=ff9900]Contract[/color]',
                        '[color=ff9900]C/P[/color]', '[color=ff9900]Expiry[/color]', '[color=ff9900]Strike[/color]', '[color=ff9900]Price[/color]',
                        '[color=ff9900]Account[/color]', '[color=ff9900]Give up Member[/color]', '[color=ff9900]Allocation Account[/color]']

            #self.lay.add_widget(Button(text='[color=33ff99]Refresh[/color]', size_hint=(1, 0.15), markup=True,on_release=self.do))
            for i in range(11):
                self.lay.add_widget(Label(text='', size_hint=(1, 0.15)))
            for j in range(11):
                self.lay.add_widget(Label(text=str(self.titre[j]),size_hint=(0.2,0.2),markup=True))
            long = len(self.data)
            for i in range(long):
                for j in range(11):
                    self.lay.add_widget(Label(text=str(self.data[i][j])))
            self.add_widget(self.lay)

    class Root(BoxLayout):

        def __init__(self):
            super(Root, self).__init__()
            self.orientation = "vertical"
            #Window.clearcolor = (0.6, 0.6, 0.6,1)
            sm = Manager()

            self.add_widget(Nav(sm=sm))
            self.add_widget(sm)
            self.add_widget(Button(text='refresh',size_hint=(0.2,0.2),on_release=self.refresh))
            Window.size = (1500, 900)

        def refresh(self,ins):
            sm=Manager()
            sm.refresh()

    class TestApp(App):
        def build(App):
            return Root()

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

Upvotes: 1

Views: 4662

Answers (1)

John Anderson
John Anderson

Reputation: 39092

Two problems with your code. First, in your refresh() method, the self.clear_widgets(screens='main') is incorrect. The screens arg must be a list of screens. So it should be

def refresh(self):
    self.clear_widgets(screens=[self.get_screen('main')])
    base=Base('main')
    self.add_widget(base)

Since you are only removing one screen, you could use self.remove_widget(self.get_screen('main')) instead.

And, second, your refresh() method in the Root class is creating a new Manager class and calling the refresh() method of that new Manager rather than the one you have displayed. To correct this, you can save a reference to the original Manager, and use that reference in the refresh() method:

class Root(BoxLayout):

    def __init__(self):
        super(Root, self).__init__()
        self.orientation = "vertical"
        #Window.clearcolor = (0.6, 0.6, 0.6,1)
        sm = Manager()

        self.sm = sm   # keep a reference for later use
        self.add_widget(Nav(sm=sm))
        self.add_widget(sm)
        self.add_widget(Button(text='refresh',size_hint=(0.2,0.2),on_release=self.refresh))
        Window.size = (1500, 900)

    def refresh(self,ins):
        self.sm.refresh()

Upvotes: 1

Related Questions