为什么我不能在我的 kv 文件的构造函数中引用 self.text_1?
Why can't I reference self.text_1 in the constructor from my kv file?
我正在开发一个简单的 Kivy Popup,我很困惑为什么我不能从 Popup [=] 的构造函数中引用我的 class 变量 'self.text_1' 75=],但我可以使用变量 'self.title'.
首先,我将从无处不在的,"I'm new to Python and Kivy, so perhaps I'm just missing something obvious, but I'm at a loss."
我试图找到答案,但到目前为止似乎没有任何内容涵盖这个主题,至少在某种程度上我可以理解并得出联系。下面是我的问题和一些用于演示的简化代码。
在 kv 文件 > 标签小部件 > 文本中,当变量放在外部时,我可以通过使用 'root.text_1' 从我的 py 文件中的 CustomPopup class 引用 'text_1'构造函数的(之前或之后),但放在其中时我不能这样做。 'self.title' 变量的设置方式与 'self.text_1' 完全相同,但我可以毫无问题地获取该值。
如果我取消注释这一行,在 kv 文件中使用 'root.text_1' returns 正确的值。
class CustomPopup( Popup ):
# I can reference this text from the kv file using "root.text_1"
# text_1 = 'blah blah blah'
如果我尝试从构造函数中使用 'self.text_1',则会收到属性错误。但是,使用 'self.text_1'.
下方的变量 'self.title' 没有问题
AttributeError: 'CustomPopup' 对象没有属性 'text_1'
def __init__( self, foo = 'bar' ):
super().__init__()
self.foo = foo
# I can't reference this text from the kv file using "root.text_1". Why?
self.text_1 = 'blah blah {foo}'.format( foo = self.foo )
# I can reference this text from the kv file using "root.title"
self.title = 'Title {foo}!'.format( foo = self.foo )
为什么我可以从一个构造函数变量中获取值,但不能从表面上类似语法的另一个构造函数变量中获取值,这有什么区别?
我正在使用 Python 3.7.1(conda 版本:4.5.12)和 Kivy 1.10.1。
Python:
import kivy
from kivy import Config
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.popup import Popup
kivy.require( '1.10.1' )
Config.set( 'graphics', 'fullscreen', 0 )
Config.set( 'graphics', 'height', 600 )
Config.set( 'graphics', 'width', 800 )
Config.set( 'graphics', 'resizable', 0 )
Config.set( 'kivy', 'exit_on_escape', 0 )
class CustomPopup( Popup ):
# I can reference this text from the kv file using "root.text_1"
# text_1 = 'blah blah blah'
def __init__( self, foo = 'bar' ):
super().__init__()
self.foo = foo
# I can't reference this text from the kv file using "root.title". Why?
self.text_1 = 'blah blah {foo}'.format( foo = self.foo )
# I can reference this text from the kv file using "root.title"
self.title = 'Title {foo}!'.format( foo = self.foo )
class CustomPopupTestApp( App ):
def build( self ):
return CustomPopup()
#Instantiate top-level/root widget and run it
if __name__ == "__main__":
CustomPopupTestApp().run()
kv:
<CustomPopup>:
id: popup
title: root.title
title_size: 30
title_align: 'center'
size_hint: 0.8, 0.8
auto_dismiss: False
pos_hint: { 'x' : 0.1 , 'y' : 0.1 }
GridLayout:
cols: 1
rows: 2
spacing: 15
padding: 15
Label:
id: content
text: root.text_1
font_size: 25
padding: 15, 25
size_hint_y: None
text_size: self.width, None
height: self.texture_size[ 1 ]
halign: 'center'
GridLayout:
cols: 2
rows: 1
AnchorLayout:
anchor_x : 'center'
anchor_y : 'bottom'
padding: 20
Button:
id: yes
text: 'Yes'
font_size: 30
size_hint: 0.8, 0.4
AnchorLayout:
anchor_x : 'center'
anchor_y : 'bottom'
padding: 20
Button:
id: no
text: 'No'
font_size: 30
size_hint: 0.8, 0.4
我想为我的弹出窗口设置文本并使用 str.format() 方法插入可变文本元素,以便我的消息根据手头的情况量身定制,而不是通用或带有多个选项的硬编码。
在这种情况下,我将参数 'foo' 传递给构造函数,将变量 'self.foo' 设置为等于 'foo',然后在我的 'self.title' 字符串和 'self.text_1' 字符串。
如果我将 'text_1' 放在构造函数之外,虽然我可以检索文本值,但由于 'foo' 尚未在该范围内定义,我无法引用它来格式化我的字符串.
我对其他解决方案和任何学习机会都很感兴趣,但最终,如果有一种方法可以在没有解决方法的情况下完成这项工作,那将是理想的。
在此先感谢您的帮助。我已经从这个网站上的每个人那里学到了很多东西。
P.S。 - 如果我做了什么 "stupid" 或冒犯了你的感情,请提供建议或更正,而不仅仅是责备我。有时人们会变得消极,这(通常)是没有必要的。
通过研究和测试,我找到了答案。
事实证明,首先,我并没有像我想的那样打电话给 'self.title'。因此,我没有看到 'self.title' 与 'self.text_1' 的不同行为;我看到了同样的行为。那么,我怎么才能显示我的标题,而不是我的内容呢?
Popup 小部件具有 'title' 和 'content' 的固有属性。当我在 CustomPopup() 中定义 'self.title' 时,我只是提供了该属性的值。即使在删除相应的 kv 代码 'title: root.title' 之后,仍然显示为 'self.title' 定义的相同值。这是关键时刻,因为我被 'self.title' vs 'self.text_1'.
的转移注意力分散了注意力
在我排除了我看到两行相同代码的不同行为的问题后,我更深入地研究了我是如何定义我的 CustomPopup class。那是我遇到这个 post 的时候,它演示了如何正确处理这个问题:Kivy: How to get class Variables in Popup.
长话短说...略短...我更新了超级方法以继承我的 'text_1' StringProperty 以便我可以从 CustomPopup object!
中引用它
这是更新后的工作解决方案:
Python:
import kivy
from kivy import Config
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.popup import Popup
from kivy.properties import StringProperty
kivy.require( '1.10.1' )
Config.set( 'graphics', 'fullscreen', 0 )
Config.set( 'graphics', 'height', 600 )
Config.set( 'graphics', 'width', 800 )
Config.set( 'graphics', 'resizable', 0 )
Config.set( 'kivy', 'exit_on_escape', 0 )
class CustomPopup( Popup ):
text_1 = StringProperty( '' )
def __init__( self, foo = 'bar' ):
super( CustomPopup, self ).__init__()
self.foo = foo
self.text_1 = 'blah blah {foo}'.format( foo = self.foo )
self.title = 'Title {foo}!'.format( foo = self.foo )
class CustomPopupTestApp( App ):
def build( self ):
blarg = CustomPopup()
return blarg
#Instantiate top-level/root widget and run it
if __name__ == "__main__":
CustomPopupTestApp().run()
kv:
<CustomPopup>:
id: popup
# title: root.title
title_size: 30
title_align: 'center'
size_hint: 0.8, 0.8
auto_dismiss: False
pos_hint: { 'x' : 0.1 , 'y' : 0.1 }
GridLayout:
cols: 1
rows: 2
spacing: 15
padding: 15
Label:
id: content
text: root.text_1
font_size: 25
padding: 15, 25
size_hint_y: None
text_size: self.width, None
height: self.texture_size[ 1 ]
halign: 'center'
GridLayout:
cols: 2
rows: 1
AnchorLayout:
anchor_x : 'center'
anchor_y : 'bottom'
padding: 20
Button:
id: yes
text: 'Yes'
font_size: 30
size_hint: 0.8, 0.4
AnchorLayout:
anchor_x : 'center'
anchor_y : 'bottom'
padding: 20
Button:
id: no
text: 'No'
font_size: 30
size_hint: 0.8, 0.4
请注意,kv 文件不再引用 'root.title',但标题仍能正常显示。
下面 link 中显示的最终产品是一个 Kivy 弹出窗口,其 structure/formatting 在 kv 文件中定义,功能和变量文本在 Python 中定义。对我来说,它看起来比在 Python 侧完成所有操作要干净得多。
CustomPopupTest Working Solution
我希望这对其他人有帮助,就像许多其他 post 帮助过我一样。
我正在开发一个简单的 Kivy Popup,我很困惑为什么我不能从 Popup [=] 的构造函数中引用我的 class 变量 'self.text_1' 75=],但我可以使用变量 'self.title'.
首先,我将从无处不在的,"I'm new to Python and Kivy, so perhaps I'm just missing something obvious, but I'm at a loss."
我试图找到答案,但到目前为止似乎没有任何内容涵盖这个主题,至少在某种程度上我可以理解并得出联系。下面是我的问题和一些用于演示的简化代码。
在 kv 文件 > 标签小部件 > 文本中,当变量放在外部时,我可以通过使用 'root.text_1' 从我的 py 文件中的 CustomPopup class 引用 'text_1'构造函数的(之前或之后),但放在其中时我不能这样做。 'self.title' 变量的设置方式与 'self.text_1' 完全相同,但我可以毫无问题地获取该值。
如果我取消注释这一行,在 kv 文件中使用 'root.text_1' returns 正确的值。
class CustomPopup( Popup ):
# I can reference this text from the kv file using "root.text_1"
# text_1 = 'blah blah blah'
如果我尝试从构造函数中使用 'self.text_1',则会收到属性错误。但是,使用 'self.text_1'.
下方的变量 'self.title' 没有问题AttributeError: 'CustomPopup' 对象没有属性 'text_1'
def __init__( self, foo = 'bar' ):
super().__init__()
self.foo = foo
# I can't reference this text from the kv file using "root.text_1". Why?
self.text_1 = 'blah blah {foo}'.format( foo = self.foo )
# I can reference this text from the kv file using "root.title"
self.title = 'Title {foo}!'.format( foo = self.foo )
为什么我可以从一个构造函数变量中获取值,但不能从表面上类似语法的另一个构造函数变量中获取值,这有什么区别?
我正在使用 Python 3.7.1(conda 版本:4.5.12)和 Kivy 1.10.1。
Python:
import kivy
from kivy import Config
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.popup import Popup
kivy.require( '1.10.1' )
Config.set( 'graphics', 'fullscreen', 0 )
Config.set( 'graphics', 'height', 600 )
Config.set( 'graphics', 'width', 800 )
Config.set( 'graphics', 'resizable', 0 )
Config.set( 'kivy', 'exit_on_escape', 0 )
class CustomPopup( Popup ):
# I can reference this text from the kv file using "root.text_1"
# text_1 = 'blah blah blah'
def __init__( self, foo = 'bar' ):
super().__init__()
self.foo = foo
# I can't reference this text from the kv file using "root.title". Why?
self.text_1 = 'blah blah {foo}'.format( foo = self.foo )
# I can reference this text from the kv file using "root.title"
self.title = 'Title {foo}!'.format( foo = self.foo )
class CustomPopupTestApp( App ):
def build( self ):
return CustomPopup()
#Instantiate top-level/root widget and run it
if __name__ == "__main__":
CustomPopupTestApp().run()
kv:
<CustomPopup>:
id: popup
title: root.title
title_size: 30
title_align: 'center'
size_hint: 0.8, 0.8
auto_dismiss: False
pos_hint: { 'x' : 0.1 , 'y' : 0.1 }
GridLayout:
cols: 1
rows: 2
spacing: 15
padding: 15
Label:
id: content
text: root.text_1
font_size: 25
padding: 15, 25
size_hint_y: None
text_size: self.width, None
height: self.texture_size[ 1 ]
halign: 'center'
GridLayout:
cols: 2
rows: 1
AnchorLayout:
anchor_x : 'center'
anchor_y : 'bottom'
padding: 20
Button:
id: yes
text: 'Yes'
font_size: 30
size_hint: 0.8, 0.4
AnchorLayout:
anchor_x : 'center'
anchor_y : 'bottom'
padding: 20
Button:
id: no
text: 'No'
font_size: 30
size_hint: 0.8, 0.4
我想为我的弹出窗口设置文本并使用 str.format() 方法插入可变文本元素,以便我的消息根据手头的情况量身定制,而不是通用或带有多个选项的硬编码。
在这种情况下,我将参数 'foo' 传递给构造函数,将变量 'self.foo' 设置为等于 'foo',然后在我的 'self.title' 字符串和 'self.text_1' 字符串。
如果我将 'text_1' 放在构造函数之外,虽然我可以检索文本值,但由于 'foo' 尚未在该范围内定义,我无法引用它来格式化我的字符串.
我对其他解决方案和任何学习机会都很感兴趣,但最终,如果有一种方法可以在没有解决方法的情况下完成这项工作,那将是理想的。
在此先感谢您的帮助。我已经从这个网站上的每个人那里学到了很多东西。
P.S。 - 如果我做了什么 "stupid" 或冒犯了你的感情,请提供建议或更正,而不仅仅是责备我。有时人们会变得消极,这(通常)是没有必要的。
通过研究和测试,我找到了答案。
事实证明,首先,我并没有像我想的那样打电话给 'self.title'。因此,我没有看到 'self.title' 与 'self.text_1' 的不同行为;我看到了同样的行为。那么,我怎么才能显示我的标题,而不是我的内容呢?
Popup 小部件具有 'title' 和 'content' 的固有属性。当我在 CustomPopup() 中定义 'self.title' 时,我只是提供了该属性的值。即使在删除相应的 kv 代码 'title: root.title' 之后,仍然显示为 'self.title' 定义的相同值。这是关键时刻,因为我被 'self.title' vs 'self.text_1'.
的转移注意力分散了注意力在我排除了我看到两行相同代码的不同行为的问题后,我更深入地研究了我是如何定义我的 CustomPopup class。那是我遇到这个 post 的时候,它演示了如何正确处理这个问题:Kivy: How to get class Variables in Popup.
长话短说...略短...我更新了超级方法以继承我的 'text_1' StringProperty 以便我可以从 CustomPopup object!
中引用它这是更新后的工作解决方案:
Python:
import kivy
from kivy import Config
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.popup import Popup
from kivy.properties import StringProperty
kivy.require( '1.10.1' )
Config.set( 'graphics', 'fullscreen', 0 )
Config.set( 'graphics', 'height', 600 )
Config.set( 'graphics', 'width', 800 )
Config.set( 'graphics', 'resizable', 0 )
Config.set( 'kivy', 'exit_on_escape', 0 )
class CustomPopup( Popup ):
text_1 = StringProperty( '' )
def __init__( self, foo = 'bar' ):
super( CustomPopup, self ).__init__()
self.foo = foo
self.text_1 = 'blah blah {foo}'.format( foo = self.foo )
self.title = 'Title {foo}!'.format( foo = self.foo )
class CustomPopupTestApp( App ):
def build( self ):
blarg = CustomPopup()
return blarg
#Instantiate top-level/root widget and run it
if __name__ == "__main__":
CustomPopupTestApp().run()
kv:
<CustomPopup>:
id: popup
# title: root.title
title_size: 30
title_align: 'center'
size_hint: 0.8, 0.8
auto_dismiss: False
pos_hint: { 'x' : 0.1 , 'y' : 0.1 }
GridLayout:
cols: 1
rows: 2
spacing: 15
padding: 15
Label:
id: content
text: root.text_1
font_size: 25
padding: 15, 25
size_hint_y: None
text_size: self.width, None
height: self.texture_size[ 1 ]
halign: 'center'
GridLayout:
cols: 2
rows: 1
AnchorLayout:
anchor_x : 'center'
anchor_y : 'bottom'
padding: 20
Button:
id: yes
text: 'Yes'
font_size: 30
size_hint: 0.8, 0.4
AnchorLayout:
anchor_x : 'center'
anchor_y : 'bottom'
padding: 20
Button:
id: no
text: 'No'
font_size: 30
size_hint: 0.8, 0.4
请注意,kv 文件不再引用 'root.title',但标题仍能正常显示。
下面 link 中显示的最终产品是一个 Kivy 弹出窗口,其 structure/formatting 在 kv 文件中定义,功能和变量文本在 Python 中定义。对我来说,它看起来比在 Python 侧完成所有操作要干净得多。
CustomPopupTest Working Solution
我希望这对其他人有帮助,就像许多其他 post 帮助过我一样。