实际上,我有两个类似的问题:
如何从TrainerBtn的on_release函数访问TrainerBoxLayout的trained_faces_value.text?根类的过程是:
self.root.ids.TrainerBoxLayout.ids.trained_faces_value.text
并且程序运行正常,因此我在self.parent(然后是self.parent.parent)中更改了self.root但是进程失败并返回 '流程已完成,退出代码为1'。
(我已经在网上搜索了很多而没有找到符合我问题的解决方案)
FaceRec.py
Kivy图书馆
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager,Screen
from kivy.uix.widget import Widget
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
from kivy.uix.settings import SettingsWithSidebar
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.actionbar import ActionBar
from kivy.logger import Logger
from kivy.core.window import Window
HomeScreen类
class ScreenManagement(ScreenManager):
pass
class HomeScreen(Screen):
pass
class HomeActionBar(ActionBar):
pass
class TitleLabel(Label):
pass
class StatusBoxLayout(BoxLayout):
pass
class ErrorsBoxLayout(BoxLayout):
pass
class TrainerBoxLayout(BoxLayout):
pass
class TrainerBtn(Button):
def on_release(self):
global face_name
face_name = face_name.replace(' ','')
...
class FaceNameTxtIn(TextInput):
def on_text(self,instance,value):
global face_name
face_name = value
class RecognizerBtn(Button):
def on_release(self):
...
主要课程
class FaceRecApp(App):
...
def build(self):
self.root = HomeScreen()
Logger.info('FaceRec.py: FaceRec.kv loaded')
self.settings_cls = MySettingsWithSidebar
Logger.info('FaceRec.py: MySettingsWithSidebar loaded')
...
return self.root
...
补充工具栏设置
class MySettingsWithSidebar(SettingsWithSidebar):
...
执行
if __name__ == '__main__':
FaceRecApp().run()
FaceRec.kv
#: import WipeTransition kivy.uix.screenmanager.WipeTransition
<ScreenManagement>:
transition: WipeTransition()
HomeScreen:
<HomeActionBar>:
id: HomeActionBar
background_color: 0.9,0.9,0.9,0.5
pos_hint: {'top':1}
size_hint_x: 1
ActionView:
use_separator: True
ActionPrevious:
title: 'Home'
with_previous: False
ActionOverflow:
ActionButton:
text: 'Logs'
on_release:
ActionButton:
text: 'Settings'
icon: 'settings.png'
background_down: 'settings.png'
on_release:
app.open_settings()
<TitleLabel>:
id: TitleLabel
text: '[b]FaceRec[/b] - [i]The Face Recognition Project[/i]'
color: 0.0,0.3,1,1
markup: True
font_size: 45
<StatusBoxLayout>:
orientation: 'horizontal'
Label:
id: status
text: 'Status: '
Label:
id: status_value
text: 'Error'
color: 1,0,0,1
<ErrorsBoxLayout>:
id: ErrorsBoxLayout
orientation: 'horizontal'
Label:
id: errors
text: 'Errors No: '
Label:
id: errors_value
text: '...'
<TrainerBoxLayout>:
id: TrainerBoxLayout
orientation: 'horizontal'
Label:
id: trained_faces
text: 'Trained faces: '
Label:
id: trained_faces_value
text: '...'
<TrainerBtn>:
id: TrainerBtn
text: 'Press to run the Face Trainer'
font_size: 25
size_hint: 0.5,1.4
<FaceNameTxtIn>:
id: FaceNameTxtIn
hint_text: 'Insert your name and then press the button below'
font_size: 19
size_hint: 0.5,1.4
multiline: False
<RecognizerBtn>:
id: RecognizerBtn
text: 'Press to run the Face Recognizer'
font_size: 25
size_hint: 0.5,1.4
<HomeScreen>:
id: HomeScreen
name: 'HomeScreen'
canvas.before:
Rectangle:
pos: self.pos
size: self.size
source: 'face_pointed.png'
HomeActionBar:
id: HomeActionBar
BoxLayout:
orientation: 'vertical'
spacing: 70
TitleLabel:
id: TitleLabel
BoxLayout:
orientation: 'vertical'
spacing: 20
StatusBoxLayout:
id: StatusBoxLayout
ErrorsBoxLayout:
id: ErrorsBoxLayout
TrainerBoxLayout:
id: TrainerBoxLayout
FaceNameTxtIn:
id: FaceNameTxtIn
BoxLayout:
orientation: 'horizontal'
TrainerBtn:
id: TrainerBtn
RecognizerBtn:
id: RecognizerBtn
Label:
text: 'Press q to quit the video'
font_size: 20
感谢您的宝贵支持。
答案 0 :(得分:0)
在Kivy内,有不同的可能性来访问其他类。
您也可以使用父级和子级访问类,这通常是一个坏主意,因为每次更改结构时都必须调整路径。
一般来说,这些类很多人都知道,这是通过使用Kivy属性来完成的。
正如您在此示例中所看到的,您必须在要使用的上下文中定义属性。 Root经常是一个好地方。
以下示例演示了如何使用Properties来使用kv文件和python来操作数据。
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
Builder.load_string('''
<MyLabel1>:
text:"label 1"
<MyLabel2>
text:"label 2"
<AppRoot>:
lbl_1:lbl_1
lbl_2:lbl_2
btn_1:btn_1
MyLabel1:
id: lbl_1
BoxLayout:
orientation:"vertical"
BoxLayout:
BoxLayout:
Label:
text:"ignore this"
MyLabel2:
id:lbl_2
Button:
id:btn_1
on_press:
root.lbl_2.text = root.lbl_1.text
root.do_something_in_root()
app.do_something_in_app()
''')
class MyLabel1(Label):
pass
class MyLabel2(Label):
pass
class AppRoot(BoxLayout):
def do_something_in_root(self):
print("AppRoot {}".format(self.lbl_1.text))
self.lbl_2.text="set in AppRoot"
class TestApp(App):
def build(self):
return AppRoot()
def do_something_in_app(self):
print("App {}".format(self.root.lbl_2.text))
self.root.lbl_1.text="set in APP"
if __name__ == '__main__':
TestApp().run()
在您的情况下,您可以使用以下方法(所有这些都在下面的代码中实现):
FaceNameTxtIn:FaceNameTxtIn
TrainerBtn:TrainerBtn
id: HomeScreen
name: 'HomeScreen'
canvas.before:
Rectangle:
pos: self.pos
size: self.size
source: 'face_pointed.png'
HomeActionBar:
id: HomeActionBar
BoxLayout:
orientation: 'vertical'
spacing: 70
TitleLabel:
id: TitleLabel
BoxLayout:
orientation: 'vertical'
spacing: 20
StatusBoxLayout:
id: StatusBoxLayout
ErrorsBoxLayout:
id: ErrorsBoxLayout
TrainerBoxLayout:
id: TrainerBoxLayout
FaceNameTxtIn:
id: FaceNameTxtIn
text:root.TrainerBtn.txt
BoxLayout:
orientation: 'horizontal'
TrainerBtn:
id: TrainerBtn
on_press:
root.FaceNameTxtIn.text="on press from TrainerBtn"
root.on_press_from_btn()
app.on_press_from_bnt2()
RecognizerBtn:
id: RecognizerBtn
Label:
text: 'Press q to quit the video'
font_size: 20
在Py文件中:
class HomeScreen(Screen):
def __init__(self, **kwargs):
super(HomeScreen, self).__init__(**kwargs)
def on_press_from_btn(self):
print("some button was pressed")
# the property is defined in the kv
self.FaceNameTxtIn.text="value changed from method in app"
class FaceRecApp(App):
def on_press_from_bnt2(self):
print("on press executed in app");
app = App.get_running_app()
app.root.FaceNameTxtIn.text="value changed from method in app"