2017-04-17 65 views
0

如何使用python或kivy訪問另一個類的標籤/ id並避免以下te錯誤? 我在其他文章中搜索過,我發現不可能通過根目錄引用另一個類...... Hower,我不知道有任何其他方法可以做到這一點。我希望你能幫助我。 提前致謝。Kivy,python:如何從根類(FaceRecApp)訪問外部/子類?

FaceRec.py

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.settings import SettingsWithSidebar 
from kivy.uix.boxlayout import BoxLayout 
from kivy.uix.actionbar import ActionBar 
from kivy.logger import Logger 
from kivy.config import Config 

設置屏幕尺寸

Config.set('graphics', 'width', '850') 
Config.set('graphics', 'height', '850') 

主屏幕類

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 FaceRecApp(App): 
    def build(self): 
     root = HomeScreen() 
     Logger.info('FaceRec.py: FaceRec.kv loaded') 
     self.settings_cls = MySettingsWithSidebar 
     Logger.info('FaceRec.py: MySettingsWithSidebar loaded') 

     status = root.ids.StatusBoxLayout.status 
     status.font_size = float(self.config.get('General', 'font_size')) 
     label = root.ids.label 
     label.font_size = float(self.config.get('General', 'font_size')) 

     return root 

    def build_config(self, config): 
     config.setdefaults('General', {'text': 'Default Hello','font_size': 20}) 

    def build_settings(self, settings): 
     settings.add_json_panel('General', self.config, 'Settings.json') 

    def on_config_change(self, config, section, key, value): 
     Logger.info("FaceRec.py: App.on_config_change: {0}, {1}, {2}, {3}".format(config, section, key, value)) 

     if section == "General": 
      if key == "text": 
       self.root.ids.label.text = value 
      elif key == 'font_size': 
       self.root.ids.label.font_size = float(value) 
       self.root.ids.StatusBoxLayout.status = float(value) 

    def close_settings(self, settings): 
     Logger.info("FaceRec.py: App.close_settings: {0}".format(settings)) 
     super(FaceRecApp, self).close_settings(settings) 

側邊欄的設置

class MySettingsWithSidebar(SettingsWithSidebar): 
    def on_close(self): 
     Logger.info('FaceRec.py: MySettingsWithSidebar.on_close') 

    def on_config_change(self, config, section, key, value): 
     Logger.info(
      "FaceRec.py: MySettingsWithSidebar.on_config_change: " 
     "{0}, {1}, {2}, {3}".format(config, section, key, value)) 

執行

if __name__ == '__main__': 
    FaceRecApp().run() 

FaceRec.kv

ScreenManagement: 
HomeScreen: 

<HomeActionBar>: 
    id: HomeActionBar 
    pos_hint: {'bottom':0} 
    ActionView: 
     use_separator: True 
     ActionPrevious: 
      title: 'Home' 
      with_previous: False 
     ActionOverflow: 
     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: 38 

<StatusBoxLayout>: 
    orientation: 'horizontal' 
    #padding: 100 
    Label: 
     id: status 
     text: 'Status: ' 
     font_size: 20 
    Label: 
     id: status_value 
     text: 'Error' 
     font_size: 20 
     color: 1,0,0,1 

<ErrorsBoxLayout>: 
    id: ErrorsBoxLayout 
    orientation: 'horizontal' 
    #padding: 100 
    Label: 
     id: errors 
     text: 'Errors No: ' 
     font_size: 20 
    Label: 
     id: errors_value 
     text: '...' 
     font_size: 20 

<HomeScreen>: 
    id: HomeScreen 
    BoxLayout: 
     orientation: 'vertical' 
     HomeActionBar: 
     TitleLabel: 

     BoxLayout: 
      cols: 2 
      orientation: 'vertical' 

      StatusBoxLayout: 
      ErrorsBoxLayout: 

    Label: 
     id: label 
     text: 'Does it run?' 

Settings.json

[ 
    { 
     "type": "string", 
     "title": "Label caption", 
     "desc": "Choose the text that appears in the label", 
     "section": "General", 
     "key": "text" 
    }, 
    { 
     "type": "numeric", 
     "title": "Label font size", 
     "desc": "Choose the font size the label", 
     "section": "General", 
     "key": "font_size" 
    } 
] 

我試圖訪問標籤變量(FaceRecApp,建立和on_config_change功能)和程序正常運行。當我在設置中更改了標籤的字體大小時,HomeScreen中已應用更改。然後我已經添加的下面幾行代碼:

