Kivy:如何使标签尺寸和画布尺寸相等?

时间:2020-04-10 19:05:05

标签: python python-3.x canvas kivy kivy-language

我使用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文件)编写上述问题的解决方案,那就更好了。如果您知道此问题的任何其他解决方案或任何其他小部件,请告诉我。像按钮小部件一样,我们可以指定背景色和文本,也可以添加将执行上述任务的任何小部件。您应该将矩形画布中的“源”替换为任何已知的图像文件。我希望你明白。如果您不这样做,请告诉我。 :)

1 个答案:

答案 0 :(得分:0)

Widgets设置为不更改sizepos是最简单的解决方案。基本上只使用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()

要使RectanglesLabels更改possize有点复杂。在下面的代码的修改版本中,我保留LabelsRectangles的列表,以及bind的{​​{1}}方法的列表,只要adjust_common_size()发生了变化。然后,该方法将sizeMyGrid中的sizepos调整为匹配:

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_sizekv匹配的更好方法。以下代码使用Rectangle,但定义了Label以包括其自己的GridLayout并在MyLabelRectangle中使其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都会创建自己的