簡體   English   中英

在Kivy中將ScreenManager與RecycleView一起使用

[英]Using the ScreenManager with RecycleView in Kivy

我有一個RecycleView小部件,可以響應觸摸輸入。 我需要RecycleView上的每一行將用戶帶到特定屏幕。 目前,我只有兩個屏幕設置。

這是Python代碼:

class Navigator(NavigationDrawer):
    image_source = StringProperty('images/1canaa.jpg')
    title = StringProperty('Navigation')

# This is the screen that is initiated when the app runs 
class MainScreen(Screen):
    pass

# This is the screen that is suppose to initiate when the first row is 
# touched
class MapScreen(Screen):
    pass


class Manager(ScreenManager):
    main_screen_obj = ObjectProperty(None)
    map_screen_obj = ObjectProperty(None)


class SelectableRecycleBoxLayout(FocusBehavior, LayoutSelectionBehavior,
                             RecycleBoxLayout):
    ''' Adds selection and focus behaviour to the view. '''


class SelectableLabel(RecycleDataViewBehavior, Label):
    ''' Add selection support to the Label '''
    index = None
    selected = BooleanProperty(False)
    selectable = BooleanProperty(True)

    def refresh_view_attrs(self, rv, index, data):
        ''' Catch and handle the view changes '''
        self.index = index
        return super(SelectableLabel, self).refresh_view_attrs(
        rv, index, data)

    def on_touch_down(self, touch):
        ''' Add selection on touch down '''
        if super(SelectableLabel, self).on_touch_down(touch):
            return True
        if self.collide_point(*touch.pos) and self.selectable:
            return self.parent.select_with_touch(self.index, touch)

    def apply_selection(self, rv, index, is_selected):
        ''' Respond to the selection of items in the view. '''
        self.selected = is_selected
        if is_selected:
            print("selection changed to {0}".format(rv.data[index]))
            if rv.data[index] == {'text': 'FIRST ROW'}:
                Manager.current = 'mapScreen'
                print('The evaluation was executed')


        else:
            print("selection removed for {0}".format(rv.data[index]))


class RV(RecycleView):
    def __init__(self, **kwargs):
        super(RV, self).__init__(**kwargs)

        Unidades = ['FIRST ROW', 'SECOND ROW', 'THIRD ROW', 'FORTH ROW']

        self.data = [{'text': x} for x in Unidades]


class Main(App):
    theme_cls = ThemeManager()
    nav_drawer = ObjectProperty()

    def build(self):
        self.nav_drawer = Navigator()
        return Manager()


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

如果查看SelectableLabel類中的apply_selection方法,您將看到我已嘗試通過檢查以下內容進行解決:

if the rv.data[index] == {'text': 'FIRST ROW'}:
    Manager.current = 'mapScreen'
    print('The evaluation was executed')

這沒有用。 請注意,我打印了一條消息以檢查評估是否已經完成,並且確實如此。 當我運行該應用程序時,我收到消息:“評估已執行”。 但是,用戶並未被帶到MapScreen。

這是kv代碼:

#:import MapSource mapview.MapSource
#:import Toolbar kivymd.toolbar.Toolbar
#:import hex kivy.utils.get_color_from_hex


<SelectableLabel>:
# Draw a background to indicate selection
    canvas.before:
        Color:
            rgba: hex('#867979') if self.selected else hex('#808080')
        Rectangle:
            pos: self.pos
            size: self.size


<RV>:
    viewclass: 'SelectableLabel'

    SelectableRecycleBoxLayout:

        default_size: None, dp(56)
        default_size_hint: 1, None
        size_hint_y: None
        height: self.minimum_height
        orientation: 'vertical'
        multiselect: False
        touch_multiselect: True


<MainScreen>:
    BoxLayout:
        orientation: 'vertical'

        Label:
            size_hint: None, None
            height: 45
            width: 100
            pos_hint: {'center_y': 0.5, 'center_x': 0.5}
            text: '[size=40]Unidades de Assistência[/size]'
            color: hex('#676767')
            markup: True
            font_name: 'alex-brush.regular.ttf'

        RV: 

<MapScreen>:
    BoxLayout:
        Label:
            text: 'MapScreen'



<Manager>:
    id: screen_manager
    main_screen_obj: main_screen
    map_screen_obj: map_screen

    MainScreen:
        id: main_screen
        name: 'mainScreen'
        manager: screen_manager


    MapScreen:
        id: map_screen
        name: 'mapScreen'
        manager: screen_manager

因此,我在這里想要完成的工作非常簡單,或者至少應該如此。 歸結為:如果觸摸了第一行,則將用戶帶到MapScreen ...如果觸摸了第二行,則將用戶帶到其他屏幕...依此類推。

我希望這不是很令人困惑。 謝謝你的幫助。

有兩種方法可以解決此問題。 一種是在奇異果園中使用路由器模塊:

https://github.com/kivy-garden/garden.router

另一種方法是將screenmanager的引用傳遞給回收視圖中的小部件,這樣您就可以說self.manager.current = self.text ,但這意味着您必須先前將所有屏幕添加到經理。

我會為此使用工廠:

from kivy.factory import Factory

class MyScreenManager(ScreenManager):
    def create_and_switch_screen(self, name):
        # This creates an instance of the class name you passed
        new_screen = getattr(Factory, name)()
        self.switch_to(my_screen)

這樣,您可以以編程方式創建每個屏幕並將它們定義為單獨的類。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM