【问题标题】:How do I pass variables between classes functions?如何在类函数之间传递变量?
【发布时间】:2019-05-24 02:03:19
【问题描述】:

好吧,我需要将 price 变量传递给 Tela 4 函数 whatever。我对 Python 很陌生,我不知道如何做到这一点,即使我认为它很简单

这就是代码现在的样子,请随时添加有关如何改进它的建议。

class Tela2(Screen):
    def op_dimoff(self):
        self.price = float((int(self.ngd) * 0.87 * 1.75) + self.price_inv)

class Tela4 (Screen):
    def whatever(self):
        tela_two = Tela2
        self.cost_output.text = str(tela_two.price)

“cost_output”指的是 kivy 标签


更新:

我认为@slackmart 的做法是正确的,但我仍然无法得到想要的结果。我收到错误AttributeError: 'Tela2' object has no attribute 'irrad'(对不起,我没有发布更完整的代码版本,这是我在这里的第一个问题,我害怕发布很长的问题)

现在的代码就是这样,如果你们能帮我找到解决方案:

class Tela2(Screen):

   ngd = ObjectProperty()

   def __init__(self, **kwargs):
       super(Tela2, self).__init__(**kwargs)
       self.price = 0.0
       self.ngd = 0.0
       self.price_inv = 0.0


   def region_define(self, text):

       self.inorte: float = 4.825
       self.inordeste: float = 5.483
       self.icentro: float = 5.082
       self.isudeste: float = 4.951
       self.isul: float = 4.444

       self.kwh_norte: float = 0.871
       self.kwh_nordeste: float = 0.308
       self.kwh_centro: float = 0.290
       self.kwh_sudeste: float = 0.322
       self.kwh_sul: float = 0.320

       if text == 'Norte':
           self.irrad = self.inorte
           self.kwh = self.kwh_norte

       elif text == 'Nordeste':
           self.irrad = self.inordeste
           self.kwh = self.kwh_nordeste

       elif text == 'Centro-Oeste':
           self.irrad = self.icentro
           self.kwh = self.kwh_centro

       elif text == 'Sudeste':
           self.irrad = self.isudeste
           self.kwh = self.kwh_sudeste

       else:
           self.irrad = self.isul
           self.kwh = self.kwh_sul

   def op_dimoff(self):

   # cálculo da Geração Mínima = (NGD/irrad)
   self.gmin = float(self.ngd/self.irrad)# em W/h

   # dimensionamento potência do inversor
   self.pot_seg = self.gmin * 1.3
   self.inv = (600, 1000, 1500, 2000, 3000)
   self.pri_inv = (1434, 1852.2, 1924, 2604, 3899)
   self.x = 0
   for self.x in range(0, len(self.inv)):
       if self.pot_seg <= self.inv[int(self.x)]:
           self.pot_inv = self.inv[int(self.x)]
           self.price_inv = self.pri_inv[int(self.x)]
           break
       else:
           self.x += 1

    self.price = float((int(self.ngd) * 0.87 * 1.75) + self.price_inv)

注意事项:

region_define 是 kivy 微调器的 on_text 函数

【问题讨论】:

  • tela_two = Tela2 更改为 tela_two = Tela2()
  • @evyllanesc 照你说的做,我得到了这个“AttributeError: 'Tela2' object has no attribute 'price'”
  • 使用minimal reproducible example 会更容易回答。例如,Kivy 似乎无关紧要,一堆未定义的名称,例如 Screenself.ngd,并且您的类已定义但未使用。

标签: python-3.x kivy


【解决方案1】:

解决方案

解决方案有两种选择。

注意:

不建议使用tela_two = Tela2(),因为您正在创建另一个对象实例Tela2,它没有与之关联的视图和不同的属性更新值。

选项 1 - 使用 get_screen()

在此选项中,我们使用get_screen() 函数检索实例化对象Tela2:,以便我们可以访问其方法或属性,例如price。我们将进行以下改进:

kv 文件:

  • name 屏幕,name: 'Tela2'name: 'Tela4' 分别用于实例化对象,Tela2:Tela4:

片段 - kv 文件

ScreenManager:
    Tela2:
        name: 'Tela2'
    ...
    Tela4:
        name: 'Tela4'

Py 文件

片段 - Py 文件

def whatever(self):
    tela_two = self.manager.get_screen('Tela2')
    self.cost_output.text = str(tela_two.price)

def whatever(self):
    self.cost_output.text = str(self.manager.get_screen('Tela2').price)

选项 2 - 使用 id: tela2

在此选项中,我们将id: tela2 添加到实例化对象Tela2: 并使用ids.tela2 访问其方法或属性,例如price。我们将进行以下改进:

kv 文件:

  • id: tela2 添加到实例化对象Tela2:

片段 - kv 文件

ScreenManager:
    Tela2:
        id: tela2
    ...
    Tela4:

