我想用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']
您的代码有几个问题。正如约翰·安德森(John Anderson)在评论中提到的那样,您在py / kv文件中有一个继承自不同类的类。您还拥有2个屏幕管理器-您只需要1个。我相信您的CameraClick类实际上应该仅从kivy继承Screen
,而不是ScreenManager
或BoxLayout
。您可以在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()
他们的代码没有问题。要在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