刷新kivy小部件的问题

时间:2018-03-30 01:06:15

标签: python kivy

我在刷新BoxLayout小部件时遇到问题,方法是删除它们,然后根据列表“Groups”重建小部件。在EditDeviceGroups屏幕上,“创建”按钮应该向列表中添加一个元素,并将用户转发到GroupTemplateScreen,它就是这样。

当用户使用后退按钮返回EditDeviceGroups屏幕时,会出现此问题。那时,我认为on_enter方法会刷新小部件以包含新元素,但列表没有显示任何更改。

我认为这是类和实例的某种问题,但我不能完全看到这一点,因为这是我对Kivy的第一次真正尝试。

soundclout.py

from kivy.app import App
from kivy.properties import ObjectProperty, ListProperty, StringProperty
from kivy.uix.listview import ListItemButton
from kivy.uix.screenmanager import ScreenManager, Screen, WipeTransition
from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.scrollview import ScrollView
from kivy.uix.button import Button,Label
from kivy.graphics import Color,Rectangle,InstructionGroup

class GroupTemplateScreen(Screen):

    def remove(self):
        pass

class HomeScreen(Screen):
    skipBuild = 'build_timeline_screen_6'

    #skips build option if already timeline is already built
    def skip_build_screen(self,value):
        if value is 1:
            print('HomeScreen.skip_build_screen')
            self.skipBuild = 'edit_timeline_screen_7'

class EditDeviceGroupsScreen(Screen):
    #Groups = [GroupNo,null]
    Groups = [[1,10],[2,20]]

    def on_enter(self):
        self.ids.glayout2.clear_widgets()
        for i in xrange(0,len(EditDeviceGroupsScreen().Groups)):
            ##THISPRINT##
            print(str(EditDeviceGroupsScreen().Groups[i][0]))
            addedGroup = BoxLayout(size_hint_y=None,height='120sp',orientation='horizontal')
            addedButton=Button(text="Group " + str(EditDeviceGroupsScreen().Groups[i][0]) + " Settings",font_size=25)
            addedGroup.add_widget(addedButton)
            self.ids.glayout2.add_widget(addedGroup)

    #Removes all widget on leaving to prevent the creation of duplicate widgets
    def nav_to_group(self):
        self.manager.current = 'edit_group_behaviour_screen_9'

    def create_group(self):
        base = 1
        for i in xrange(0,len(EditDeviceGroupsScreen().Groups)):
            if base < EditDeviceGroupsScreen().Groups[i][0]:
                base = EditDeviceGroupsScreen().Groups[i][0]
        EditDeviceGroupsScreen().Groups.append([base+1,(base+1)*10])        

#manages screens
class Manager(ScreenManager):

    home_screen = ObjectProperty()
    edit_device_groups_screen = ObjectProperty()
    group_template_screen= ObjectProperty()

    def update(self):
        self.connected_device_list._trigger_reset_populate()
        self.current_screen.update()

class SoundCloutApp(App):

    def build(self):
        return Manager(transition=WipeTransition())

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

soundclout.kv

#: kivy 1.10.0
#: import hex kivy.utils.get_color_from_hex
#: import main soundclout
#: import ListAdapter kivy.adapters.listadapter.ListAdapter
#: import ListItemButton kivy.uix.listview.ListItemButton
#: import ScrollView kivy.uix.scrollview


