英文:
Python Kivy: Connect TabbePanel to Screen using Screenmanager
问题
我一直在开发一个Python应用程序,包括一个main.py和一个gui.kv文件。所有屏幕(“Main”,“First”,“Second”)都由ScreenManager管理,就像main.py中的示例一样。
现在我想将每个屏幕链接到一个选项卡。通过按下相应的选项卡,屏幕应该切换。到目前为止,我已经成功将一个具有3个选项卡(“Main”,“First”,“Second”)的TabbedPanel添加到gui.kv中。
问题:TappedPanelItem事件(on_release: root.manager.current= 'first')的工作方式不如预期。当我单击“First”选项卡时,程序会切换到一个空白屏幕,并且“Main”选项卡仍然亮起。第二次按下“First”选项卡时,“First”屏幕最终显示“First”屏幕,并且“First”选项卡标记会亮起。
main.py:
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen, NoTransition
from kivy.uix.tabbedpanel import TabbedPanel
from kivy.uix.floatlayout import FloatLayout
class TabbedTest(TabbedPanel):
pass
class MainScreen(Screen):
pass
class FirstScreen(Screen):
pass
class SecondScreen(Screen):
pass
class TabTest_with_Screenmanager_V2(App):
def build(self):
root = FloatLayout()
sm = ScreenManager(size_hint_y=0.99, pos_hint={'y': 0}, transition=NoTransition())
sm.add_widget(MainScreen(name='main'))
sm.add_widget(FirstScreen(name='first'))
sm.add_widget(SecondScreen(name='second'))
root.add_widget(sm)
return root
if __name__ == '__main__':
TabTest_with_Screenmanager_V2().run()
TabTest_with_Screenmanager_V2.kv:
<MainScreen>:
id: main
TabbedPanel:
do_default_tab: False
TabbedPanelItem:
text: "Main"
BoxLayout:
Label:
text: 'Main'
TabbedPanelItem:
text: "First"
on_release: root.manager.current = 'first'
TabbedPanelItem:
text: "Second"
on_release: root.manager.current = 'second'
<FirstScreen>:
id: first
TabbedPanel:
do_default_tab: False
TabbedPanelItem:
text: "Main"
on_state: if self.state == "down": root.manager.current = 'main'
TabbedPanelItem:
text: "First"
BoxLayout:
Label:
text: "first"
TabbedPanelItem:
text: "Second"
on_state: if self.state == "down": root.manager.current = 'second'
<SecondScreen>:
id: second
TabbedPanel:
do_default_tab: False
TabbedPanelItem:
text: "Main"
on_state: if self.state == "down": root.manager.current = 'main'
TabbedPanelItem:
text: "First"
on_state: if self.state == "down": root.manager.current = 'first'
TabbedPanelItem:
text: "Second"
BoxLayout:
Label:
text: 'second'
目标:当我点击选项卡时,程序应立即切换到相应的屏幕并点亮相应的选项卡。你有什么想法,哪种事件可能会起作用,或者是否有更好的解决方案?
英文:
I’ve been working on a Python app consisting of a main.py and a gui.kv. All screens (“Main”, “First”, “Second”) are managed by the ScreenManager as shown in the example main.py.
Now I would like to link a tab to each screen. By pressing the corresponding tab the screen shall switch. What I managed so far is the addition of a TabbedPanel with 3 TabbedPanelItems (“Main”, “First”, “Second”) to the gui.kv.
The problem: The TappedPanelItem event (on_release: root.manager.current= 'first') doesn’t work as intended. When I press the tab “First” once, the program switches to a blank screen and the “Main” tab marking is still illuminated. The second time I press the tab “First” the “First” screen finally shows the “First”-Screen and the “First“ tab marking illuminates.
main.py:
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen, NoTransition
from kivy.uix.tabbedpanel import TabbedPanel
from kivy.uix.floatlayout import FloatLayout
class TabbedTest(TabbedPanel):
pass
class MainScreen(Screen):
pass
class Firstscreen(Screen):
pass
class Secondscreen(Screen):
pass
class TabTest_with_Screenmanager_V2(App):
def build(self):
root = FloatLayout()
#self.tabbedtest = TabbedTest(size_hint_y=0.5, pos_hint={'top': 1.0})
#root.add_widget(self.tabbedtest)
# Create the screen manager
sm = ScreenManager(size_hint_y=0.99, pos_hint={'y': 0},transition=NoTransition())
sm.add_widget(MainScreen(name='main'))
sm.add_widget(Firstscreen(name='first'))
sm.add_widget(Secondscreen(name='second'))
root.add_widget(sm)
return root
if __name__ == '__main__':
TabTest_with_Screenmanager_V2().run()
TabTest_with_Screenmanager_V2.kv:
<MainScreen>:
id: main
TabbedPanel:
do_default_tab: False
TabbedPanelItem:
text:"Main"
BoxLayout:
Label:
text:'Main'
TabbedPanelItem:
text:"First"
on_release: root.manager.current= 'first'
TabbedPanelItem:
text:"Second"
on_release:root.manager.current= 'second'
<Firstscreen>:
id: first
TabbedPanel:
do_default_tab: False
TabbedPanelItem:
text:"Main"
on_state: if self.state == "down":root.manager.current= 'main'
TabbedPanelItem:
text:"First"
BoxLayout:
Label:
text:"first"
TabbedPanelItem:
text:"Second"
on_state: if self.state == "down":root.manager.current= 'second'
<Secondscreen>:
id: second
TabbedPanel:
do_default_tab: False
TabbedPanelItem:
text:"Main"
on_state: if self.state == "down":root.manager.current= 'main'
TabbedPanelItem:
text:"First"
on_state: if self.state == "down":root.manager.current= 'first'
TabbedPanelItem:
text:"Second"
BoxLayout:
Label:
text:'second'
Objective: When I press a tab the program shall switch to the corresponding screen and illuminate the corresponding tab, immediately.
Do you have any idea what kind of event might work or is there better solution?
答案1
得分: 0
可以使用一些ids
和每个Screen
的on_enter()
方法来实现这个功能。
首先,在TabbedPanel
上分配一个id
,并为您希望在进入该Screen
时打开的默认选项卡分配另一个id
。例如:
<MainScreen>:
id: main
TabbedPanel:
id: tab
do_default_tab: False
TabbedPanelItem:
id: home_tab
text: "主页"
BoxLayout:
Label:
text: '主页'
TabbedPanelItem:
text: "第一项"
on_release: root.manager.current = '第一个'
TabbedPanelItem:
text: "第二项"
on_release: root.manager.current = '第二个'
然后,在该Screen
上添加一个on_enter()
方法:
class MainScreen(Screen):
def on_enter(self, *args):
tab = self.ids.tab
home_tab = self.ids.home_tab
Clock.schedule_once(lambda *args: tab.switch_to(home_tab))
相同的ids
方案可以添加到每个Screen
上,并且可以向每个Screen
添加相同的on_enter()
方法。
英文:
You can use some ids
and the on_enter()
method of each Screen
to do this.
First, assign an id
to the TabbedPanel
and another to the default tab that you want to be opened when you enter that Screen
. For example:
<MainScreen>:
id: main
TabbedPanel:
id: tab
do_default_tab: False
TabbedPanelItem:
id: home_tab
text:"Main"
BoxLayout:
Label:
text:'Main'
TabbedPanelItem:
text:"First"
on_release: root.manager.current='first'
TabbedPanelItem:
text:"Second"
on_release:root.manager.current= 'second'
Then add an on_enter()
method to that Screen
:
class MainScreen(Screen):
def on_enter(self, *args):
tab = self.ids.tab
home_tab = self.ids.home_tab
Clock.schedule_once(lambda *arges: tab.switch_to(home_tab))
The same scheme of ids
can be added to each Screen
, and the identical on_enter()
method can be added to each Screen
.
答案2
得分: 0
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen, NoTransition
from kivy.uix.tabbedpanel import TabbedPanel
from kivy.uix.floatlayout import FloatLayout
from kivy.clock import Clock
class TabbedTest(TabbedPanel):
pass
class MainScreen(Screen):
def on_enter(self, *args):
tab = self.ids.tabbedpanel
home_tabX = self.ids.home_tab
Clock.schedule_once(lambda *args: tab.switch_to(home_tabX))
class Firstscreen(Screen):
def on_enter(self, *args):
tab = self.ids.tabbedpanel
first_tabX = self.ids.first_tab
Clock.schedule_once(lambda *args: tab.switch_to(first_tabX))
class Secondscreen(Screen):
def on_enter(self, *args):
tab = self.ids.tabbedpanel
second_tabX = self.ids.second_tab
Clock.schedule_once(lambda *args: tab.switch_to(second_tabX))
class TabTest_with_Screenmanager_V2(App):
def build(self):
sm = ScreenManager(size_hint_y=0.99, pos_hint={'y': 0}, transition=NoTransition())
sm.add_widget(MainScreen(name='main'))
sm.add_widget(Firstscreen(name='first'))
sm.add_widget(Secondscreen(name='second'))
root.add_widget(sm)
return root
if __name__ == '__main__':
TabTest_with_Screenmanager_V2().run()
英文:
main.kv
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen, NoTransition
from kivy.uix.tabbedpanel import TabbedPanel
from kivy.uix.floatlayout import FloatLayout
from kivy.clock import Clock
class TabbedTest(TabbedPanel):
pass
class MainScreen(Screen):
def on_enter(self, *args):
tab= self.ids.tabbedpanel
home_tabX = self.ids.home_tab
Clock.schedule_once(lambda *args: tab.switch_to(home_tabX))
#pass
class Firstscreen(Screen):
def on_enter(self, *args):
tab= self.ids.tabbedpanel
first_tabX = self.ids.first_tab
Clock.schedule_once(lambda *args: tab.switch_to(first_tabX))
class Secondscreen(Screen):
def on_enter(self, *args):
tab= self.ids.tabbedpanel
second_tabX = self.ids.second_tab
Clock.schedule_once(lambda *args: tab.switch_to(second_tabX))
class TabTest_with_Screenmanager_V2(App):
def build(self):
sm = ScreenManager(size_hint_y=0.99,
pos_hint={'y': 0},transition=NoTransition())
sm.add_widget(MainScreen(name='main'))
sm.add_widget(Firstscreen(name='first'))
sm.add_widget(Secondscreen(name='second'))
root.add_widget(sm)
return root
if __name__ == '__main__':
TabTest_with_Screenmanager_V2().run()
答案3
得分: 0
<TabTest_with_Screenmanager_V2.kv>:
<MainScreen>:
id: main
TabbedPanel:
id: tabbedpanel
do_default_tab: False
TabbedPanelItem:
id: home_tab
text: "主页"
BoxLayout:
Label:
text: '主页'
TabbedPanelItem:
id: first_tab
text: "第一项"
on_release: root.manager.current = '第一项'
TabbedPanelItem:
id: second_tab
text: "第二项"
on_release: root.manager.current = '第二项'
<Firstscreen>:
id: first
TabbedPanel:
id: tabbedpanel
do_default_tab: False
TabbedPanelItem:
id: home_tab
text: "主页"
on_state: if self.state == "down": root.manager.current = '主页'
TabbedPanelItem:
id: first_tab
text: "第一项"
BoxLayout:
Label:
text: "第一项"
TabbedPanelItem:
id: second_tab
text: "第二项"
on_state: if self.state == "down": root.manager.current = '第二项'
<Secondscreen>:
id: second
TabbedPanel:
id: tabbedpanel
do_default_tab: False
TabbedPanelItem:
id: home_tab
text: "主页"
on_state: if self.state == "down": root.manager.current = '主页'
TabbedPanelItem:
id: first_tab
text: "第一项"
on_state: if self.state == "down": root.manager.current = '第一项'
TabbedPanelItem:
id: second_tab
text: "第二项"
BoxLayout:
Label:
text: '第二项'
英文:
TabTest_with_Screenmanager_V2.kv:
<MainScreen>:
id: main
TabbedPanel:
id: tabbedpanel
do_default_tab: False
TabbedPanelItem:
id: home_tab
text:"Main"
BoxLayout:
Label:
text:'Main'
TabbedPanelItem:
id: first_tab
text:"First"
on_release: root.manager.current= 'first'
TabbedPanelItem:
id: second_tab
text:"Second"
on_release:root.manager.current= 'second'
<Firstscreen>:
id: first
TabbedPanel:
id: tabbedpanel
do_default_tab: False
TabbedPanelItem:
id: home_tab
text:"Main"
on_state: if self.state == "down":root.manager.current= 'main'
TabbedPanelItem:
id: first_tab
text:"First"
BoxLayout:
Label:
text:"first"
TabbedPanelItem:
id: second_tab
text:"Second"
on_state: if self.state == "down":root.manager.current= 'second'
<Secondscreen>:
id: second
TabbedPanel:
id: tabbedpanel
do_default_tab: False
TabbedPanelItem:
id: home_tab
text:"Main"
on_state: if self.state == "down":root.manager.current= 'main'
TabbedPanelItem:
id: first_tab
text:"First"
on_state: if self.state == "down":root.manager.current= 'first'
TabbedPanelItem:
id: second_tab
text:"Second"
BoxLayout:
Label:
text:'second'
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论