【问题标题】:Button for switch screen inside Kivy carouselKivy旋转木马内切换屏幕的按钮
【发布时间】:2019-06-07 10:56:10
【问题描述】:

我正在尝试创建一个按钮来更改/返回到轮播中的上一个屏幕。

我习惯于在 .kv 文件中管理我的按钮,但轮播不可能,如果我这样做,只会在最后一张幻灯片上创建一个按钮。

我需要按钮出现在每张幻灯片上,所以我这样做了,效果很好,只是我不知道如何将按钮链接到 ScreenManager。

我的python文件的一部分:

class MyCarousel(Carousel):
    def __init__(self, **kwargs):
        super(MyCarousel, self).__init__(**kwargs)
        self.direction = "right"
        log_file = open_logfile()
        for i in range(log_file['len']):
            src = log_file['path'][(log_file['len']) - (i + 1)] + "_file_resize.jpg"
            button = Button(size_hint=(.15,.25),\
                    pos_hint={'center_x': .05, 'y': .65},\
                    background_color=(1, 1, 1, 1),\
                    border=(0, 0, 0, 0),\
                    on_release=***???***
                    background_normal="Interface_PNG/bouton/Bouton_retour.png",\
                    background_down="Interface_PNG/bouton/Bouton_retour_fonce.png")
            image = AsyncImage(source=src, allow_stretch=True, size_hint=(1, 1), pos_hint={'center_x': .5, 'y': 0})
            layout = FloatLayout()
            layout.add_widget(image)
            layout.add_widget(button)
            self.add_widget(layout)
        self.loop = True

class StartScreen(Screen):
    pass

class GalleryPhoto(Screen):
    def call_next(self, dt):
        self.manager.current = "start"

class RootScreen(ScreenManager):
    pass

class PhotoboothApp(App):
    def build(self):
        sm = RootScreen()
        self.start_screen = StartScreen()
        self.gallery_photo = GalleryPhoto()
        sm.add_widget(self.start_screen)
        sm.add_widget(self.gallery_photo)
        return sm

我的 kv 文件的一部分:

<StartScreen>:
    name: "start"
    canvas.before:
        Rectangle:
            pos: self.pos
            size: self.size
    FloatLayout:
        Image:
            source: "Interface_PNG/Page_1.png"
            allow_stretch : True
            keep_ratio : False
            size_hint: 1, 1
        Button:
            background_color: 0, 0, 0, 0
            on_release: root.manager.current = "gallery"

<GalleryPhoto>:
    name: "gallery"
    FloatLayout:
        Image:
            source: "Interface_PNG/Page_8.png"
            allow_stretch: True
            keep_ratio: False
            size_hint: 1, 1
        MyCarousel:

我想在 python 中做类似的事情:

 MyCarousel:
     Button:
        on_release: root.manager.current = "start"

我认为这很简单,但我有点迷茫......欢迎任何帮助。

【问题讨论】:

  • 获取“SyntaxError:无效语法”。第二个符号“=”似乎有问题。

标签: python-3.x kivy


【解决方案1】:
  • class MyCarousel() 中实现change_screen() 方法
  • 将按钮绑定到change_screen()方法
  • 使用App.get_running_app().root 访问实例化的根ScreenManager 对象。

片段 - py

class MyCarousel(Carousel):
    def __init__(self, **kwargs):
        ...
            button = Button(size_hint=(.15,.25), pos_hint={'center_x': .05, 'y': .65},
                            background_color=(1, 1, 1, 1), border=(0, 0, 0, 0),
                            on_release=self.change_screen(),

            ...

    def change_screen(self, instance):
        App.get_running_app().root.current = 'start'

示例

main.py

​​>
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.carousel import Carousel
from kivy.uix.image import AsyncImage
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
from kivy.lang import Builder


class MyCarousel(Carousel):
    def __init__(self, **kwargs):
        super(MyCarousel, self).__init__(**kwargs)
        self.direction = "right"

        for i in range(10):
            src = "http://placehold.it/480x270.png&text=slide-%d&.png" % i
            image = AsyncImage(source=src, allow_stretch=True, size_hint=(1, 1), pos_hint={'center_x': .5, 'y': 0})
            button = Button(size_hint=(.15, .25), pos_hint={'center_x': .05, 'y': .65},
                            text='StartScreen',
                            on_release=self.change_screen)

            layout = FloatLayout()
            layout.add_widget(image)
            layout.add_widget(button)
            self.add_widget(layout)
        self.loop = True

    def change_screen(self, instance):
        App.get_running_app().root.current = 'start'


class StartScreen(Screen):
    pass


class GalleryPhoto(Screen):
    pass


class RootScreen(ScreenManager):
    pass


Builder.load_file("main.kv")


class TestApp(App):
    title = "Photobooth"

    def build(self):
        return RootScreen()


if __name__ == "__main__":
    TestApp().run()

main.kv

<RootScreen>:
    StartScreen:
    GalleryPhoto:


<StartScreen>:
    name: "start"
    canvas.before:
        Rectangle:
            pos: self.pos
            size: self.size
    FloatLayout:
        Image:
            source: "kivy-logo.png"
            allow_stretch : True
            keep_ratio : True   # False
            size_hint: 1, 1
        Button:
            background_color: 0, 0, 0, 0
            on_release: root.manager.current = "gallery"

<GalleryPhoto>:
    name: "gallery"
    FloatLayout:
        Image:
            source: "kivymd_logo.png"
            allow_stretch: True
            keep_ratio: False
            size_hint: 1, 1
        MyCarousel:

输出

【讨论】:

  • 谢谢!我不知道为什么,但对 (App.get_running_app().root.) 的调用并没有给我一个对象。编辑:我在这里找到了解决方案stackoverflow
  • 请参考更新后的帖子以及工作示例(main.py 和 kv 文件)。如果在 Kivy 创建完所有对象之前使用App.get_running_app().root,它将返回None
  • 是的,我现在明白了。您的解决方案运行良好,非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多