<GroupTemplateScreen>:
    rows: 2
    spacing: 10
    canvas:
        Color:
            rgba: 1,1,1,1
        Rectangle:
            pos: self.pos
            size: self.size

    BoxLayout:
        size_hint_y: None
        height: 50
        spacing: 10
        pos: root.x, (root.height-50)

        # Make the background for the toolbar blue
        canvas:
            Color:
                rgba: hex('#0099cc')
            Rectangle:
                pos: self.pos
                size: self.size
        Button:
            on_press: root.manager.current = 'homescreen_1'
            background_normal: 'icons/home.png'
            size_hint_x: None
            width:50

    BoxLayout:
        size_hint_y: None
        height: 500
        spacing: 50
        padding: 20
        pos: root.x, (root.height-560)

        BoxLayout:
            orientation: "vertical"
            spacing: 10
            padding: 10
            canvas:
                Color:
                    rgba: hex('#0099cc')
                Rectangle:
                    pos: self.pos
                    size: self.size

            BoxLayout:
                size_hint_y: None
                orientation: "horizontal"
                height: 50
                spacing: 10
                padding: 0
                canvas:
                    Color:
                        rgba: hex('#0099cc')
                    Rectangle:
                        pos: self.pos
                        size: self.size   
                Button:
                    size_hint_x: None
                    size_hint_y: None
                    height: 50
                    width:100
                    text: 'Back'
                    on_release: root.manager.current = 'edit_device_groups_screen_5'

                Button:
                    size_hint_x: None
                    size_hint_y: None
                    height: 50
                    width:100
                    text: 'Remove'

                    #have to change first arguement, for now assume switch is on
                    on_press: root.remove()
                    on_release:root.manager.current = 'edit_device_groups_screen_5'

            BoxLayout:
                orientation: "vertical"
                spacing: 10
                padding: 10
                canvas:
                    Color:
                        rgba: hex('#ffffff')
                    Rectangle:
                        pos: self.pos
                        size: self.size

                #Devices connected
                BoxLayout:
                    orientation: "horizontal"
                    canvas:
                        Color:
                            rgba: hex('#98a6b3')
                        Rectangle:
                            pos: self.pos
                            size: self.size

                    Label:
                        text: 'Name:'
                        font_size: 24

                        #TODO
                    Label:
                        text: 'Group 1'
                        font_size: 24

                #Devices connected
                BoxLayout:
                    orientation: "horizontal"
                    canvas:
                        Color:
                            rgba: hex('#98a6b3')
                        Rectangle:
                            pos: self.pos
                            size: self.size

                    Label:
                        text: 'Devices:'
                        font_size: 24

                    #TODO
                    Label:
                        text: '1,2,3,4'
                        font_size: 24

<HomeScreen>:
    rows: 2
    spacing: 10
    canvas:
        Color:
            rgba: 1,1,1,1
        Rectangle:
            pos: self.pos
            size: self.size

    BoxLayout:
        size_hint_y: None
        height: 50
        spacing: 10
        pos: root.x, (root.height-50)

        # Make the background for the toolbar blue
        canvas:
            Color:
                rgba: hex('#0099cc')
            Rectangle:
                pos: self.pos
                size: self.size
        Button:
            on_press: root.manager.current = 'homescreen_1'
            background_normal: 'icons/home.png'
            size_hint_x: None
            width:50

    BoxLayout:
        size_hint_y: None
        height: 500
        spacing: 50
        padding: 50
        pos: root.x, (root.height-560)

        BoxLayout:
            orientation: "vertical"
            spacing: 10
            padding: 10
            canvas:
                Color:
                    rgba: hex('#0099cc')
                Rectangle:
                    pos: self.pos
                    size: self.size

            Button:
                text: "Start"
                font_size: 20

            Button:
                text: "Device Tester"
                font_size: 20

            Button:
                text: "Connect Devices"
                font_size: 20

            Button:
                text: "Edit Device Groups"
                font_size: 20
                on_press: root.manager.current = 'edit_device_groups_screen_5'

            Button:
                text: "Edit Group Behavior"
                font_size: 20

        BoxLayout:
            orientation: "vertical"
            spacing: 10
            padding: 10
            canvas:
                Color:
                    rgba: hex('#0099cc')
                Rectangle:
                    pos: self.pos
                    size: self.size
            Label:
                text: "Connected Devices"
                font_size: 30

