我使用Gridlayout制作了一个正方形的标签网格。现在我想为标签添加背景色(每个标签都有不同的矩形)。我尝试通过以下代码来做到这一点。
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.gridlayout import GridLayout
from kivy.graphics import Rectangle, Color
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.label import Label
class MyGrid(FloatLayout):
def __init__(self,**kwargs):
super(MyGrid,self).__init__(**kwargs)
self.grid=GridLayout()
self.grid_size=4
self.grid.cols=self.grid_size
for k in range(self.grid_size):
for i in range(self.grid_size):
with self.grid.canvas:
Rectangle(size=(100,100),pos=(k*160+100,i*160+100),source="52852.JPG")
for h in range(self.grid_size):
for j in range(self.grid_size):
self.grid.add_widget(Label(text="labwl"+str(h)+str(j),size=(100,100),pos=(h*160+100,j*160+100)))
self.add_widget(self.grid)
class GameApp(App):
def build(self):
return MyGrid()
if __name__ == '__main__':
GameApp().run()
在此代码中,如果我未指定“ self.grid.cols”,则会在python控制台中生成警告,并且当窗口变为全屏模式时,画布上的矩形仍保留原始大小和位置,但标签会保留不要。我想将标签放置在画布的矩形前面,并且它们还应保留指定的屏幕尺寸。此外,如果我将“ self.grid.size”更改为任何其他数字,它也应使该长度的标签网格和相应的画布数量相同。我也为此目的尝试了浮动布局,但这没有帮助。无论窗口大小如何,画布矩形和标签都应适合窗口。如果能以python文件(而不是.kv文件)编写上述问题的解决方案,那就更好了。如果您知道此问题的任何其他解决方案或任何其他小部件,请告诉我。像按钮小部件一样,我们可以指定背景色和文本,也可以添加将执行上述任务的任何小部件。您应该将矩形画布中的“源”替换为任何已知的图像文件。我希望你明白。如果您不这样做,请告诉我。 :)
答案 0 :(得分:0)
将Widgets
设置为不更改size
或pos
是最简单的解决方案。基本上只使用size_hint=(None, None)
而不使用GridLayout
:
from kivy.app import App
from kivy.graphics import Rectangle
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.label import Label
class MyGrid(FloatLayout):
def __init__(self,**kwargs):
super(MyGrid,self).__init__(**kwargs)
self.grid_size=4
for k in range(self.grid_size):
for i in range(self.grid_size):
with self.canvas:
Rectangle(size=(100,100),pos=(k*160+100,i*160+100),source="52852.JPG")
for h in range(self.grid_size):
for j in range(self.grid_size):
self.add_widget(Label(text="labwl"+str(h)+str(j),size=(100,100),pos=(h*160+100,j*160+100), size_hint=(None, None)))
class GameApp(App):
def build(self):
return MyGrid()
if __name__ == '__main__':
GameApp().run()
要使Rectangles
和Labels
更改pos
和size
有点复杂。在下面的代码的修改版本中,我保留Labels
和Rectangles
的列表,以及bind
的{{1}}方法的列表,只要adjust_common_size()
发生了变化。然后,该方法将size
和MyGrid
中的size
和pos
调整为匹配:
Labels
没有必要为Rectangles
使用from kivy.app import App
from kivy.properties import ListProperty
from kivy.graphics import Rectangle
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.label import Label
class MyGrid(FloatLayout):
common_size = ListProperty((100, 100))
def __init__(self,**kwargs):
super(MyGrid,self).__init__(**kwargs)
self.grid_size=4
self.rects = []
self.labels = []
for k in range(self.grid_size):
one_row = []
self.rects.append(one_row)
for i in range(self.grid_size):
with self.canvas:
one_row.append(Rectangle(size=self.common_size,pos=(k*160+100,i*160+100),source="52852.JPG"))
for h in range(self.grid_size):
one_row = []
self.labels.append(one_row)
for j in range(self.grid_size):
label = Label(text="labwl"+str(h)+str(j),size=self.common_size,pos=(h*160+100,j*160+100), size_hint=(None, None))
one_row.append(label)
self.add_widget(label)
self.bind(size=self.adjust_common_size)
def adjust_common_size(self, instance, new_size):
self.common_size = (new_size[0] * 0.9 / self.grid_size, new_size[1] * 0.9 / self.grid_size)
for k in range(self.grid_size):
for i in range(self.grid_size):
adjusted_pos = (k * new_size[0] / self.grid_size, i * new_size[1] / self.grid_size)
rect = self.rects[k][i]
label = self.labels[k][i]
label.size = self.common_size
label.pos = adjusted_pos
rect.size = self.common_size
rect.pos = adjusted_pos
class GameApp(App):
def build(self):
return MyGrid()
if __name__ == '__main__':
GameApp().run()
,但是如果您决定使用ListProperty
,这将很方便。
这是一个有趣的问题。这是使common_size
和kv
匹配的更好方法。以下代码使用Rectangle
,但定义了Label
以包括其自己的GridLayout
并在MyLabel
和Rectangle
中使其Rectangle
保持匹配:
pos
采用这种方法,您不必在size
中创建from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.graphics import Rectangle
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.label import Label
class MyLabel(Label):
def __init__(self, **kwargs):
super(MyLabel, self).__init__(**kwargs)
with self.canvas.before:
self.rect = Rectangle(size=self.size,pos=self.pos,source="52852.JPG")
self.bind(size=self.adjust_size)
self.bind(pos=self.adjust_pos)
def adjust_pos(self, instance, new_pos):
self.rect.pos = new_pos
def adjust_size(self, instance, new_size):
self.rect.size = new_size
class MyGrid(FloatLayout):
def __init__(self,**kwargs):
super(MyGrid,self).__init__(**kwargs)
self.grid=GridLayout()
self.grid_size=4
self.grid.cols=self.grid_size
for h in range(self.grid_size):
for j in range(self.grid_size):
self.grid.add_widget(MyLabel(text="labwl"+str(h)+str(j),size=(100,100),pos=(h*160+100,j*160+100)))
self.add_widget(self.grid)
class GameApp(App):
def build(self):
return MyGrid()
if __name__ == '__main__':
GameApp().run()
,因为每个Rectangles
都会创建自己的