python - kivy 中的属性绑定和样式问题
问题描述
目标
我有一个带有属性的小部件类c_description
。我需要能够创建标签(或其他类型的小部件)并将其添加到这个c_description
作为文本继承的小部件。并将更改c_description
传播到标签的文本。我需要能够使用函数运行此标签的创建/添加。
我基本上需要完全按照其他问题的要求去做。
我做了什么以及遇到了什么问题我
格式化了这个标签类StretchingLabel
拉伸以适应它的内容。我在 kivy中有一个脚本,显示了我希望它如何工作。最终结果应该是这样的。
这是另一个脚本,在将其text
属性绑定到c_description
.
如果我运行它,我会得到如下所示的结果。
标签的文本是 "" 而不是 的内容c_description
,所以这是一个问题。但是,如果我删除属性绑定语句并更改c_label = StretchingLabel()
为,c_label = StretchingLabel(pos=self.pos, width=self.width, text=self.c_description)
我们至少应该能够看到成功的属性绑定是什么样的。
当我这样做时,结果看起来像这样。
这不是我想要的。我希望它看起来像第一张照片。
我的代码
from kivy.app import App
from kivy.lang import Builder
from kivy.clock import Clock
from kivy.uix.widget import Widget
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import StringProperty
from kivy.uix.textinput import TextInput
Builder.load_string('''
<StretchingLabel>:
size_hint_y: None
text_size: self.width, None
height: self.texture_size[1]
group: 'test'
canvas.before:
Color:
rgba: .7, .7, .7, 1
Rectangle:
pos: self.pos
size: self.size
<MyLabelFrame>:
id: xLabel
<ContainerBox>:
orientation: 'horizontal'
Button:
text: 'h1'
group: 'test'
BoxLayout:
orientation: 'vertical'
size: root.size
pos: root.pos
Label:
text: 'Description'
size_hint_y: None
height: 30
bold: True
MyLabelFrame:
Label:
''')
class StretchingLabel(Label):
def __init__(self, **kwargs):
super(StretchingLabel, self).__init__(**kwargs)
#This is for debugging
Clock.schedule_once(lambda dt: print("StretchingLabel.init(): ", self.text), timeout=0.01)
def on_double_click(self, instance, p_ignoreme):
#This is also for debugging
print("StretchingLabel.on_double_click():", self.text)
class MyLabelFrame(Widget):
c_description = StringProperty(
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. \n\nProin vitae turpis ornare urna elementum pharetra non et tortor. Curabitur semper mattis viverra. \nPellentesque et lobortis purus, eu ultricies est. Nulla varius ac dolor quis mattis. Pellentesque vel accumsan tellus. Donec a nunc urna. Nulla convallis dignissim leo, tempor sagittis orci sollicitudin aliquet. Duis efficitur ex vel auctor ultricies. Etiam feugiat hendrerit mauris suscipit gravida. Quisque lobortis vitae ligula eget tristique. Nullam a nulla id enim finibus elementum eu sit amet elit.')
def __init__(self, **kwargs):
super(MyLabelFrame, self).__init__(**kwargs)
Clock.schedule_once(lambda dt: self.makeLabel(), timeout=0.01)
def makeLabel(self):
c_label = StretchingLabel()
#HERE! This vvv does not seem to work for some reason.
self.bind(pos=c_label.setter('pos'), width=c_label.setter('width'), c_description=c_label.setter('text'))
#This vvv didn't work either.
#c_label.bind(pos=self.setter('pos'), width=self.setter('width'), text=self.setter('c_description'))
self.add_widget(c_label)
class ContainerBox(BoxLayout):
def __init__(self, **kwargs):
super(ContainerBox, self).__init__(**kwargs)
class Nested2App(App):
def build(self):
return ContainerBox()
if __name__ == '__main__':
Nested2App().run()
我对你的问题
- 为什么不
self.bind(c_description=c_label.setter('text'))
工作?正在创建标签,但它没有从c_description
. 我究竟做错了什么? - 为什么创建的标签格式错误?我在 kv 代码中传递了与
makeLabel()
. 而且我需要能够使用该makeLabel()
功能正确执行此操作。
笔记
我在这里看到了另一个问题,它与我遇到的问题完全相同(没有格式问题),但由于某种原因,答案对我不起作用。
解决方案
问题 1
为什么 self.bind(c_description=c_label.setter('text')) 不起作用?正在创建标签,但它没有从 c_description 获取文本。我究竟做错了什么?
回答
你有正确的代码,
self.bind(pos=c_label.setter('pos'), width=c_label.setter('width'), c_description=c_label.setter('text'))
绑定过程不会立即更新text
. text
只有在改变时才会改变c_description
。
例子
以下示例说明了以下内容:
- 最初显示一个空标签
- 在更改后显示
c_descripton
,但在小部件的默认值pos=[0,0]
和width=100
- 最大化窗口并
c_description
显示在正确的位置,因为pos
和width
已更改。
注意:-kv 文件
添加color: 0, 0, 0, 1 # black colour text
到类规则中,<StretchingLabel>:
因为文本不可见。这是因为背景颜色是白色,而 Label 文本的默认颜色也是白色。
主文件
from kivy.app import App
from kivy.lang import Builder
from kivy.clock import Clock
from kivy.uix.widget import Widget
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import StringProperty
Builder.load_string('''
<StretchingLabel>:
color: 0, 0, 0, 1 # black color text
size_hint_y: None
text_size: self.width, None
height: self.texture_size[1]
group: 'test'
canvas.before:
Color:
rgba: .7, .7, .7, 1
Rectangle:
pos: self.pos
size: self.size
<MyLabelFrame>:
id: xLabel
<ContainerBox>:
orientation: 'horizontal'
Button:
text: 'h1'
group: 'test'
BoxLayout:
orientation: 'vertical'
size: root.size
pos: root.pos
Label:
text: 'Description'
size_hint_y: None
height: 30
bold: True
MyLabelFrame:
Label:
''')
class StretchingLabel(Label):
def __init__(self, **kwargs):
super(StretchingLabel, self).__init__(**kwargs)
# This is for debugging
Clock.schedule_once(lambda dt: print("StretchingLabel.init(): ", self.text), timeout=0.01)
def on_double_click(self, instance, p_ignoreme):
# This is also for debugging
print("StretchingLabel.on_double_click():", self.text)
class MyLabelFrame(Widget):
c_description = StringProperty(
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. \n\nProin vitae turpis ornare urna elementum pharetra non et tortor. Curabitur semper mattis viverra. \nPellentesque et lobortis purus, eu ultricies est. Nulla varius ac dolor quis mattis. Pellentesque vel accumsan tellus. Donec a nunc urna. Nulla convallis dignissim leo, tempor sagittis orci sollicitudin aliquet. Duis efficitur ex vel auctor ultricies. Etiam feugiat hendrerit mauris suscipit gravida. Quisque lobortis vitae ligula eget tristique. Nullam a nulla id enim finibus elementum eu sit amet elit.')
def __init__(self, **kwargs):
super(MyLabelFrame, self).__init__(**kwargs)
Clock.schedule_once(lambda dt: self.makeLabel(), timeout=0.8)
def makeLabel(self):
c_label = StretchingLabel()
self.bind(pos=c_label.setter('pos'), width=c_label.setter('width'), c_description=c_label.setter('text'))
self.add_widget(c_label)
Clock.schedule_once(lambda dt: self.chg_text(), 1)
def chg_text(self):
self.c_description = 'Updated: ...' + self.c_description
class ContainerBox(BoxLayout):
def __init__(self, **kwargs):
super(ContainerBox, self).__init__(**kwargs)
class Nested2App(App):
def build(self):
return ContainerBox()
if __name__ == '__main__':
Nested2App().run()
输出
问题2
为什么创建的标签格式错误?我在 kv 代码中传递了与 makeLabel() 中相同的属性。而且我需要能够使用 makeLabel() 函数正确执行此操作。
根本原因
问题是由于 Kivy 的造型未完成。
解决方案
将该timeout
值增加到至少 0.8 秒。该值会有所不同,即取决于您的计算机速度。
片段
def __init__(self, **kwargs):
super(MyLabelFrame, self).__init__(**kwargs)
Clock.schedule_once(lambda dt: self.makeLabel(), timeout=0.8)
def makeLabel(self):
c_label = StretchingLabel(pos=self.pos, width=self.width, text=self.c_description)
self.add_widget(c_label)
输出
推荐阅读
- python - 从熊猫数据框中的列表中删除字符串
- react-native - React Native Animated - TypeError:尝试分配给只读属性
- css - CSS 轮廓颜色属性在 firefox 中不起作用吗?例如:输入:焦点{大纲颜色:#9aadee; }
- angular - Okta+Springboot+angular 的 401 未授权错误
- html - 无法在汉堡之间留出空间 - Tailwind CSS
- python - 将 python 字典中的值推送到第二个字典的相应键值
- mysql - 如何使用Typeorm mysql leftJoinAndSelect?
- javascript - 如何从数组中仅减去选定的值
- c# - 当我在同一解决方案中卸载项目时,Visual Studio 中的引用路径不起作用
- oracle - OCIEnvCreate 失败并返回代码 1,但错误消息文本不可用 - 仍未解决?