<EditDeviceGroupsScreen>:
    rows: 2
    spacing: 10
    canvas:
        Color:
            rgba: 1,1,1,1
        Rectangle:
            pos: self.pos
            size: self.size

    #ToolBar
    BoxLayout:
        size_hint_y: None
        height: 50
        spacing: 10
        pos: root.x, (root.height-50)

        # Make the background for the toolbar blue
        canvas:
            Color:
                rgba: hex('#0099cc')
            Rectangle:
                pos: self.pos
                size: self.size
        Button:
            on_press: root.manager.current = 'homescreen_1'
            background_normal: 'icons/home.png'
            size_hint_x: None
            width:50

    BoxLayout:
        size_hint_y: None
        height: 500
        spacing: 50
        padding: 20
        pos: root.x, (root.height-560)

        BoxLayout:
            orientation: "vertical"
            spacing: 10
            padding: 10
            canvas:
                Color:
                    rgba: hex('#0099cc')
                Rectangle:
                    pos: self.pos
                    size: self.size
            Button:
                size_hint_x: None
                size_hint_y: None
                height: 50
                size: self.size
                text: 'create group'
                on_press: main.EditDeviceGroupsScreen().create_group()
                on_release: root.manager.current = 'group_template_screen_11'

            #Groups holder
            BoxLayout:
                orientation: "vertical"
                spacing: 5
                padding: 5
                canvas:
                    Color:
                        rgba: hex('#ffffff')
                    Rectangle:
                        pos: self.pos
                        size: self.size

                #Adds Scrollability
                ScrollView:
                    do_scroll_x:False
                    do_scroll_Y:True
                    BoxLayout:
                        id: glayout2
                        orientation: 'vertical'
                        spacing: 5
                        size_hint_y: None
                        height: self.minimum_height


<Manager>:
    id: screen_manager
    home_screen: home_screen
    edit_device_groups_screen: edit_device_groups_screen
    group_template_screen: group_template_screen

    HomeScreen:
        id: home_screen
        name: 'homescreen_1'
        manager: screen_manager

    EditDeviceGroupsScreen:
        id: edit_device_groups_screen
        name: 'edit_device_groups_screen_5'
        manager: screen_manager

    GroupTemplateScreen:
        id: group_template_screen
        name: 'group_template_screen_11'
        manager: screen_manager

1 个答案:

答案 0 :(得分:0)

问题

EditDeviceGroups 屏幕不会使用新添加的小部件刷新,因为按 Back 按钮时,会实例化另一个 EditDeviceGroupScreen 实例。

解决方案

通过以下更改,当用户单击后退按钮返回到EditDeviceGroups屏幕时, on_enter 方法刷新窗口小部件以包含添加的新元素。有关详细信息,请参阅示例和输出。

