如何使用 kivy select 屏幕中的图像并将其显示在另一个屏幕上?

How to select an image in a screen and display it on another using kivy?

我正在使用 Kivy 为图像分类任务创建一个简单的双屏界面。在第一个屏幕中,我使用文件选择器选择图像并显示它。在第二个屏幕中,我想显示相同的图像和分类任务的结果。屏幕之间的转换是通过第一个屏幕上的按钮完成的。

我的问题是:当我按下按钮时,如何在副屏上触发图像源属性的更新,从而使选择的图像显示在副屏上? 分类部分只是为了了解我的问题的背景,我没有把它包含在代码中。

这是 main.py 文件

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

class WindowManager(ScreenManager):
    image_source = StringProperty()
    def selected(self,filename):
        try:    
            self.image_source = filename[0]
        except:
            pass
    
# Screen where the image is selected
class ImageSelector(Screen):
    pass

# Display image & classification results
class ClassificationResultWindow(Screen):
    pass

class MainApp(App):
    def build(self):        
        self.image_selector = ImageSelector()
        self.scan_result_window = ClassificationResultWindow()

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

这里是 main.kv 文件

#:kivy 2.0.0
WindowManager:
    ImageSelector:
    ClassificationResultWindow:

<ImageSelector>:
    name: "image_selector"
    id: image_selector
    BoxLayout:
        orientation: 'vertical'
        id: image_box
        FileChooserListView:
            id: filechooser
            on_selection: 
                root.manager.selected(filechooser.selection)
                print(root.manager.image_source)             
            size_hint: 1, 10           
        Image:
            id: image
            source: root.manager.image_source
            size_hint: 1, 4 
        Button:
            id: diagnose
            text: "Classify"
            on_release: 
                print(root.manager.image_source) 
                app.root.current = "classification_result"

<ClassificationResultWindow>:
    name: "classification_result"
    BoxLayout:
        orientation: 'vertical'
        id: box
        Image:
            id: scan
            source: root.manager.image_source
            size_hint: 1, 10        
        Label:
            text: "Here comes the classification result"
            font_size: 30
            size_hint: 1, 2
            id: label

我尝试以不同的方式绑定 属性 但没有成功,但由于我是 kivy 的新手,我不知道它是否有意义,所以我没有在此处包括它们。

我处理将信息从一个屏幕传递到另一个屏幕的方式是让 ScreenManager 保留属性,并让 Screen 访问它们。

您的 main.py 文件现在应该是:

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

class WindowManager(ScreenManager):
    image_source = StringProperty()
    def selected(self,filename):
        try:    
            self.image_source = filename[0]
        except:
            pass
    
# Screen where the image is selected
class ImageSelector(Screen):
    pass

# Display image & classification results
class ClassificationResultWindow(Screen):
    pass

class MainApp(App):
    pass     

if __name__ == "__main__":
    MainApp().run()
#:kivy 2.0.0
WindowManager:
    ImageSelector:
    ClassificationResultWindow:

<ImageSelector>:
    name: "image_selector"
    id: image_selector
    BoxLayout:
        orientation: 'vertical'
        id: image_box
        FileChooserListView:
            id: filechooser
            on_selection: 
                root.manager.selected(filechooser.selection)          
            size_hint: 1, 10           
        Image:
            id: image
            screen: image_selector 
            source: self.screen.manager.image_source
            size_hint: 1, 4 
        Button:
            id: diagnose
            text: "Classify"
            on_release: 
                app.root.current = "classification_result"

<ClassificationResultWindow>:
    name: "classification_result"
    id: classification_results
    BoxLayout:
        orientation: 'vertical'
        id: box
        Image:
            id: scan
            screen: classification_results
            source: self.screen.manager.image_source
            size_hint: 1, 10        
        Label:
            text: "Here comes the classification result"
            font_size: 30
            size_hint: 1, 2
            id: label

这是怎么回事?所以首先在 ScreenManager 中创建了一个 StringProperty。这些属性的绑定是自动创建的,因此引用此 属性 的内容将在更改时更新。

然后每个 Screen 中的 Image class 通过 root.manager.image_source.

引用此 StringProperty
  • root 是根控件,
  • manager 是一个 属性,每个屏幕都有它指向其父 ScreenManager
  • image_source就是我们之前创建的属性。

希望这对您有所帮助。我没有测试上面的内容,所以可能会有一两个错误,但我认为让 ScreenManager 保存 Screen 需要传递给彼此的对象的一般概念是我如何解决这个问题。