Python和Kivy:相机和切换屏幕

问题描述 投票:0回答:2

我想用Python用Kivy构建一个应用程序,但遇到了一些错误,但我尝试解决了很多次,但我做不到。

我首先要打开相机屏幕。在屏幕上,我们将看到网络摄像头屏幕,并且底部有2个按钮(播放和捕获)。当我按“播放”时,网络摄像头将打开,如果按“捕获”按钮,我想拍摄快照。我构建了工作代码,直到此处。

[按“捕获”按钮并拍摄快照后,我想更改屏幕以转到第二屏幕,它只会在黑色背景上显示一个基本的Hello World句子。

这是我的代码,我的错在哪里?你可以解决吗?

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import ScreenManager, Screen
import time

class CheckScreen(Screen):
    pass

class ScreenManagement(ScreenManager):
    pass

Builder.load_string("""
ScreenManagement:
    CheckScreen:

<CameraClick@ScreenManager>:
    orientation: 'vertical'
    Camera:
        id: camera
        resolution: (640, 480)
        play: False
    ToggleButton:
        text: 'Play'
        on_press: camera.play = not camera.play
        size_hint_y: None
        height: '48dp'
    Button:
        text: 'Capture'
        size_hint_y: None
        height: '48dp'
        on_press:
            root.capture()
            root.manager.transition.direction = 'left'
            root.manager.current = 'check'

<CheckScreen>:
    name: "check"
    Button:
        text: "Next Screen"
        font_size: 50
""")

class CameraClick(BoxLayout):

    def capture(self):
        camera = self.ids['camera']
        timestr = time.strftime("%Y%m%d_%H%M%S")
        camera.export_to_png("IMG_{}.png".format(timestr))
        print("Captured")
        return CheckScreen

class TestCamera(App):

    def build(self):
        return CameraClick()


TestCamera().run()

当我运行此代码时,它显示;

[AttributeError:'CameraClick'对象没有属性'manager']

python camera kivy screen
2个回答
0
投票

您的代码有几个问题。正如约翰·安德森(John Anderson)在评论中提到的那样,您在py / kv文件中有一个继承自不同类的类。您还拥有2个屏幕管理器-您只需要1个。我相信您的CameraClick类实际上应该仅从kivy继承Screen,而不是ScreenManagerBoxLayout。您可以在CameraClick类本身内部定义布局。

您的错误是由于您试图获取尚未在任何地方定义的CameraClick类的'manager'属性而引起的。要引用屏幕管理器(看起来就是您要尝试的操作),您必须给屏幕管理器指定一个“ id”,并以这种方式引用它(就像您在“相机”中一样)。

使用ScreenManager时,另一个好的做法是在将屏幕添加到ScreenManager小部件时提供屏幕以及ID和名称。例如代替

ScreenManagement:
    CheckScreen:

执行

ScreenManagement:
    CheckScreen:
        name: "check_screen"
        id: check_screen

[另一个好的做法是将kv代码加载到变量中,然后在主应用程序的build方法中将其返回。依此类推。我对您的代码做了一些更改,我认为它现在应该可以完成您期望的工作。请花些时间对其进行审核并与您进行比较,以便您可以看到它们之间的差异,并让我知道它是否不是您想要的。

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import ScreenManager, Screen
import time

class CheckScreen(Screen):
    pass

class CameraClickScreen(Screen):
    def capture(self):
        camera = self.ids['camera']
        timestr = time.strftime("%Y%m%d_%H%M%S")
        camera.export_to_png("IMG_{}.png".format(timestr))


GUI = Builder.load_string("""

GridLayout:
    cols: 1
    ScreenManager:
        id: screen_manager
        CameraClickScreen:
            name: "camera_click_screen"
            id: camera_click_screen
        CheckScreen:
            name: "check_screen"
            id: check_screen



<CameraClickScreen>:
    orientation: 'vertical'
    GridLayout:
        cols: 1
        Camera:
            id: camera
            resolution: (640, 480)
            play: False
        ToggleButton:
            text: 'Play'
            on_press: camera.play = not camera.play
            size_hint_y: None
            height: '48dp'
        Button:
            text: 'Capture'
            size_hint_y: None
            height: '48dp'
            on_press:
                root.capture()
                # root refers to <CameraClickScreen>
                # app refers to TestCamera, app.root refers to the GridLayout: at the top
                app.root.ids['screen_manager'].transition.direction = 'left'
                app.root.ids['screen_manager'].current = 'check_screen'

<CheckScreen>:
    Button:
        text: "Next Screen"
        font_size: 50
""")

class TestCamera(App):

    def build(self):
        return GUI


TestCamera().run()

0
投票

他们的代码没有问题。要在Android上运行代码,您必须授予它权限。这是代码;您可以将其添加到代码顶部:

from android.permissions import request_permissions, Permission
request_permissions([Permission.CAMERA,Permission.WRITE_EXTERNAL_STORAGE,Permission.READ_EXTERNAL_STORAGE])

注意:导入Android模块后,代码在台式机上编译时可能会出现“导入错误”,但它将在Android上成功构建并运行。

此外,请不要忘记更改buildozer.spec文件中的代码:

android.permissions = CAMERA, WRITE_EXTERNAL_STORAGE, READ_EXTERNAL_STORAGE
© www.soinside.com 2019 - 2024. All rights reserved.