首页 > 解决方案 > 如何在屏幕中选择图像并使用 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 的新手,我不知道这是否有意义,所以我没有将它们包括在这里。

标签: imagekivykivy-language

解决方案


我处理将信息从一个屏幕传递到另一个屏幕的方法是拥有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

到底是怎么回事?所以首先 aStringPropertyScreenManager. 与这些属性的绑定是自动创建的,因此引用此属性的内容将随着它的更改而更新。

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

  • root是根小部件,
  • manager是每个屏幕都有的一个属性,它指向它的父级ScreenManager
  • image_source是我们之前创建的属性。

希望这可以帮助。我没有测试上述内容,因此可能会出现一两个错误,但我认为拥有需要相互传递的ScreenManager持有对象的一般概念是我解决此问题的方法。Screen


推荐阅读