【问题标题】:How to position kivy widgets in floatlayout using pos_hint?如何使用 pos_hint 在 floatlayout 中定位 kivy 小部件?
【发布时间】:2020-07-21 11:09:25
【问题描述】:

我一直在尝试使用 pos_hint 在 FloatLayout 中定位 kivy 中的小部件。 如果标签从一开始就存在,例如如果我可以在 .kv 文件中定义 pos_hint,一切都会按预期工作。但是,我稍后会尝试创建按钮。使用这个 .kv 文件(名为 layouttest.kv):

<NewButton@Button>:
    size_hint: (0.1, 0.1)

<BasicFloatLayout@FloatLayout>:
    Button:
        size_hint: (0.4, 0.2)
        pos_hint: {'x': 0.0, 'top': 1.0}
        text: 'create Button'
        on_release: self.parent.create_Button()

和这个 python 代码,我试图将新创建的空白按钮放置在我的 BasicFloatLayout 大小的 0%-100% 范围内的随机 y 位置,以及 0-200px 范围内的随机 x 位置。 如果我按下按钮一次,一切都会按预期运行。在第二次按下时,第一个创建的按钮将更改其 y 位置,使其与新创建的按钮相同。第三次按下时,两个旧按钮都将与新创建的按钮对齐,依此类推。然而,x 定位将保持如预期的那样。有人可以解释一下我在这里做错了什么吗? (如果您可以帮助我使用更新功能和 pos_hint 移动按钮,则可以加分)

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.button import Button
from kivy.properties import NumericProperty 
from kivy.clock import Clock

import random

class BasicFloatLayout(FloatLayout):
    timer = NumericProperty(0)
    def update(self, *args):
        self.timer += 1
        for child in self.children:
            try: child.update()
            except AttributeError:
                pass
    def create_Button(self):
        button = NewButton( (random.random(), random.random()) )
        self.add_widget(button)
        
class NewButton(Button):
    def __init__(self, pos, **kwargs):
        super(NewButton, self).__init__(**kwargs)
        self.pos[0] = 200*pos[0]
        self.pos_hint['y'] = pos[1]

class layouttestApp(App):
    def build(self):
        GUI = BasicFloatLayout()
        Clock.schedule_interval(GUI.update, 1/30.)
        return GUI

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

【问题讨论】:

    标签: python kivy


    【解决方案1】:

    首先,使pos_hint: {'x': 0.0, 'y': 0.5}(因为很难让两个不同的东西工作,如果你使用x,使用y而不是Top,如果你使用Top,那么使用Bottom insead of x)

    其次,不要在 kv 文件中提供on_release: self.parent.create_Button(),而是这样做:on_release: root.create_Button()

    第三,你只给y赋值了,你还应该给x赋值,NewButton类里面的行是self.pos_hint['y'] = pos[1]

    但是您可以通过这样做使其更简单:

    #from your first class......
    def create_Button(self):
            button = NewButton(self.pos_hint{'x' : random.random(), 'y' : random.random()}
            self.add_widget(button)
    
    class NewButton(Button):
        def __init__(self, *kwargs):
            pass
    

    希望这有某种意义,您可以对其进行更多修改。 (注:你主课的开头部分我还没写,我很懒;-p)

    【讨论】:

    • 不幸的是,这不起作用...首先,我同意,独立配置这两个东西会更容易,但这样做更能解决真正的问题,因为所有的按钮堆栈彼此重叠,看起来只有一个按钮在移动。事实上,它是堆叠的按钮数量越来越多。第二,我同意。但是,这只是外观上的差异。第三,这在某种程度上类似于第一个。您的代码示例无法编译。如果我调用 button = NewButton(pos_hint={'x': random.random(), 'y': random.random()}) 它确实有效,但会产生相同的错误。
    • @fruchti 然后尝试在添加 self.add_widget(button) 后使用 self.remove_widget(button) 删除第一个按钮,为此不要使用 kv lang,使用逻辑代码这里。如果可能的话,试着给出不同的名字。
    • 但我不想删除第一个按钮,我想创建十个或二十个...
    • @fruchti 如果它们仍然不起作用,那么 kivy 是不可能的,kivy.md 可能会起作用,我喜欢 kivy,但它也有一些缺点,我试图用 kivy 创建一个聊天应用程序,我需要将新消息作为标签放置,并且只需附加屏幕,以便用户可以滚动与此人聊天。但是这种“可滚动标签”类型的东西在 kivy 中不存在。您可以尝试使用不同的 gui 框架,或使用 kivy.md!
    • 我把所有东西都带到了 kivy.md 但那里是一样的......我担心我只是不明白如何正确启动按钮。我正在为类的所有实例设置 pos_hint,而不仅仅是为单个实例。除非我首先在 .kv 文件中创建它,否则在 .kv 中创建的文件将保持其预期的 pos_hint。无论如何,感谢您的 kivy.md 推荐
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多