我想一开始就不显示TabbedPannel,
然后当完成某些任务时,我想在此之后显示选项卡。
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 Document。
我想做的是
有什么主意吗?
答案 0 :(得分:1)
听起来像是一个有趣的小挑战,所以这就是我想出的:
'''
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()
这个想法是创建一个“可移动的”标签栏,并用TabbedPanel
中的实际标签填充它,然后对该标签栏进行动画处理。我更改了kv语言字符串,将整个内容放入FloatLayout
中(我认为这使Animation
更加容易)。以前没有执行任何操作的Button
现在可以切换选项卡。在do_tab_toggle()
方法中,我将可移动的标签条的x位置设置为TabbedPanel
的x位置加2。2是一个软键,我无法确定为什么。是必需的,对于其他TabbedPanel
实例可能有所不同。 do_tab_toggle()
的“删除”部分也可以设置动画,但这留给读者练习:-)
其他选项是简单地使用clear_tabs()
方法清除选项卡,或为tab_height
的{{1}}属性设置动画(将高度设置为零以隐藏选项卡)。 / p>
编辑:添加了一对绑定来捕获在调用TabbedPanel
方法时无法可靠获得的数据。