Kivy:GridLayout 中的按钮有间隙
Posted
技术标签:
【中文标题】Kivy:GridLayout 中的按钮有间隙【英文标题】:Kivy: Buttons in GridLayout have gap 【发布时间】:2019-12-14 10:25:21 【问题描述】:在 GridLayout 内部,奇数 Button 子级不会出现。
我已经尝试了 Button 和 GridLayout 大小、size_hint、高度等的几种配置,但似乎无法解决这个问题。从子项中删除 Button 类可以解决此问题,但我想要按钮小部件的功能。
main.py:
from kivy.app import App
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.gridlayout import GridLayout
from kivy.properties import NumericProperty, StringProperty, ListProperty
from kivy.uix.behaviors.focus import FocusBehavior
from kivy.uix.button import Button
class Tube(Button, RelativeLayout, FocusBehavior):
pass
class TubeMapView(GridLayout, FocusBehavior):
orderNumber = NumericProperty()
customerName = StringProperty("")
tubeList = ListProperty([])
bundleList = ListProperty([])
def add_tube(self):
self.tubeList.append(Tube())
self.add_widget(self.tubeList[-1])
def _on_focusable(self, instance, value):
self.add_tube()
def keyboard_on_key_down(self, window, keycode, text, modifiers):
print(keycode)
if keycode[1] is 'enter':
self.add_tube()
class LengthView(GridLayout):
pass
class AppView(GridLayout):
pass
class TubeMapApp(App):
pass
if __name__ == '__main__':
TubeMapApp().run()
tubemap.kv:
<Tube>:
size_hint_y: None
height: dp(60)
canvas.before:
Color:
rgba: (0,1,0,1)
Rectangle:
size: self.size
<LengthView>:
size_hint_x: 1
size_hint_y: 1
canvas.before:
Color:
rgba: (0,0,1,1)
Rectangle:
size: self.size
<TubeMapView>:
cols: 1
rows: None
size_hint_max_x:
size_hint_y: None
height: self.minimum_height
canvas.before:
Color:
rgba: (0,1,0,1)
Rectangle:
pos: self.pos
size: self.size
AppView:
cols: 2
rows: None
RelativeLayout:
size_hint_x: 0.75
ScrollView:
size: self.size
TubeMapView:
focus: True
Tube:
Tube:
Tube:
RelativeLayout:
size_hint_x: 0.25
ScrollView:
LengthView:
我希望每个 Button 都会渲染,但只有其他 Button 才会渲染,从第一个开始:
【问题讨论】:
你真的需要你的Tube
类来扩展RelativeLayout
吗?
不,但是随着我将更多标签和其他元素附加到 Tube 类,RelativeLayout 将更容易管理,并且将来会减少混乱。关于为什么 RelativeLayout 产生这种行为的任何想法?
【参考方案1】:
您可以继承 Button、RelativeLayout 和 FocusBehavior,并创建自己的样式。
片段 - py 文件
class Tube(Button, RelativeLayout, FocusBehavior):
pass
片段 - kv fie
<-Tube>:
text: ''
focus: False
size_hint_y: None
height: dp(60)
canvas.before:
Color:
rgba: (0,1,0,1)
# rgba: (1,0,1,0.5) if self.focus else (0,1,0,1)
Rectangle:
size: self.size
state_image: self.background_normal if self.state == 'normal' else self.background_down
disabled_image: self.background_disabled_normal if self.state == 'normal' else self.background_disabled_down
canvas:
Color:
rgba: (1,0,1,1) if self.focus else self.background_color
BorderImage:
border: self.border
pos: self.pos
size: self.size
source: self.disabled_image if self.disabled else self.state_image
Color:
rgba: 1, 1, 1, 1
Rectangle:
texture: self.texture
size: self.texture_size
pos: int(self.center_x - self.texture_size[0] / 2.), int(self.center_y - self.texture_size[1] / 2.)
输出
示例
下面的kv文件是一个模型。
poc.kv
<-Tube>:
text: ''
focus: False
size_hint_y: None
height: dp(60)
canvas.before:
Color:
rgba: (0,1,0,1)
Rectangle:
size: self.size
state_image: self.background_normal if self.state == 'normal' else self.background_down
disabled_image: self.background_disabled_normal if self.state == 'normal' else self.background_disabled_down
canvas:
Color:
rgba: (1,0,1,1) if self.focus else self.background_color
BorderImage:
border: self.border
pos: self.pos
size: self.size
source: self.disabled_image if self.disabled else self.state_image
Color:
rgba: 1, 1, 1, 1
Rectangle:
texture: self.texture
size: self.texture_size
pos: int(self.center_x - self.texture_size[0] / 2.), int(self.center_y - self.texture_size[1] / 2.)
<LengthView>:
size_hint_x: 1
size_hint_y: 1
canvas.before:
Color:
rgba: (0,0,1,1)
Rectangle:
size: self.size
<TubeMapView>:
cols: 1
rows: None
size_hint_y: None
height: self.minimum_height
canvas.before:
Color:
rgba: (0,1,0,1)
Rectangle:
pos: self.pos
size: self.size
AppView:
cols: 2
rows: None
RelativeLayout:
size_hint_x: 0.75
ScrollView:
size: self.size
TubeMapView:
Tube:
focus: True
text: 'tube 1'
Tube:
text: 'tube 2'
Tube:
text: 'tube 3'
RelativeLayout:
size_hint_x: 0.25
ScrollView:
LengthView:
【讨论】:
这个例子正确地解决了这个问题。但是,我仍然不明白为什么会发生这种行为,这在 Kivy 中经常发生。对此有什么想法吗?【参考方案2】:如果您希望您的 Tube
成为行为类似于 Button
的 RelativeLayout
,请将您的 Tube
类的声明更改为:
class Tube(ButtonBehavior, FocusBehavior, RelativeLayout):
pass
请注意,documentation 表示 Behavior 类在继承中必须位于 Widget
类之前。
此更改符合我的想法。
【讨论】:
以上是关于Kivy:GridLayout 中的按钮有间隙的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Kivy Python 中为 GridLayout 的某些按钮设置高度?
MDRectangleFlatButton(s) 不采用它们在 GridLayout 或 MDGridLayout 中应该具有的大小。 Kivy 的按钮工作正常