如何在Kivy中创建由绘图形状、标签和按钮组成的“实体”,并具有相对大小和位置?

How to create an "entity" composed of drawing shapes, labels and buttons with relative sizing and positioning in Kivy?

提问人:PetitFroggie 提问时间:11/12/2023 更新时间:11/22/2023 访问量:39

问:

我是 Python 和 Kivy 的新手。我正在尝试创建温度控制器(称为 PID)的显示。PID 由以下部分组成:

  • 浅灰色矩形背景;
  • 浅灰色背景上部的黑色矩形显示;
  • 黑色显示屏上有两个标签,显示设定温度和当前温度;和
  • 在黑色显示屏下方的浅灰色背景中水平对齐的四个按钮。

我将需要使用并显示其中的四个 PID。有没有办法将其创建为一个“实体、组件或小部件”,可以根据需要调用和显示,并具有相对大小和位置,以便在窗口中自动调整?

我设法创建了它,但只有固定的大小和定位

下面是 PID 的屏幕截图

我尝试了很多东西,包括浮动和相对布局,但我无法创建 PID 控制器,以便组件(黑色显示、标签、按钮)相对于浅色背景,这样我就可以使用size_hint和pos_hint在窗口中显示 PID。部分问题似乎在于“矩形”不支持size_hint和pos_hint。

以下是目前的基本 Python 代码:

 from kivy.app import App
    from kivy.uix.boxlayout import BoxLayout
    from kivy.uix.button import Button
    from kivy.uix.widget import Widget

这是目前的 Mivy 代码:

class MainWidget(Widget):
        pass

    PID:

    <PID>:
        canvas:
            Color:
                rgba: 1, 1, 1, .3
            Rectangle:
                size: 200, 150
                pos: 300, 200
            Color:
                rgba: 0, 0, 0, 1
            Rectangle:
                size: 180, 80
                pos: 310, 260
                
        Widget:
            Button:
                size: "40dp", "40dp"
                pos: "310dp", "210dp"
                background_normal: "[email protected]"
            Button:
                size: "40dp", "40dp"
                pos: "357dp", "210dp"
                background_normal: "[email protected]"
            Button:
                size: "40dp", "40dp"
                pos: "403dp", "210dp"
                background_normal: "[email protected]"
            Button:
                size: "40dp", "40dp"
                pos: "450dp", "210dp"
                background_normal: "[email protected]"
            Label:
                color: 1, 0, 0, 1
                text: "107.38"
                size: "40dp", "40dp"
                pos: "430dp", "305dp"
            Label:
                color: 0, 1, 0, 1
                text: "70.04"
                size: "40dp", "40dp"
                pos: "430dp", "270dp"

提前感谢您的时间和帮助,非常感谢。

Python 布局 Kivy

评论


答:

0赞 mishaeel 11/22/2023 #1

既然似乎没有人会回答这个问题,我决定构建你所描述的练习。希望这对你有用。

我相信要工作,小部件必须是 or 的子项。您可能知道这一点,因为它非常基本,但只是意味着 Kivy 会将小部件的左侧放置在左侧布局宽度的 30%,而小部件的底部则从底部开始放置布局高度的 70%。同样,意味着 Kivy 将使小部件宽度大小为布局宽度的 20%,小部件高度为布局高度的 20%。pos_hintFloatLayoutRelativeLayoutpos_hint: {'x': .3, 'y': .7}size_hint: (.2, .2)

所以你必须在 python 代码中创建 you,然后在 kv 语言中在 parent 下添加 with 和 的子项。在 kv 语言中,您可以将画布 Rectangle 设置为 和 ,然后输入 和 之后(见下文)。然后,小部件的画布将从 和 获取它,并在窗口调整大小时自动更新。FloatLayoutFloatLayoutpos_hintssize_hintsposself.possizeself.sizepos_hintsize_hintpossizepos_hintsize_hint

Python 代码:

from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.button import Button
from kivy.uix.widget import Widget
from kivy.graphics import Color, Rectangle
from kivy.uix.image import Image

class PID(FloatLayout):
    pass

class PIDApp(App):
    def build(self):
        return PID()

if __name__ == "__main__":
    PIDApp().run()

KV语言代码:

#:kivy 2.2.0

<PID>
    Widget: # this is the grey background
        canvas:
            Color:
                rgba: (.5,.5,.5,1)
            Rectangle:
                pos: self.pos
                size: self.size
        pos_hint: {'x': .3, 'y': .3}
        size_hint: (.4, .4)

    Widget: # this is the black screen
        canvas:
            Color:
                rgba: (0,0,0,1)
            Rectangle:
                pos: self.pos
                size: self.size
        pos_hint: {'x': .32, 'y': .45}
        size_hint: (.36, .22)

    Label: # this is the top red label
        text: '107.38'
        color: (1,0,0,1)
        pos_hint: {'x': .55, 'y': .55}
        size_hint: (.1,.1)

    Label: # this is the bottom green label
        text: '70.04'
        color: (0,1,0,1)
        pos_hint: {'x': .55, 'y': .47}
        size_hint: (.1,.1)

    Button: # I only added the first image to the buttons, so you will need to add the others
        pos_hint: {'x': .33, 'y': .33}
        size_hint: (.07, .08)       
        Image:
            pos: self.parent.pos
            size: self.parent.size
            source: '[email protected]'
            fit_mode: 'fill' # this make the image fill the button area
    Button:
        pos_hint: {'x': .42, 'y': .33}
        size_hint: (.07, .08)       
    Button:
        pos_hint: {'x': .51, 'y': .33}
        size_hint: (.07, .08)       
    Button:
        pos_hint: {'x': .60, 'y': .33}
        size_hint: (.07, .08)