Kivy:从外面更新课程中的小部件?

时间:2017-12-19 23:59:42

标签: android python kivy

看起来这应该很简单,但我已经尝试了一周(真的)来更新类中的一列按钮(从弹出窗口调用)

如果您运行以下代码,请选择顶部按钮,然后选择"完成"在弹出窗口中,从不删除顶部按钮,但通过

调用该函数

问题:

每次我从类refreshList调用类MyWidget中的函数JobDialog时,我都可以看到该函数正在运行,但我认为它打开了一个新实例,我看不到它的构建!看起来应该很简单。我只是写了更多的意大利面而没有到达任何地方!

有什么输入?我是否必须在APP类中定义一些东西?

谢谢你的时间!

这是我的代码(超简化):

from kivy.uix.popup import Popup
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
from kivy.app import App
from kivy.config import Config
from kivy.properties import ObjectProperty
from kivy.uix.image import AsyncImage, Image
from kivy.uix.label import Label


Config.set('graphics', 'fullscreen', '0') #Force Fullscreen off.

#setting up default variables
loggedInUserName = "default usrname"
isLoggedIn = 0

currentProdNum = ""

ResultSet = {
    "1231" : {"name" : "test text asdf", "dateDue" : "", "status" : "0"},

}


Builder.load_string("""

<MyWidget>:
    BoxLayout:
        ScrollView:
            size_hint_x: 500
            do_scroll_x: False
            BoxLayout:
                id: resultScrollList
                cols: 1
                size_hint_y: None
                height: self.minimum_height

""")

class menuScreen(BoxLayout):

    def __init__(self,**kwargs):
        super(menuScreen,self).__init__(**kwargs)
    pass




class MyWidget(BoxLayout):
    login = ObjectProperty()
    def refreshList(self, *kwargs):
        #for the scrollList::
        layout = GridLayout(cols=1, spacing=10, size_hint_y=None)
        # Make sure the height is such that there is something to scroll.
        layout.bind(minimum_height=layout.setter('height'))

        self.orientation = "vertical"

        self.name_input = TextInput(text='name')

        #self.add_widget(self.name_input)

        self.login_button = Button(text="login")
        self.login_button.bind(on_press=self.login)

        self.job_popup = JobDialog(self) # initiation of the popup, and self gets passed

        #self.add_widget(self.login_button)

        #start adding widgets:

        for key, value in ResultSet.items():
            #first create the string for the box:
            if value["status"] == "0":
                print(key)
                l = Label(text='Hello world', font_size='20sp')
                strstr = value['name'] + ' - ' + value['dateDue'] + ' - ' + value['status']
                btn = Button(text=strstr,id=key, size_hint_y=None)
                btn.bind(on_press=self.login)
                layout.add_widget(btn)
                pass
            pass

        self.ids.resultScrollList.clear_widgets()
        #self.ids.resultScrollList.add_widget(layout)
        #root.parent.MyWidget.ids.resultScrollList.add_widget(layout)

    def __init__(self,**kwargs):
        super(MyWidget,self).__init__(**kwargs)

        #for the scrollList::
        layout = GridLayout(cols=1, spacing=10, size_hint_y=None)
        # Make sure the height is such that there is something to scroll.
        layout.bind(minimum_height=layout.setter('height'))

        self.orientation = "vertical"

        self.name_input = TextInput(text='name')

        #self.add_widget(self.name_input)

        self.login_button = Button(text="login")
        self.login_button.bind(on_press=self.login)

        self.job_popup = JobDialog(self) # initiation of the popup, and self gets passed

        #self.add_widget(self.login_button)

        #start adding widgets:

        for key, value in ResultSet.items():
            #first create the string for the box:
            print(key)
            if value["status"] == "0":
                l = Label(text='Hello world', font_size='20sp')
                strstr = value['name'] + ' - ' + value['dateDue'] + ' - ' + value['status']
                btn = Button(text=strstr,id=key, size_hint_y=None)
                btn.bind(on_press=self.login)
                layout.add_widget(btn)
                pass
            pass

        self.ids.resultScrollList.clear_widgets()
        self.ids.resultScrollList.add_widget(layout)

    def login(self, instance):
        global isLoggedIn
        global currentProdNum
        currentProdNum = instance.id
        print("current Prod to modify is %s" % currentProdNum)
        self.job_popup.open()
    pass


class JobDialog(Popup):
    global currentProdNum
    print("current Prod to modify is %s" % str(currentProdNum) )
    tempTitle = loggedInUserName
    title = tempTitle
    def __init__(self,my_widget,**kwargs):  # my_widget is now the object where popup was called from.
        super(JobDialog,self).__init__(**kwargs)
        #my_widget.title='Authenticate'
        self.my_widget = my_widget
        #title='Authenticate', size_hint=(None, None), size=(400, 400)
        self.content = BoxLayout(orientation="vertical")
        self.title = "this is a test"
        aimg = AsyncImage(source='https://upload.wikimedia.org/wikipedia/commons/d/d9/Test.png')

        self.done_button = Button(text='Done')
        self.done_button.bind(on_press=self.DoneAction)

        self.cancel_button = Button(text='Cancel')
        self.cancel_button.bind(on_press=self.cancel)

        self.pass_input = TextInput(text='')

        self.content.add_widget(aimg)
        self.content.add_widget(self.done_button)
        self.content.add_widget(self.cancel_button)


    def DoneAction(self,*args):
        global loginLookupTable
        global loggedInName
        print(" %s selected!" % self.done_button.text) # and you can access all of its attributes
        print("State of Prod:")
        print(ResultSet[currentProdNum]['status'])
        ResultSet[currentProdNum]['status'] = 1
        print('Changed to 1.')
        self.dismiss()
        app = App.get_running_app()
        app.mywidget.refreshList()

    def cancel(self,*args):
        print("cancel")
        self.dismiss()

