我正在使用Kivy库主要使用Python代码来创建应用。我是Python和Kivy的新手。这里是我的代码片段。
我试图将定义为“ on_start”的图像传递给我的NavButton。 @ikolim帮助我确定了问题所在。您可以在下面看到我的评论。
小部件
class NavButton(GridLayout):
def __init__(self, **kwargs):
super(NavButton, self).__init__(**kwargs)
self.rows = 1
frame = FloatLayout(id = "frame")
grid1 = MyGrid(
rows = 1,
cols = 5,
pos_hint = {"top":1, "left": 1},
size_hint = [1, .2] )
grid1.set_background(0.95,0.95,0.95,1)
grid1.add_widget(MyButton(
source = "img/settings.png",
size_hint = [0.2,0.2] ))
grid1.add_widget(MyButton(
source = "img/arrow-left.png" ))
city_icon = Image(
source="img/image1.png",
id="city_icon",
size_hint=[0.8, 0.8])
self.ids.cityicon = city_icon
grid1.add_widget(city_icon)
grid1.add_widget(MyButton(
source = "img/arrow-right.png" ))
grid1.add_widget(MyButton(
source = "img/globe.png",
size_hint = [0.2,0.2] ))
frame.add_widget(grid1)
self.add_widget(frame)
class Homescreen(Screen):
def __init__(self, **kwargs):
super(Homescreen, self).__init__(**kwargs)
frame = FloatLayout(id = "frame")
grid1 = NavButton()
frame.add_widget(grid1)
...
这是我搞砸的地方!显然,您必须定义主屏幕的名称(即homescreen = Homescreen(name="home_screen")
),否则在启动应用程序时它不会更新NavButton的图像。我不知道为什么,但是我只是为将来的编码员强调这一点。
class MyScreenManager(ScreenManager):
def __init__(self, **kwargs):
super(MyScreenManager, self).__init__(**kwargs)
homescreen = Homescreen()
self.add_widget(homescreen)
self.ids.screenmanager = self
def change_screen(self, name):
self.current = name
GUI = Builder.load_file("main.kv")
class Main(App):
def build(self):
return GUI
def on_start(self):
self.mynewimage = "image2"
homescreen = self.root.get_screen("home_screen")
homescreen.ids.navbutton.ids.cityicon.source = f"img/{self.mynewimage}.png"
if __name__ == "__main__":
Main().run()
再次,@ ikolim感谢您的支持。
答案 0 :(得分:1)
需要以下增强功能才能解决该问题。
self.ids.cityicon = "cityicon"
与self.ids.cityicon = city_icon
self.bind(on_start=self.update_image)
和方法update_image()
on_start()
homescreen =
Main.get_running_app().root.get_screen("home_screen")
替换为
homescreen = self.root.get_screen("home_screen")
frame.children[3].children[0].children[0].children[2].source
与
homescreen.ids.navbutton.ids.cityicon.source
frame = homescreen.children[0]
,navbutton =
frame.children[3]
和print(...)
)class NavButton(GridLayout):
def __init__(self, **kwargs):
super(NavButton, self).__init__(**kwargs)
...
city_icon = Image(
source="img/settings.png",
id="city_icon",
size_hint=[0.8, 0.8])
self.ids.cityicon = city_icon
...
class Main(App):
...
def on_start(self):
self.my_city = "it-Rome"
homescreen = self.root.get_screen("home_screen")
homescreen.ids.navbutton.ids.cityicon.source = f"img/{self.my_city}.png"
...
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.gridlayout import GridLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.button import ButtonBehavior
from kivy.uix.label import Label
from kivy.uix.image import Image
from kivy.graphics import Color, Rectangle
class MyButton(ButtonBehavior, Image):
pass
class ImageButton(ButtonBehavior, Image):
pass
### Components
class NavButton(GridLayout):
def __init__(self, **kwargs):
super(NavButton, self).__init__(**kwargs)
self.rows = 1
frame = FloatLayout(id="frame")
grid1 = MyGrid(
rows=1,
cols=5,
pos_hint={"top": 1, "left": 1},
size_hint=[1, .2])
grid1.set_background(0.95, 0.95, 0.95, 1)
grid1.add_widget(MyButton(
source="img/settings.png",
size_hint=[0.2, 0.2]))
grid1.add_widget(MyButton(
source="img/arrow-left.png"))
city_icon = Image(
source="img/settings.png",
id="city_icon",
size_hint=[0.8, 0.8])
self.ids.cityicon = city_icon
grid1.add_widget(city_icon)
grid1.add_widget(MyButton(
source="img/arrow-right.png"))
grid1.add_widget(MyButton(
source="img/globe.png",
size_hint=[0.2, 0.2]))
frame.add_widget(grid1)
self.add_widget(frame)
### Grids
class MyGrid(GridLayout):
def set_background(self, r, b, g, o):
self.canvas.before.clear()
with self.canvas.before:
Color(r, g, b, o)
self.rect = Rectangle(pos=self.pos, size=self.size)
self.bind(pos=self.update_rect,
size=self.update_rect)
def update_rect(self, *args):
self.rect.pos = self.pos
self.rect.size = self.size
### Screens
class Homescreen(Screen):
def __init__(self, **kwargs):
super(Homescreen, self).__init__(**kwargs)
frame = FloatLayout(id="frame")
grid1 = NavButton()
frame.add_widget(grid1)
# This grid contains the number of zpots collected
grid2 = MyGrid(
cols=1,
pos_hint={"top": 0.8, "left": 1},
size_hint=[1, .2], )
grid2.add_widget(Image(
source="img/spot.png"))
grid2.add_widget(Label(
text="[color=3333ff]20/30[/color]",
markup=True))
grid2.set_background(0.95, 0.95, 0.95, 1)
frame.add_widget(grid2)
# This grid contains a scrollable list of nearby zpots
grid3 = MyGrid(
cols=1,
pos_hint={"top": 0.6, "left": 1},
size_hint=[1, .5])
grid3.set_background(0.95, 0.95, 0.95, 1)
frame.add_widget(grid3)
# This grid contains a the map of nearby zpots
grid4 = MyGrid(
cols=1,
pos_hint={"top": 0.1, "left": 1},
size_hint=[1, .1])
grid4.set_background(0.95, 0.95, 0.95, 1)
frame.add_widget(grid4)
self.ids.navbutton = grid1
self.add_widget(frame)
class Newscreen(Screen):
pass
class Settingscreen(Screen):
pass
### ScreenManager
class MyScreenManager(ScreenManager):
def __init__(self, **kwargs):
super(MyScreenManager, self).__init__(**kwargs)
homescreen = Homescreen(name='home_screen')
self.add_widget(homescreen)
self.ids.screenmanager = self
def change_screen(self, name):
self.current = name
class TestApp(App):
def build(self):
return MyScreenManager()
def on_start(self):
self.my_city = "it-Rome"
homescreen = self.root.get_screen("home_screen")
print(f"\non_start-Before change: img={homescreen.ids.navbutton.ids.cityicon.source}")
homescreen.ids.navbutton.ids.cityicon.source = f"img/{self.my_city}.png"
print(f"\non_start-After change: img={homescreen.ids.navbutton.ids.cityicon.source}")
if __name__ == "__main__":
TestApp().run()
App.get_running_app()
函数获取您的应用程序实例self
的前面添加my_city
class NavButton(GridLayout):
def get(self):
...
city_icon = Image(
source = "img/" + App.get_running_app().my_city,
size_hint = [0.8,0.8] )
...
class Main(App):
def build(self):
return GUI
def on_start(self):
# get data from DB
self.my_city = "it-Rome"