【问题标题】:How can I change source of Image in Kivy?如何更改 Kivy 中的图像来源?
【发布时间】:2021-03-13 23:47:48
【问题描述】:

我正在尝试使用 Kivy 制作一个应用程序,当您单击按钮转到第二个屏幕时,它会拍摄一张照片,然后使用该照片在第二个屏幕中用作 Kivy 图像。我尝试使用对象属性在我的代码中引用图像对象,但是当我尝试更改源时,它返回

'AttributeError: 'NoneType' 对象没有属性'source'

我的 Python 代码:

from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import ObjectProperty
from kivy.core.window import Window
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.image import Image
import random

import time
import cv2
import os

face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

Window.size= (500,800)
class ScreenOne(Screen):
    def __init__(self, **kwargs):
        super(ScreenOne, self).__init__(**kwargs)
    def capture(self):
        try:
            os.remove('faces.jpg')
        except:
            pass
        '''
        Function to capture the images and give them the names
        according to their captured time and date.
        '''
        camera = self.ids['camera']
        timestr = time.strftime("%Y%m%d_%H%M%S")
        camera.export_to_png("IMG_{}.png".format(timestr))
        image = cv2.imread("IMG_{}.png".format(timestr))
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        os.remove("IMG_{}.png".format(timestr))
        faceCascade = cv2.CascadeClassifier(cv2.data.haarcascades + "haarcascade_frontalface_default.xml")
        faces = faceCascade.detectMultiScale(
            gray,
            scaleFactor=1.3,
            minNeighbors=3,
            minSize=(30, 30)
        )

        print("[INFO] Found {0} Faces!".format(len(faces)))

        for (x, y, w, h) in faces:
            #cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
            roi_color = image[y-40:y + h+50, x-20:x + w+40]
            print("[INFO] Object found. Saving locally.")
            cv2.imwrite('faces.jpg', roi_color)

        self.manager.current = 'screen2'


class ScreenTwo(Screen):
    imageview = ObjectProperty(None)
    def __init__(self, **kwargs):
        super(ScreenTwo, self).__init__(**kwargs)
        curdir = os.listdir('.')
        self.imageview.source = 'faces.jpg'




class Manager(ScreenManager):
    screen_one = ObjectProperty(None)
    screen_two = ObjectProperty(None)



class ScreensApp(App):
    def build(self):
        return Manager()


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

还有我的 .kv 文件:

<ScreenOne>:

   BoxLayout:
       orientation: 'vertical'
       size: root.size
       Camera:
           pos_hint:{'top': 1,'center_y': 0.5}
           id: camera
           resolution: (640, 480)
           play: True

       Button:
           text: 'Capture'
           size_hint_y: None
           on_press: root.capture()
           background_normal: 'Up.png'
           background_down: 'down.png'

<ScreenTwo>:
   bl:bl
   but:but
   BoxLayout:
       id: bl
       orientation: 'vertical'
       Image:
           id: imageview
           source: 'faces.jpg'
           size: self.texture_size

       Button:
           id:but
           text: 'screen3'
           on_press: root.manager.current = "screen1"




<Manager>
   id: screen_manager

   screen_one: screen_one
   screen_two: screen_two




   ScreenOne:
       id: screen_one
       name: "screen1"
       manager: screen_manager

   ScreenTwo:
       id: screen_two
       name: "screen2"
       manager: screen_manager

任何帮助将不胜感激!

【问题讨论】:

  • 您可能需要一个空白的faces.jpg 作为替身,这样您的应用才会加载。不要使用os.remove('faces.jpg'),直接覆盖即可。
  • 问题是我试过了,但是当它进入第二个屏幕时,它使用的是原始 faces.jpg,而不是新覆盖的。我的主要问题是,有没有办法从 python 代码中引用图像对象?
  • 我不记得细节了,我已经好几年没有使用 kivy 了。我知道你可以 ask_update kivy.org/doc/stable/…reload kivy.org/doc/stable/… 但我不记得这些与屏幕/小部件有什么关系。您可能需要等到 拍照后 才能将该屏幕添加到您的窗口管理器中。或者从管理器中删除小部件,而不是将其重新添加 - 如果您拍摄的照片不止一张。

标签: python kivy buildozer


【解决方案1】:

&lt;ScreenTwo&gt; 规则中添加一行来定义imageview 的值,如下所示:

<ScreenTwo>:
   imageview: imageview
   bl:bl
   but:but
   BoxLayout:
       id: bl
       orientation: 'vertical'
       Image:
           id: imageview
           source: 'faces.jpg'
           size: self.texture_size

       Button:
           id:but
           text: 'screen3'
           on_press: root.manager.current = "screen1"

【讨论】:

    猜你喜欢
    • 2016-08-17
    • 1970-01-01
    • 1970-01-01
    • 2015-12-28
    • 1970-01-01
    • 2012-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多