soundclout.kv

  1. 已删除 #:import main soundclout
  2. main.EditDeviceGroupsScreen()。create_group() 替换为 root.create_group()
  3. soundclout.py

    1. 将所有 EditDeviceGroupsScreen()。 替换为 self。
    2. 实施例

      main.py

      from kivy.app import App
      from kivy.properties import ObjectProperty, ListProperty, StringProperty
      from kivy.uix.listview import ListItemButton
      from kivy.uix.screenmanager import ScreenManager, Screen, WipeTransition
      from kivy.uix.gridlayout import GridLayout
      from kivy.uix.boxlayout import BoxLayout
      from kivy.uix.scrollview import ScrollView
      from kivy.uix.button import Button, Label
      from kivy.graphics import Color, Rectangle, InstructionGroup
      
      
      class GroupTemplateScreen(Screen):
      
          def remove(self):
              pass
      
      
      class HomeScreen(Screen):
          skipBuild = 'build_timeline_screen_6'
      
          # skips build option if already timeline is already built
          def skip_build_screen(self, value):
              if value is 1:
                  print('HomeScreen.skip_build_screen')
                  self.skipBuild = 'edit_timeline_screen_7'
      
      
      class EditDeviceGroupsScreen(Screen):
          # Groups = [GroupNo, null]
          Groups = [[1, 10], [2, 20]]
      
          def on_enter(self):
              print("EditDeviceGroupsScreen.on_enter:")
              self.ids.glayout2.clear_widgets()
              for i in range(0, len(self.Groups)):
                  ##THISPRINT##
                  print(str(self.Groups[i][0]))
                  addedGroup = BoxLayout(size_hint_y=None, height='120sp', orientation='horizontal')
                  addedButton = Button(text="Group " + str(self.Groups[i][0]) + " Settings", font_size=25)
                  addedGroup.add_widget(addedButton)
                  self.ids.glayout2.add_widget(addedGroup)
      
          # Removes all widget on leaving to prevent the creation of duplicate widgets
          def nav_to_group(self):
              self.manager.current = 'edit_group_behaviour_screen_9'
      
          def create_group(self):
              base = 1
              for i in range(0, len(self.Groups)):
                  if base < self.Groups[i][0]:
                      base = self.Groups[i][0]
              self.Groups.append([base+1, (base+1)*10])
      
      
      # manages screens
      class Manager(ScreenManager):
      
          home_screen = ObjectProperty()
          edit_device_groups_screen = ObjectProperty()
          group_template_screen= ObjectProperty()
      
          def update(self):
              self.connected_device_list._trigger_reset_populate()
              self.current_screen.update()
      
      
      class SoundCloutApp(App):
      
          def build(self):
              return Manager(transition=WipeTransition())
      
      
      if __name__ == '__main__':
          SoundCloutApp().run()
      

      soundclout.kv

      #:kivy 1.10.0
      #:import hex kivy.utils.get_color_from_hex
      #:import ListAdapter kivy.adapters.listadapter.ListAdapter
      #:import ListItemButton kivy.uix.listview.ListItemButton
      #:import ScrollView kivy.uix.scrollview
      
      
      <GroupTemplateScreen>:
          rows: 2
          spacing: 10
          canvas:
              Color:
                  rgba: 1,1,1,1
              Rectangle:
                  pos: self.pos
                  size: self.size
      
          BoxLayout:
              size_hint_y: None
              height: 50
              spacing: 10
              pos: root.x, (root.height-50)
      
              # Make the background for the toolbar blue
              canvas:
                  Color:
                      rgba: hex('#0099cc')
                  Rectangle:
                      pos: self.pos
                      size: self.size
              Button:
                  on_press: root.manager.current = 'homescreen_1'
                  background_normal: 'icons/home.png'
                  size_hint_x: None
                  width:50
      
          BoxLayout:
              size_hint_y: None
              height: 500
              spacing: 50
              padding: 20
              pos: root.x, (root.height-560)
      
              BoxLayout:
                  orientation: "vertical"
                  spacing: 10
                  padding: 10
                  canvas:
                      Color:
                          rgba: hex('#0099cc')
                      Rectangle:
                          pos: self.pos
                          size: self.size
      
                  BoxLayout:
                      size_hint_y: None
                      orientation: "horizontal"
                      height: 50
                      spacing: 10
                      padding: 0
                      canvas:
                          Color:
                              rgba: hex('#0099cc')
                          Rectangle:
                              pos: self.pos
                              size: self.size
                      Button:
                          size_hint_x: None
                          size_hint_y: None
                          height: 50
                          width:100
                          text: 'Back'
                          on_release: root.manager.current = 'edit_device_groups_screen_5'
      
                      Button:
                          size_hint_x: None
                          size_hint_y: None
                          height: 50
                          width:100
                          text: 'Remove'
      
                          #have to change first arguement, for now assume switch is on
                          on_press: root.remove()
                          on_release:root.manager.current = 'edit_device_groups_screen_5'
      
                  BoxLayout:
                      orientation: "vertical"
                      spacing: 10
                      padding: 10
                      canvas:
                          Color:
                              rgba: hex('#ffffff')
                          Rectangle:
                              pos: self.pos
                              size: self.size
      
                      #Devices connected
                      BoxLayout:
                          orientation: "horizontal"
                          canvas:
                              Color:
                                  rgba: hex('#98a6b3')
                              Rectangle:
                                  pos: self.pos
                                  size: self.size
      
                          Label:
                              text: 'Name:'
                              font_size: 24
      
                              #TODO
                          Label:
                              text: 'Group 1'
                              font_size: 24
      
                      #Devices connected
                      BoxLayout:
                          orientation: "horizontal"
                          canvas:
                              Color:
                                  rgba: hex('#98a6b3')
                              Rectangle:
                                  pos: self.pos
                                  size: self.size
      
                          Label:
                              text: 'Devices:'
                              font_size: 24
      
                          #TODO
                          Label:
                              text: '1,2,3,4'
                              font_size: 24
      
      <HomeScreen>:
          rows: 2
          spacing: 10
          canvas:
              Color:
                  rgba: 1,1,1,1
              Rectangle:
                  pos: self.pos
                  size: self.size
      
          BoxLayout:
              size_hint_y: None
              height: 50
              spacing: 10
              pos: root.x, (root.height-50)
      
              # Make the background for the toolbar blue
              canvas:
                  Color:
                      rgba: hex('#0099cc')
                  Rectangle:
                      pos: self.pos
                      size: self.size
              Button:
                  on_press: root.manager.current = 'homescreen_1'
                  background_normal: 'icons/home.png'
                  size_hint_x: None
                  width:50
      
          BoxLayout:
              size_hint_y: None
              height: 500
              spacing: 50
              padding: 50
              pos: root.x, (root.height-560)
      
              BoxLayout:
                  orientation: "vertical"
                  spacing: 10
                  padding: 10
                  canvas:
                      Color:
                          rgba: hex('#0099cc')
                      Rectangle:
                          pos: self.pos
                          size: self.size
      
                  Button:
                      text: "Start"
                      font_size: 20
      
                  Button:
                      text: "Device Tester"
                      font_size: 20
      
                  Button:
                      text: "Connect Devices"
                      font_size: 20
      
                  Button:
                      text: "Edit Device Groups"
                      font_size: 20
                      on_press: root.manager.current = 'edit_device_groups_screen_5'
      
                  Button:
                      text: "Edit Group Behavior"
                      font_size: 20
      
              BoxLayout:
                  orientation: "vertical"
                  spacing: 10
                  padding: 10
                  canvas:
                      Color:
                          rgba: hex('#0099cc')
                      Rectangle:
                          pos: self.pos
                          size: self.size
                  Label:
                      text: "Connected Devices"
                      font_size: 30
      
      <EditDeviceGroupsScreen>:
          rows: 2
          spacing: 10
          canvas:
              Color:
                  rgba: 1,1,1,1
              Rectangle:
                  pos: self.pos
                  size: self.size
      
          #ToolBar
          BoxLayout:
              size_hint_y: None
              height: 50
              spacing: 10
              pos: root.x, (root.height-50)
      
              # Make the background for the toolbar blue
              canvas:
                  Color:
                      rgba: hex('#0099cc')
                  Rectangle:
                      pos: self.pos
                      size: self.size
              Button:
                  on_press: root.manager.current = 'homescreen_1'
                  background_normal: 'icons/home.png'
                  size_hint_x: None
                  width:50
      
          BoxLayout:
              size_hint_y: None
              height: 500
              spacing: 50
              padding: 20
              pos: root.x, (root.height-560)
      
              BoxLayout:
                  orientation: "vertical"
                  spacing: 10
                  padding: 10
                  canvas:
                      Color:
                          rgba: hex('#0099cc')
                      Rectangle:
                          pos: self.pos
                          size: self.size
                  Button:
                      size_hint_x: None
                      size_hint_y: None
                      height: 50
                      size: self.size
                      text: 'create group'
                      on_press: root.create_group()
                      on_release: root.manager.current = 'group_template_screen_11'
      
                  #Groups holder
                  BoxLayout:
                      orientation: "vertical"
                      spacing: 5
                      padding: 5
                      canvas:
                          Color:
                              rgba: hex('#ffffff')
                          Rectangle:
                              pos: self.pos
                              size: self.size
      
                      #Adds Scrollability
                      ScrollView:
                          do_scroll_x:False
                          do_scroll_Y:True
                          BoxLayout:
                              id: glayout2
                              orientation: 'vertical'
                              spacing: 5
                              size_hint_y: None
                              height: self.minimum_height
      
      
      <Manager>:
          id: screen_manager
          home_screen: home_screen
          edit_device_groups_screen: edit_device_groups_screen
          group_template_screen: group_template_screen
      
          HomeScreen:
              id: home_screen
              name: 'homescreen_1'
              manager: screen_manager
      
          EditDeviceGroupsScreen:
              id: edit_device_groups_screen
              name: 'edit_device_groups_screen_5'
              manager: screen_manager
      
          GroupTemplateScreen:
              id: group_template_screen
              name: 'group_template_screen_11'
              manager: screen_manager
      

      输出

      Img01 - App Startup Img02 - Clicked Button EditDeviceGroups Img03 - Clicked Button CreateGroup Img04 - Clicked Button Back