在構建():

status = root.ids.StatusBoxLayout.status 
status.font_size = float(self.config.get('General', 'font_size')) 

和on_config_change():

self.root.ids.StatusBoxLayout.status = float(value) 

其結果是一個錯誤:

[INFO    ] [Logger  ] Record log in C:\***\.kivy\logs\kivy_17-04-17_109.txt 
[INFO    ] [Kivy  ] v1.9.1 
[INFO    ] [Python  ] v2.7.13 (v2.7.13:a06454b1afa1, Dec 17 2016, 20:53:40) [MSC v.1500 64 bit (AMD64)] 
[INFO    ] [Factory  ] 179 symbols loaded 
[INFO    ] [Image  ] Providers: img_tex, img_dds, img_gif, img_sdl2, img_pil (img_ffpyplayer ignored) 
[INFO    ] [Text  ] Provider: sdl2 
[INFO    ] [OSC   ] using <thread> for socket 
[INFO    ] [Window  ] Provider: sdl2 
[INFO    ] [GL   ] GLEW initialization succeeded 
[INFO    ] [GL   ] OpenGL version <4.5.0 NVIDIA 376.53> 
[INFO    ] [GL   ] OpenGL vendor <NVIDIA Corporation> 
[INFO    ] [GL   ] OpenGL renderer <GeForce ***/PCIe/SSE2> 
[INFO    ] [GL   ] OpenGL parsed version: 4, 5 
[INFO    ] [GL   ] Shading version <4.50 NVIDIA> 
[INFO    ] [GL   ] Texture max size <16384> 
[INFO    ] [GL   ] Texture max units <32> 
[INFO    ] [Window  ] auto add sdl2 input provider 
[INFO    ] [Window  ] virtual keyboard not allowed, single mode, not docked 
[INFO    ] [FaceRec.py ] FaceRec.kv loaded 
[INFO    ] [FaceRec.py ] MySettingsWithSidebar loaded 
Traceback (most recent call last): 
    File "C:/***/PycharmProjects/face_recognition_2/FaceRec.py", line 114, in <module> 
    FaceRecApp().run() 
    File "C:\Python27\lib\site-packages\kivy\app.py", line 802, in run 
    root = self.build() 
    File "C:/***/PycharmProjects/face_recognition_2/FaceRec.py", line 65, in build 
    status = root.ids.StatusBoxLayout.status 
    File "kivy\properties.pyx", line 757, in  kivy.properties.ObservableDict.__getattr__ (kivy\properties.c:11882) 
AttributeError: 'super' object has no attribute '__getattr__' 

Process finished with exit code 1 

我已閱讀此文章(以及其他許多...): How to access id/widget of different class from a kivy file (.kv)? 但我的程序尚未運行。

再次感謝您的支持。

回答

0

你忘了在你的根類(HomeScreen)中給StatusBoxLayout一個id。該id需要在根類中給出,以便能夠將其認爲是self.root.ids.StatusBoxLayout。
所以給它的ID在主屏幕:

<HomeScreen>: 
    id: HomeScreen 
    BoxLayout: 
     orientation: 'vertical' 
     HomeActionBar: 
     TitleLabel: 

     BoxLayout: 
      cols: 2 
      orientation: 'vertical' 

      StatusBoxLayout: 
       id: StatusBoxLayout 
      ErrorsBoxLayout: 
       id: ErrorsBoxLayout 

而當你在這,你還不如給一個id ErrorsBoxLayout過,或任何其他類,你需要通過ID訪問。

現在,當您分配status = root.ids.StatusBoxLayout.status,分配給它像這個:

status = self.root.ids.StatusBoxLayout.ids.status 

你需要預先self理解,因爲在你隨後的App類,要獲取或設置self.root。但是您沒有將root定義爲類屬性。
而第二ids是因爲狀態是StatusBoxLayout
所以您的構建方法的ID,應該是這樣的:

def build(self): 
    self.root = HomeScreen() 
    Logger.info('FaceRec.py: FaceRec.kv loaded') 
    self.settings_cls = MySettingsWithSidebar 
    Logger.info('FaceRec.py: MySettingsWithSidebar loaded') 

    status = self.root.ids.StatusBoxLayout.ids.status 
    status.font_size = float(self.config.get('General', 'font_size')) 
    label = self.root.ids.label 
    label.font_size = float(self.config.get('General', 'font_size')) 

    return self.root