Py 文件

  • tela_two = Tela2 替换为tela_two = self.manager.ids.tela2

片段 - Py 文件

def whatever(self):
    tela_two = self.manager.ids.tela2
    self.cost_output.text = str(tela_two.price)

def whatever(self):
    self.cost_output.text = str(self.manager.ids.tela2.price)

Kivy ScreenManager » default property manager

默认情况下,每个屏幕都有一个属性manager,它为您提供 使用的ScreenManager 的实例。

示例 - 使用 id:tela2

以下示例说明使用get_screen() 函数和ids.tela2 访问对象Tela2 中定义的属性。它还通过调用self.region_define('Norte')self.op_dimoff() 模拟on_text 事件。

main.py

​​>
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import ObjectProperty
from kivy.lang import Builder

Builder.load_string("""
<ScreenManagement>:
    Tela2:
        id: tela2
        name: 'Tela2'
    Tela4:
        name: 'Tela4'

<Tela2>:
    Button:
        text: 'Goto Tela4'
        on_release: root.manager.current = 'Tela4'
<Tela4>:
    on_pre_enter:
        self.whatever()
    Label:
        id: cost_output
        font_size: sp(50)
""")


class Tela2(Screen):
    ngd = ObjectProperty(None)

    def __init__(self, **kwargs):
        super(Tela2, self).__init__(**kwargs)
        self.price = 0.0
        self.ngd = 0.0
        self.price_inv = 0.0

        # simulation
        self.region_define('Norte')
        self.op_dimoff()

    def region_define(self, text):
        self.inorte: float = 4.825
        self.inordeste: float = 5.483
        self.icentro: float = 5.082
        self.isudeste: float = 4.951
        self.isul: float = 4.444

        self.kwh_norte: float = 0.871
        self.kwh_nordeste: float = 0.308
        self.kwh_centro: float = 0.290
        self.kwh_sudeste: float = 0.322
        self.kwh_sul: float = 0.320

        if text == 'Norte':
            self.irrad = self.inorte
            self.kwh = self.kwh_norte

        elif text == 'Nordeste':
            self.irrad = self.inordeste
            self.kwh = self.kwh_nordeste

        elif text == 'Centro-Oeste':
            self.irrad = self.icentro
            self.kwh = self.kwh_centro

        elif text == 'Sudeste':
            self.irrad = self.isudeste
            self.kwh = self.kwh_sudeste

        else:
            self.irrad = self.isul
            self.kwh = self.kwh_sul

    def op_dimoff(self):
        # cálculo da Geração Mínima = (NGD/irrad)
        self.gmin = float(self.ngd / self.irrad)  # em W/h

        # dimensionamento potência do inversor
        self.pot_seg = self.gmin * 1.3
        self.inv = (600, 1000, 1500, 2000, 3000)
        self.pri_inv = (1434, 1852.2, 1924, 2604, 3899)
        self.x = 0
        for self.x in range(0, len(self.inv)):
            if self.pot_seg <= self.inv[int(self.x)]:
                self.pot_inv = self.inv[int(self.x)]
                self.price_inv = self.pri_inv[int(self.x)]
                break
            else:
                self.x += 1

        self.price = float((int(self.ngd) * 0.87 * 1.75) + self.price_inv)


class Tela4(Screen):

    def whatever(self):
        # Each screen has by default a roperty manager that gives you the instance of the ScreenManager used.
        self.ids.cost_output.text = str(self.manager.ids.tela2.price)
        print(f"tela2.irrad={self.manager.ids.tela2.irrad}")
        print(f"tela2.kwh={self.manager.get_screen('Tela2').kwh}")


class ScreenManagement(ScreenManager):
    pass


class TestApp(App):

    def build(self):
        return ScreenManagement()


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

输出

【讨论】:

  • 我得到这个 ``` AttributeError: 'Tela4' object has no attribute 'root'```
  • Tela4 是否被实例化为 ScreenManager 的子级?
  • self.root.ids.tela2.price 替换为self.parent.ids.tela2.price注意:您不想使用tela_two = Tela2(),因为您正在创建对象的另一个实例Tela2,并且它没有与之关联的视图。你会得到 AttributeError ,即没有属性或小部件,即使它是用 kv 语言为 Tela2 定义的。
  • 在我的代码中实现得到了这个line 264, in whatever self.ids.cost_output.text = str(self.parent.ids.tela2.price) File "kivy\properties.pyx", line 841, in kivy.properties.ObservableDict.__getattr__ AttributeError: 'super' object has no attribute '__getattr__' 你知道这个错误是关于什么的吗?
  • 请提供Minimal, Reproducible Example(包括kv文件和main.py),以便我们重现错误。
猜你喜欢
  • 1970-01-01
  • 2019-06-04
  • 2020-07-02
  • 1970-01-01
  • 1970-01-01
  • 2013-04-09
  • 2013-03-07
  • 1970-01-01
相关资源
最近更新 更多