python - 为什么我不能从我的 kv 文件的构造函数中引用 self.text_1 ?
问题描述
我正在研究一个简单的 Kivy Popup,我很困惑为什么我不能从 Popup 类的构造函数中引用我的类变量“self.text_1”,但我可以使用变量'自.title'。
首先,我将从无处不在的“我是 Python 和 Kivy 的新手,所以也许我只是遗漏了一些明显的东西,但我不知所措”开始。
我试图找到答案,但到目前为止似乎没有任何内容涵盖这个主题,至少在某种程度上我可以理解和绘制连接。下面是我的问题和一些简化的演示代码。
在 kv 文件 > 标签小部件 > 文本中,当变量放置在构造函数之外(之前或之后)时,我可以使用“root.text_1”从我的 py 文件中的 CustomPopup 类中引用“text_1”,但是放在里面时我不能这样做。“self.title”变量的设置方式与“self.text_1”完全相同,但我可以毫无问题地获得该值。
如果我取消注释这一行,在 kv 文件中使用“root.text_1”会返回正确的值。
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()
千伏:
<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.foo”中引用“self.foo”。 text_1' 字符串。
如果我将 'text_1' 放在构造函数之外,虽然我可以检索文本值,但由于尚未在该范围内定义 'foo',我无法引用它来格式化我的字符串。
我对其他解决方案和任何学习机会感兴趣,但最终,如果有一种方法可以在没有解决方法的情况下完成这项工作,那将是理想的。
提前感谢您的帮助。我已经从这个网站上的每个人那里学到了很多东西。
PS - 如果我做了一些“愚蠢”的事情或冒犯了你的感情,请提供建议或更正,而不是仅仅责备我。有时人们会变得消极,这(通常)是没有必要的。
解决方案
通过研究和测试,我找到了答案。
事实证明,首先,我并没有像我想象的那样称呼“self.title”。因此,我没有看到“self.title”与“self.text_1”的不同行为;我看到了同样的行为。那么,我如何才能显示我的标题,而不是我的内容?
Popup 小部件具有“标题”和“内容”的固有属性。当我在 CustomPopup() 中定义“self.title”时,我只是提供了该属性的值。即使删除了相应的 kv 代码 'title: root.title',仍然会显示为 'self.title' 定义的相同值。这是关键时刻,我被“self.title”与“self.text_1”的红鲱鱼分心了。
一旦我排除了我看到两行相同代码行的不同行为的问题,我就更深入地研究了我是如何定义我的 CustomPopup 类的。就在那时,我看到了这篇文章,它展示了如何正确处理这个问题:Kivy:如何在 Popup 中获取类变量。
长话短说……稍长……我更新了我的超级方法以继承我的“text_1”字符串属性,以便我可以从 CustomPopup 对象中引用它!
这是更新的工作解决方案:
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()
千伏:
<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”,但标题仍然正确显示。
下面链接中描绘的最终产品是一个 Kivy 弹出窗口,其结构/格式在 kv 文件中定义,功能和可变文本在 Python 中定义。对我来说,它看起来比在 Python 端做这一切要干净得多。
我希望这对其他人有所帮助,就像许多其他帖子对我有所帮助一样。
推荐阅读
- apache-spark - IndexError:在pyspark shell上使用reduceByKey操作时列出索引超出范围
- typescript - 从 .d.ts 文件导出和导入 Typescript 类型别名
- jquery - Laravel 5.8 多张图片上传
- sql - 如何在 PowerShell 中运行多个 SQL 查询“加载本地 infile”?
- java - Android 如何让从 firebase 数据库加载数据与 orderByChild() & startAt() & limitToFirst() 结合使用?
- javascript - 当我刷新不同的路由路径时,Firebase 身份验证会重置
- javascript - 无法在 jQuery 函数中返回 $.posted php 文件数据
- jquery - 如何使用 Squelize 修复 RAW 查询
- arrays - autohotkey array null ...你如何检查数组是否为空/空?
- javascript - Javascript regex 查找除 html 标签内的文本之外的所有内容,并排除一些标签