Kivy:更改屏幕上的图像源

时间:2018-08-16 02:00:39

标签: python python-3.x kivy

经过大量的敲打,我创建了一个打开FileChooser并选择图像的应用程序。然后,一个函数将变换图像并在屏幕上进行更改。

只是开始,相对不重要。 是文件选择器。路径可能需要编辑。 应当显示图像以及最终将引导至其他位置的按钮。

我怀疑问题在于线路

sm.current = "_third_screen_"

正在创建一个新实例,该实例与我已经传递项目的其他所有事物分开。如何显示我选择的图像?

from kivy.lang import Builder
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import ObjectProperty, StringProperty


Builder.load_string("""

<MyScreenManager>:
    FirstScreen:
    SecondScreen:
    ThirdScreen:

<FirstScreen>:
    name: '_first_screen_'
    BoxLayout:
        orientation: "horizontal"
        Label:
            id: first_screen_label
            text: "Hi, I'm the home page"
        BoxLayout:
            orientation: "vertical"
            Button:
                text: "Okay!"
                on_press: root.manager.current = '_second_screen_'
            Button:
                text: "Cancel!"
                on_press: app.stop()

<SecondScreen>:
    name: '_second_screen_'
    id: file_chooser
    BoxLayout:
        id: file_chooser_box_layout
        orientation: "horizontal"
        Button
            text: "Open"
            on_press: 
                root.callback_image_and_other_stuff(file_chooser_list_view.selection)
        FileChooserListView:
            id: file_chooser_list_view

<ThirdScreen>:
    name: '_third_screen_'
    BoxLayout:
        orientation: "vertical"
        id: third_screen
        Label:
            id: main_title
            text: "Upload"
            size_hint: (1, 0.1)
        Image:
            id: main_image
            source: root.img
            size_hint: (1, 0.75)
        BoxLayout:
            orientation: "horizontal"
            padding: 10
            size_hint: (1, 0.15)
            Button:
                text: "Okay"
                size_hint: (0.5, 1)
                on_press: image_viewer.image_accepted_by_user(filechooser.selection)
            Button:
                text: "Cancel"
                size_hint: (0.5, 1) 
                on_press: root.manager.current = '_first_screen_'   
""")

class FirstScreen(Screen):
    pass

class SecondScreen(Screen):
    def callback_image_and_other_stuff(self, new_image_address):
        # do other stuff here also, then pass new_image_address along
        new_image_address = new_image_address[0].replace("\\", "/")
        third_screen = ThirdScreen()
        third_screen.callback_image(new_image_address)

class ThirdScreen(Screen):
    img = ObjectProperty(None)

    def __init__(self, **kwargs):
        super(Screen, self).__init__(**kwargs)

    def callback_image(self, new_image_address):
        sm.current = "_third_screen_"
        self.img = new_image_address
        self.ids.main_image.source = self.img

        print(self.img)

# Create the screen manager
sm = ScreenManager() # Problem?
sm.add_widget(FirstScreen(name='_first_screen_'))
sm.add_widget(SecondScreen(name='_second_screen_'))
sm.add_widget(ThirdScreen(name='_third_screen_'))

class MyApp(App):
    def build(self):
        return sm

if __name__ == '__main__':
    MyApp().run()

1 个答案:

答案 0 :(得分:1)

每次使用some_obj = SomClass()时,您都在创建一个新对象,在这种情况下,您正在创建一个新的ThirdScreen,它不同于您未观察到的显示对象图像,解决方案是您必须使用ScreenManager和名称屏幕访问初始对象。

from kivy.lang import Builder
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import ObjectProperty, StringProperty


Builder.load_string("""
<FirstScreen>:
    BoxLayout:
        orientation: "horizontal"
        Label:
            id: first_screen_label
            text: "Hi, I'm the home page"
        BoxLayout:
            orientation: "vertical"
            Button:
                text: "Okay!"
                on_press: root.manager.current = '_second_screen_'
            Button:
                text: "Cancel!"
                on_press: app.stop()

<SecondScreen>:
    id: file_chooser
    BoxLayout:
        id: file_chooser_box_layout
        orientation: "horizontal"
        Button
            text: "Open"
            on_press: 
                root.callback_image_and_other_stuff(file_chooser_list_view.selection)
        FileChooserListView:
            id: file_chooser_list_view

<ThirdScreen>:
    BoxLayout:
        orientation: "vertical"
        id: third_screen
        Label:
            id: main_title
            text: "Upload"
            size_hint: (1, 0.1)
        Image:
            id: main_image
            source: root.img
            size_hint: (1, 0.75)
        BoxLayout:
            orientation: "horizontal"
            padding: 10
            size_hint: (1, 0.15)
            Button:
                text: "Okay"
                size_hint: (0.5, 1)
                on_press: image_viewer.image_accepted_by_user(filechooser.selection)
            Button:
                text: "Cancel"
                size_hint: (0.5, 1) 
                on_press: root.manager.current = '_first_screen_'   
""")

class FirstScreen(Screen):
    pass

class SecondScreen(Screen):
    def callback_image_and_other_stuff(self, new_image_address):
        if new_image_address:
            third_screen = self.manager.get_screen("_third_screen_")
            # do other stuff here also, then pass new_image_address along
            new_image_address = new_image_address[0].replace("\\", "/")
            third_screen.callback_image(new_image_address)

class ThirdScreen(Screen):
    img = ObjectProperty(None)

    def __init__(self, **kwargs):
        super(Screen, self).__init__(**kwargs)

    def callback_image(self, new_image_address):
        sm.current = "_third_screen_"
        self.img = new_image_address
        self.ids.main_image.source = self.img

        print(self.img)

# Create the screen manager
sm = ScreenManager() # Problem?
sm.add_widget(FirstScreen(name='_first_screen_'))
sm.add_widget(SecondScreen(name='_second_screen_'))
sm.add_widget(ThirdScreen(name='_third_screen_'))

class MyApp(App):
    def build(self):
        return sm

if __name__ == '__main__':
    MyApp().run()