【问题标题】:Kivy: Update widgets in a class from outside?Kivy:从外部更新类中的小部件?
【发布时间】:2017-12-20 13:54:20
【问题描述】:

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

如果您运行下面的代码,选择顶部按钮,然后在弹出窗口中选择“完成”,顶部按钮永远不会被移除,但函数会被调用

问题:

每次我从JobDialogMyWidget 中调用函数refreshList 时,我可以看到该函数正在运行,但我认为它打开了一个新实例,我看不到它构建了什么!这看起来应该很简单。写更多的意大利面,我只是无济于事!

任何输入?我必须在 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()

【问题讨论】:

  • 您能否制作一个仅包含您的问题的简单可运行示例?
  • 好的,简化了。更好?
  • 您永远不会删除 refreshList 方法中的顶部按钮
  • 是的。这不是问题...这对我有帮助:stackoverflow.com/questions/23994233/… 我想我快到了!

标签: android python kivy


【解决方案1】:

终于明白了! 当您不了解它们的工作原理时,很难使用类进行编程。我没有调用app.my_widget.refreshList()(因为我在 App 类中定义了它),而是调用了self.my_widget.refreshList(),一旦我在上面定义了它以从另一个类继承“self”!听起来很简单。以下是感兴趣的人的工作代码:

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()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-12-06
    • 2020-01-13
    • 2018-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-06
    相关资源
    最近更新 更多