Я новичок в Python и объектно-ориентированном программировании. Я делаю свой графический интерфейс в kivy, с несколькими страницами, диспетчером экранов, экранами и классами. Я столкнулся с проблемой доступа к объектам и их обновления с разных экранов и классов.

Я думаю, что это способ ссылки на идентификатор объекта, который я не понимаю.

Был бы очень признателен, если бы кто-нибудь достаточно добрый мог направить и помочь мне. Спасибо. Извините за код, старался максимально сократить.

У меня проблема с обновлением цвета фона идентификатора process_available .

На который я пытался ссылаться, используя эту строку (не уверен, что я прав) -> WindowWithMenuTemplate.process_available.background_color = 1, 1, 1, 1

Который принадлежит к классу ProcessIndicatorTemplate внутри WindowWithMenuTemplate прикреплен к экрану AccWindow на экранное меню WindowManager .

Ошибка, которую он возвращает,

WindowWithMenuTemplate.process_available.background_color = 1, 1, 1, 1
 AttributeError: 'kivy.properties.ObjectProperty' object has no attribute 'background_color'

В питоне

import os
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.label import Label
from kivy.uix.spinner import Spinner
from kivy.properties import ObjectProperty, StringProperty
from kivy.clock import Clock
import requests
from base64 import b64encode, b64decode
from Crypto.Cipher import PKCS1_v1_5
from Crypto.PublicKey import RSA
import time
import numpy as np
import pandas as pd

class AccWindow(Screen):
    def __init__(self, **kwargs):
        super(AccWindow, self).__init__(**kwargs)

        acc0_user_record = ObjectProperty(None)

    def acc0_login_btn(self, acc_no):
        # i shorten this function as an illustration to ask, else the code is very long. the rest of codes is 
        # working except this specific line is not working below which i am trying to change another class object 
        # background color when i press this login_btn
        WindowWithMenuTemplate.process_available.background_color = 1, 1, 1, 1
        # this line below works
        self.acc0_user_record.background_color = 0, 0, 0, 0

class WindowWithMenuTemplate(FloatLayout):
    def __init__(self, **kwargs):
        super(WindowWithMenuTemplate, self).__init__(**kwargs)

        process_available = ObjectProperty(None)
        process_in_automation = ObjectProperty(None)
        process_in_manual = ObjectProperty(None)

class BackgroundColorLabelTemplate(Label):
    pass

class ProcessIndicatorTemplate(Label):
    pass

class WindowManager(ScreenManager):
    pass

class MyApp(App):
    def build(self):
        wm = WindowManager()
        return wm

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

В кывах

<WindowManager>:
    LoginWindow:
    HomeWindow:
    ExecutionWindow:
    OrdersWindow:
    AccWindow:
    SettingsWindow:

<HomeWindow>:
    name: "home_window"
    WindowWithMenuTemplate:

<ExecutionWindow>:
    name: "execution_window"
    WindowWithMenuTemplate:

<OrdersWindow>:
    name: "orders_window"
    WindowWithMenuTemplate:

<AccWindow>:
    name: "acc_window"
    acc0_user_record: acc0_user_record
    WindowWithMenuTemplate:

    GridLayout:
        cols: 4
        padding: 10, 10, 10, 10
        spacing: 10,10
        size_hint: 1, 0.834
        pos_hint: {"x": 0, "y": 0}

        GridLayout:
            cols: 1
            Label:
                text: "Acc 0"
                font_size: 11
            GridLayout:
                cols: 3
                BackgroundColorLabelTemplate:
                    id: acc0_user_record
                    text: ""
                    font_size: 11
                TextInput:
                    id: acc0_user_input
                    text: ""
                    font_size: 11
                    multiline: False
            GridLayout:
                cols: 1
                Button:
                    text: "Submit"
                    font_size: 11
                    disabled: True if acc_win_toggle_off.state == "down" and acc_win_toggle_on.state == "normal" else False
                    on_release:
                        root.acc0_login_btn("0")
                        acc_win_toggle_off.state = "down"
            GridLayout:
                cols: 1
                Button:
                    text: "Logout"
                    font_size: 11
                    disabled: True if acc_win_toggle_off.state == "down" and acc_win_toggle_on.state == "normal" else False
                    on_release:
                        root.acc0_logout_btn()
                        acc_win_toggle_off.state = "down"

<SettingsWindow>:
    name: "settings_window"
    WindowWithMenuTemplate:

<WindowWithMenuTemplate>:
    process_available: process_available
    process_in_automation: process_in_automation
    process_in_manual: process_in_manual

    ActionBar:
        pos_hint: {"x": 0, "top":1}
        ActionView:
            use_separator: False
            ActionPrevious:
                title: "My"
                with_previous: True
                on_release:
                    app.root.current = "home_window"
            ActionButton:
                text: "Execution"
                on_release:
                    app.root.current = "execution_window"
            ActionButton:
                text: "Orders"
                on_release:
                    app.root.current = "orders_window"
            ActionGroup:
                text: "Options"
                mode: "spinner"
                ActionButton:
                    text: "Acc"
                    on_release:
                        app.root.current = "acc_window"
                ActionButton:
                    text: "Settings"
                    on_release:
                        app.root.current = "settings_window"
                ActionButton:
                    text: "Logout"
                    on_release:
                        app.root.current = "login_window"

    GridLayout:
        size_hint: 0.1, 0.05
        pos_hint: {"x": 0.9, "top": 0.922}
        cols: 3
        ProcessIndicatorTemplate:
            id: process_available
        ProcessIndicatorTemplate:
            id: process_in_automation
        ProcessIndicatorTemplate:
            id: process_in_manual

<BackgroundColorLabelTemplate>:
    background_color: 0,0,0,0
    canvas.before:
        Color:
            rgba: root.background_color
        Rectangle:
            size: self.size
            pos: self.pos

<ProcessIndicatorTemplate>:
    background_color: 0,0,0,0
    canvas.before:
        Color:
            rgba: root.background_color
        Ellipse:
            size: self.size
            pos: self.pos
0
Kaixuan Ang 21 Мар 2021 в 10:48

1 ответ

Лучший ответ

Вы должны получать доступ к значениям свойств на уровне экземпляра, а не на уровне класса, поэтому

WindowWithMenuTemplate.process_available.background_color = 1, 1, 1, 1

Вызывает ошибку. Один из способов исправить это - сослаться на экземпляр, добавив id к WindowWithMenuTemplate в kv:

<AccWindow>:
    name: "acc_window"
    acc0_user_record: acc0_user_record
    WindowWithMenuTemplate:
        id: wwmt

Затем используйте это в коде Python:

def acc0_login_btn(self, acc_no):
    # i shorten this function as an illustration to ask, else the code is very long. the rest of codes is
    # working except this specific line is not working below which i am trying to change another class object
    # background color when i press this login_btn
    # WindowWithMenuTemplate.process_available.background_color = 1, 1, 1, 1
    self.ids.wwmt.process_available.background_color = 1, 1, 1, 1
    # this line below works
    self.acc0_user_record.background_color = 0, 0, 0, 0
0
John Anderson 21 Мар 2021 в 13:27