我正在尝试使用Python和kivy构建应用程序。 在我的kv文件中,我想创建一个自定义小部件(MenuFloatLayout) 可以被其他屏幕引用。基本上,它是每个屏幕上的菜单栏。此栏由几个切换按钮组成,这些按钮处于按下状态,并且如果您当前在该按钮所链接的屏幕上,则这些按钮处于禁用状态。
此引用由: 状态:如果root.manager.current =='Screenname',则为“ down”,否则为“ normal”
问题是: root.manager.current不再链接到通常的屏幕管理器, 因为我的自定义小部件现在是根。
周围有工作吗? 还是有更简单的方法将切换按钮状态链接到用户所在的屏幕?
我是编程和Python的新手,很高兴为您提供任何帮助或提示!谢谢!
Python文件:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen, ScreenManager
class StartWindow(Screen):
pass
class PortfolioOverview(Screen):
pass
class Portfolio(Screen):
pass
class Market(Screen):
pass
class Economics(Screen):
pass
class PortfolioTools(Screen):
pass
class WindowManager(ScreenManager):
pass
kv = Builder.load_file("vigiles.kv")
class VigilesApp(App):
def build(self):
return kv
if __name__ == "__main__":
VigilesApp().run()
和kv文件:
WindowManager:
StartWindow:
PortfolioOverview:
Portfolio:
Market:
Economics:
PortfolioTools:
<MenuFloatLayout@FloatLayout>:
Label:
text: "Portfolio"
markup: True
size_hint: 0.5, None
height: 30
pos_hint:{"top":1, "left":1}
TextInput:
text: "Search"
multiline: False
size_hint: 0.5, None
height: 30
pos_hint:{"top":1, "right":1}
ScrollView:
size_hint: None, None
do_scroll_y: False
do_scroll_x: True
size: 500, 150
GridLayout:
rows: 1
size_hint_y: None
ToggleButton:
group: "pmenu"
text: 'Overview'
state: "down" if root.manager.current == 'poverview' else "normal"
disabled: True if root.manager.current == 'poverview' else False
background_disabled_down: "atlas://data/images/defaulttheme/button_pressed"
disabled_color: 1, 1, 1, 1
on_release: app.root.current = "poverview"
ToggleButton:
group: "pmenu"
text: 'Portfolio'
state: "down" if root.manager.current == 'portfolio' else "normal"
disabled: True if root.manager.current == 'portfolio' else False
background_disabled_down: "atlas://data/images/defaulttheme/button_pressed"
disabled_color: 1, 1, 1, 1
on_release: app.root.current = "portfolio"
ToggleButton:
group: "pmenu"
text: 'Market'
state: "down" if root.manager.current == 'market' else "normal"
disabled: True if root.manager.current == 'market' else False
background_disabled_down: "atlas://data/images/defaulttheme/button_pressed"
disabled_color: 1, 1, 1, 1
on_release: app.root.current = "market"
ToggleButton:
group: "pmenu"
text: 'Economics'
state: "down" if root.manager.current == 'economics' else "normal"
disabled: True if root.manager.current == 'economics' else False
background_disabled_down: "atlas://data/images/defaulttheme/button_pressed"
disabled_color: 1, 1, 1, 1
on_release: app.root.current = "economics"
ToggleButton:
group: "pmenu"
text: 'Tools'
state: "down" if root.manager.current == 'ptools' else "normal"
disabled: True if root.manager.current == 'ptools' else False
background_disabled_down: "atlas://data/images/defaulttheme/button_pressed"
disabled_color: 1, 1, 1, 1
on_release: app.root.current = "ptools"
<StartWindow>:
name: "start"
BoxLayout:
canvas:
Rectangle:
size: self.size
color: 1, 1, 1, 0
id: login_layout
orientation: 'vertical'
padding: [10,10,10,10]
spacing: 30
Label:
text: 'some text'
font_size: 32
color: 0, 0, 0, 1
BoxLayout:
orientation: 'vertical'
Label:
text: 'Login'
font_size: 18
halign: 'left'
text_size: root.width-20, 20
color: 0, 0, 0, 1
TextInput:
id: login
multiline:False
font_size: 28
BoxLayout:
orientation: 'vertical'
Label:
text: 'Password'
halign: 'left'
font_size: 18
text_size: root.width-20, 20
color: 0, 0, 0, 1
TextInput:
id: password
multiline:False
password:True
font_size: 28
Button:
text: 'Connect'
font_size: 24
on_release: app.root.current = "poverview"
<PortfolioOverview>:
name: "poverview"
MenuFloatLayout:
<Portfolio>:
name: "portfolio"
MenuFloatLayout:
<Market>:
name: "market"
MenuFloatLayout:
<Economics>:
name: "economics"
MenuFloatLayout:
<PortfolioTools>:
name: "ptools"
MenuFloatLayout:
目标是将我的自定义窗口小部件链接回我的屏幕管理器,或者找到一个更简单的解决方案以将切换按钮状态链接到当前屏幕。
AttributeError:'MenuFloatLayout'对象没有属性'manager'
答案 0 :(得分:0)
我会将您的根窗口小部件设为布局窗口小部件(GridLayout
,BoxLayout
或FloatLayout
),然后让屏幕管理器仅占用实际屏幕的一部分。尝试更改
WindowManager:
StartWindow:
PortfolioOverview:
Portfolio:
收件人:
GridLayout:
# Play with using a FloatLayout or BoxLayout instead of GridLayout if you want
cols: 1
MenuFloatLayout:
id: the_menu_id
WindowManager:
StartWindow:
PortfolioOverview:
Portfolio:
这样,您的菜单将继续存在,并且屏幕管理器仅更改实际屏幕的一部分。
通过给MenuFloatLayout
一个id
,您可以引用它。要从Python端引用它,如果要从self.root.ids.the_menu_id
对象引用它,请使用App
。如果您使用的是其他类型的对象,则可以先导入App
(import App
),然后使用App.get_running_app().root.ids.the_menu_id
要从屏幕上引用它,可以使用app
关键字。例如:app.root.ids.the_menu_id
引用菜单id
的所有三种方式基本上是相同的。
答案 1 :(得分:0)
MenuFloatLayout
的实例过多MenuFloatLayout
实例MenuFloatLayout
的一个和唯一一个实例ScreenManager
。这第一个ScreenManager
用于控制身份验证/登录屏幕。第二个ScreenManager
用于在不同屏幕之间导航。ToggleButton
创建一个dynamic class from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen, ScreenManager
class StartWindow(Screen):
pass
class PortfolioOverview(Screen):
pass
class Portfolio(Screen):
pass
class Market(Screen):
pass
class Economics(Screen):
pass
class PortfolioTools(Screen):
pass
class WindowManager(ScreenManager):
pass
Builder.load_file("main.kv")
class TestApp(App):
def build(self):
return WindowManager()
if __name__ == "__main__":
TestApp().run()
<WindowManager>:
sm2: sm2
StartWindow:
Screen:
name: 'connect'
ScreenManager:
id: sm2
PortfolioOverview:
Portfolio:
Market:
Economics:
PortfolioTools:
MenuFloatLayout:
<CustomToggleButton@ToggleButton>: # dynamic class
group: "pmenu"
state: "normal" if app.root is None else "down" if app.root.sm2.current == self.text.lower() else "normal"
background_disabled_down: "atlas://data/images/defaulttheme/button_pressed"
disabled_color: 1, 1, 1, 1
on_state:
if self.state == "down": self.disabled = True
else: self.disabled = False
on_release:
app.root.sm2.current = self.text.lower()
<MenuFloatLayout@FloatLayout>: # dynamic class
Label:
text: "Portfolio"
markup: True
size_hint: 0.5, None
height: 30
pos_hint:{"top":1, "left":1}
TextInput:
hint_text: "Search"
multiline: False
size_hint: 0.5, None
height: 30
pos_hint:{"top":1, "right":1}
ScrollView:
size_hint: None, None
do_scroll_y: False
do_scroll_x: True
size: 500, 150
GridLayout:
rows: 1
size_hint_y: None
CustomToggleButton:
text: 'Overview'
state: 'down' # default
CustomToggleButton:
text: 'Portfolio'
CustomToggleButton:
text: 'Market'
CustomToggleButton:
text: 'Economics'
CustomToggleButton:
text: 'Tools'
<StartWindow>:
name: "start"
BoxLayout:
canvas:
Rectangle:
size: self.size
color: 1, 1, 1, 0
id: login_layout
orientation: 'vertical'
padding: [10,10,10,10]
spacing: 30
Label:
text: 'some text'
font_size: 32
color: 0, 0, 0, 1
BoxLayout:
orientation: 'vertical'
Label:
text: 'Login'
font_size: 18
halign: 'left'
text_size: root.width-20, 20
color: 0, 0, 0, 1
TextInput:
id: login
multiline:False
font_size: 28
BoxLayout:
orientation: 'vertical'
Label:
text: 'Password'
halign: 'left'
font_size: 18
text_size: root.width-20, 20
color: 0, 0, 0, 1
TextInput:
id: password
multiline:False
password:True
font_size: 28
Button:
text: 'Connect'
font_size: 24
on_release:
root.manager.current = 'connect'
<PortfolioOverview>:
name: "overview"
Label:
text: 'Screen - Overview'
<Portfolio>:
name: "portfolio"
Label:
text: 'Screen - Portfolio'
<Market>:
name: "market"
Label:
text: 'Screen - Market'
<Economics>:
name: "economics"
Label:
text: 'Screen - Economics'
<PortfolioTools>:
name: "tools"
Label:
text: 'Screen - Portfolio Tools'