class MyApp(App):
    mywidget = MyWidget()
    def build(self):
        return MyWidget()


MyApp().run()

1 个答案:

答案 0 :(得分:0)

终于想通了! 当你不了解它们的工作方式时,很难用课程编程。我没有调用app.my_widget.refreshList()(因为我在App类中定义了它而工作),而是在我上面定义它以继承&#34; self&#34;之后,我调用了self.my_widget.refreshList()。来自其他班级!听起来很简单。以下是感兴趣的人的工作代码:

from kivy.uix.popup import Popup
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
from kivy.app import App
from kivy.config import Config
from kivy.properties import ObjectProperty
from kivy.uix.image import AsyncImage, Image
from kivy.uix.label import Label


Config.set('graphics', 'fullscreen', '0') #Force Fullscreen off.

#setting up default variables
loggedInUserName = "default usrname"
isLoggedIn = 0

currentProdNum = ""

ResultSet = {
    "1231" : {"name" : "test text asdf", "dateDue" : "", "status" : "0"},

}


Builder.load_string("""

<MyWidget>:
    BoxLayout:
        ScrollView:
            size_hint_x: 500
            do_scroll_x: False
            BoxLayout:
                id: resultScrollList
                cols: 1
                size_hint_y: None
                height: self.minimum_height

""")

class menuScreen(BoxLayout):

    def __init__(self,**kwargs):
        super(menuScreen,self).__init__(**kwargs)
    pass




class MyWidget(BoxLayout):
    login = ObjectProperty()
    def refreshList(self, *kwargs):
        #for the scrollList::
        layout = GridLayout(cols=1, spacing=10, size_hint_y=None)
        # Make sure the height is such that there is something to scroll.
        layout.bind(minimum_height=layout.setter('height'))

        self.orientation = "vertical"

        self.name_input = TextInput(text='name')

        #self.add_widget(self.name_input)

        self.login_button = Button(text="login")
        self.login_button.bind(on_press=self.login)

        self.job_popup = JobDialog(self) # initiation of the popup, and self gets passed

        #self.add_widget(self.login_button)

        #start adding widgets:

        for key, value in ResultSet.items():
            #first create the string for the box:
            if value["status"] == "0":
                print(key)
                l = Label(text='Hello world', font_size='20sp')
                strstr = value['name'] + ' - ' + value['dateDue'] + ' - ' + value['status']
                btn = Button(text=strstr,id=key, size_hint_y=None)
                btn.bind(on_press=self.login)
                layout.add_widget(btn)
                pass
            pass

        self.ids.resultScrollList.clear_widgets()
        #self.ids.resultScrollList.add_widget(layout)
        #root.parent.MyWidget.ids.resultScrollList.add_widget(layout)

    def __init__(self,**kwargs):
        super(MyWidget,self).__init__(**kwargs)

        #for the scrollList::
        layout = GridLayout(cols=1, spacing=10, size_hint_y=None)
        # Make sure the height is such that there is something to scroll.
        layout.bind(minimum_height=layout.setter('height'))

        self.orientation = "vertical"

        self.name_input = TextInput(text='name')

        #self.add_widget(self.name_input)

        self.login_button = Button(text="login")
        self.login_button.bind(on_press=self.login)

        self.job_popup = JobDialog(self) # initiation of the popup, and self gets passed

        #self.add_widget(self.login_button)

        #start adding widgets:

        for key, value in ResultSet.items():
            #first create the string for the box:
            print(key)
            if value["status"] == "0":
                l = Label(text='Hello world', font_size='20sp')
                strstr = value['name'] + ' - ' + value['dateDue'] + ' - ' + value['status']
                btn = Button(text=strstr,id=key, size_hint_y=None)
                btn.bind(on_press=self.login)
                layout.add_widget(btn)
                pass
            pass

        self.ids.resultScrollList.clear_widgets()
        self.ids.resultScrollList.add_widget(layout)

    def login(self, instance):
        global isLoggedIn
        global currentProdNum
        currentProdNum = instance.id
        print("current Prod to modify is %s" % currentProdNum)
        self.job_popup.open()
    pass


class JobDialog(Popup):
    global currentProdNum
    print("current Prod to modify is %s" % str(currentProdNum) )
    tempTitle = loggedInUserName
    title = tempTitle
    def __init__(self,my_widget,**kwargs):  # my_widget is now the object where popup was called from.
        super(JobDialog,self).__init__(**kwargs)
        #my_widget.title='Authenticate'
        self.my_widget = my_widget
        #title='Authenticate', size_hint=(None, None), size=(400, 400)
        self.content = BoxLayout(orientation="vertical")
        self.title = "this is a test"
        aimg = AsyncImage(source='https://upload.wikimedia.org/wikipedia/commons/d/d9/Test.png')

        self.done_button = Button(text='Done')
        self.done_button.bind(on_press=self.DoneAction)

        self.cancel_button = Button(text='Cancel')
        self.cancel_button.bind(on_press=self.cancel)

        self.pass_input = TextInput(text='')

        self.content.add_widget(aimg)
        self.content.add_widget(self.done_button)
        self.content.add_widget(self.cancel_button)


    def DoneAction(self,*args):
        global loginLookupTable
        global loggedInName
        print(" %s selected!" % self.done_button.text) # and you can access all of its attributes
        print("State of Prod:")
        print(ResultSet[currentProdNum]['status'])
        ResultSet[currentProdNum]['status'] = 1
        print('Changed to 1.')
        self.dismiss()
        self.my_widget.refreshList()

    def cancel(self,*args):
        print("cancel")
        self.dismiss()

class MyApp(App):
    mywidget = MyWidget()
    def build(self):
        return MyWidget()


MyApp().run()