Динамическое управление TabbedPanel в Кивах - PullRequest
0 голосов
/ 17 октября 2018

Я пытаюсь сделать TabbedPannel невидимым в начале,

Затем, когда определенное задание выполнено, я хочу показать вкладки после этого.

enter image description here

from kivy.app import App
from kivy.uix.tabbedpanel import TabbedPanel
from kivy.lang import Builder

Builder.load_string("""

<Test>:
    size_hint: .5, .5
    pos_hint: {'center_x': .5, 'center_y': .5}
    do_default_tab: False

    TabbedPanelItem:
        text: 'first tab'
        Label:
            text: 'First tab content area'
    TabbedPanelItem:
        text: 'tab2'
        BoxLayout:
            Label:
                text: 'Second tab content area'
            Button:
                text: 'Button that does nothing'
    TabbedPanelItem:
        text: 'tab3'
        RstDocument:
            text:
                '\\n'.join(("Hello world", "-----------",
                "You are in the third tab."))

""")


class Test(TabbedPanel):
    pass


class TabbedPanelApp(App):
    def build(self):
        return Test()


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

Код выше взят из Документа Kivy .

Я пытаюсь сделать следующее:

  1. Скрыть вкладки (также предотвращает перемещение вкладок)
  2. Когда определенное действие выполнено, сдвигает вкладки вниз снаружиэкран.

Есть идеи?

1 Ответ

0 голосов
/ 17 октября 2018

Звучит как забавный маленький вызов, поэтому вот что я придумал:

'''
TabbedPanel
============

Test of the widget TabbedPanel.
'''
from kivy.animation import Animation
from kivy.app import App
from kivy.clock import Clock
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.scrollview import ScrollView
from kivy.uix.tabbedpanel import TabbedPanel, TabbedPanelStrip
from kivy.lang import Builder


class Test(TabbedPanel):

    def __init__(self, **kwargs):
        super(Test, self).__init__(**kwargs)
        self.initialTabHeight = None
        self.myTabsList = None
        self.start_top = None
        self.tabs_showing = True

        # this TabbedPanelStrip will be a copy of the real one (self._tab_strip)
        self.tmp_tab_strip = TabbedPanelStrip(
            tabbed_panel=self,
            rows=1, size_hint=(None, None),
            height=self.tab_height, width=self.tab_width)

        # this is the movable Widget that contains the tabs
        self.movable_tab_strip = ScrollView(size_hint=(None, None), height=self.tab_height)

        # These value are needed to set the width of self.movable_tab_strip, but
        # they aren't always available when self.first is called below
        self._tab_strip.bind(width=self.tab_strip_width_changed)
        self.bind(width=self.panel_width_changed)

        Clock.schedule_once(self.first)

    def tab_strip_width_changed(self, instance, new_width):
        self.movable_tab_strip.width = min(self.tmp_tab_strip.width, self.width)

    def panel_width_changed(self, instance, new_width):
        self.movable_tab_strip.width = min(self.tmp_tab_strip.width, self.width)

    def first(self, *args):
        # show tab2, so that the Button will be available
        self.switch_to(self.parent.ids.tab2)

        # save some info
        self.initialTabHeight = self.tab_height
        self.myTabsList = self.tab_list.copy()

        tsw = 0
        for tab in self.myTabsList:
            if tab.size_hint_x:
                tsw += 100
            else:
                tsw += tab.width
        self.tmp_tab_strip.width = tsw
        self.movable_tab_strip.add_widget(self.tmp_tab_strip)

        # actually remove the tabs
        self.do_clear_widgets()

    def do_clear_widgets(self, *args):
        # eliminate the tabs and populate the moveable_tab_strip
        #self.movable_tab_strip.width = min(self.tmp_tab_strip.width, self.width)
        self.tab_height = 0
        self.clear_tabs()
        for tab in reversed(self.myTabsList):
            self.tmp_tab_strip.add_widget(tab)
        self.tabs_showing = False

    def do_progress(self, animation, widget, progression):
        # grow the tab height when the moveable_tab_strip impinges on the TabbedPanel
        # this has the effect of appearing to shrink the TappedPanel to the size it will have when the tabs are replaced
        if self.start_top > self.movable_tab_strip.y:
            self.tab_height = self.start_top - self.movable_tab_strip.y

    def do_replace_tabs(self, *args):
        # replace the moveable_tab_trip with the actual tabs
        self.tmp_tab_strip.clear_widgets()
        for tab in reversed(self.myTabsList):
            self.add_widget(tab)
        self.tab_height = self.initialTabHeight
        self.parent.remove_widget(self.movable_tab_strip)

    def do_tab_toggle(self, *args):
        if self.tabs_showing:
            self.do_clear_widgets()
        else:
            self.anim = Animation(pos=(self.x+2, self.y + self.height - self.movable_tab_strip.height))
            self.movable_tab_strip.pos = (self.x + 2, App.get_running_app().root_window.height)
            self.start_top = self.top
            self.parent.add_widget(self.movable_tab_strip)
            self.anim.bind(on_progress=self.do_progress)
            self.anim.bind(on_complete=self.do_replace_tabs)
            self.anim.start(self.movable_tab_strip)
            self.tabs_showing = True


class MyLayout(FloatLayout):
    pass


theRoot = Builder.load_string("""

MyLayout:
    Test:
        id: thePanel
        size_hint: .5, .5
        pos_hint: {'center_x': .5, 'center_y': .5}
        do_default_tab: False

        TabbedPanelItem:
            text: 'first tab'
            Label:
                id: theLabel
                text: 'First tab content area'
        TabbedPanelItem:
            id: tab2
            text: 'tab2'
            BoxLayout:
                Label:
                    text: 'Second tab content area'
                Button:
                    text: 'Button that does something'
                    on_press: thePanel.do_tab_toggle()
        TabbedPanelItem:
            id: tab3
            text: 'tab3'
            RstDocument:
                text:
                    '\\n'.join(("Hello world", "-----------",
                    "You are in the third tab."))
        TabbedPanelItem:
            text: 'tab4'
            Label:
                text: 'This is Tab4'
        TabbedPanelItem:
            id:tab5
            text: 'tab5'
            Label:
                text: 'This is Tab5'

""")


class TabbedPanelApp(App):
    def build(self):
        return theRoot

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

Идея состоит в том, чтобы создать «подвижную» полосу вкладок, заполнив ее фактическими вкладками из * 1004.*, а затем анимируйте эту полосу вкладок.Я изменил строку языка kv, чтобы поместить все это в FloatLayout (я думаю, что облегчает Animation).Button, который раньше ничего не делал, теперь переключает вкладки.В методе do_tab_toggle() я установил положение x подвижной планки с лапками в положение x у TabbedPanel плюс 2. 2 - коэффициент выдумки, и я не смог определить, зачем он нужен, иэто может отличаться для других TabbedPanel экземпляров.«Удалить» часть do_tab_toggle() также можно анимировать, но это оставлено для читателя в качестве упражнения: -)

Другие варианты - просто очистить вкладки с помощью метода clear_tabs(), илианимировать свойство tab_height TabbedPanel (анимировать высоту до нуля, чтобы скрыть вкладки).

РЕДАКТИРОВАТЬ: Добавлена ​​пара привязок для захвата данных, которые ненадежно доступны при методе firstназывается.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...