Kivy小部件超出了预期的界限

时间:2016-04-18 16:24:05

标签: python python-3.x kivy

我正在为我的小部件进行自定义触摸处理。我设置它的方式是设置和修复窗口小部件的初始大小,但是,稍后,我会根据内容动态更改它。我暂时关闭了该功能以缩短代码,它不会影响问题。当我点击小部件右侧的空白点并且触摸已经注册时,我注意到一些奇怪的东西,所以我添加了一个画布背景来检查。显然,实际的窗口小部件边界设置比实际的窗口小部件实例大得多,我真的不知道是什么导致了这个。这些小部件位于FloatLayout,但我从未设置size_hints,只有大小。可能是这样吗?如何将窗口小部件边界缩短到它们应该是什么?

以下是整个源代码,问题很可能出现在kv定义中:

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen, ScreenManager, NoTransition
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.uix.scrollview import ScrollView
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.textinput import TextInput

global pr_msg_y
pr_msg_y = 5

Builder.load_string('''            
<ScrollView>:
    canvas:
        Color:
            rgba: 1, 1, 1, 1
        Rectangle:
            pos: self.pos
            size: self.size

<Message>:
    width: 500
    canvas:
        Color:
            rgba: 1, 0, 0, 0.3
        Rectangle:
            pos: self.pos
            size: self.size

    BoxLayout:
        pos: root.pos
        height: self.height
        canvas:
            Color:
                rgba: 0.6, 0.6, 0.6, 1
            Rectangle:
                pos: root.pos
                size: self.size

        TextInput:
            pos: root.pos
            size: root.size
            id: msg
            background_color: 0, 0, 0, 0
            text: str(msg)
''')

class Message(Widget):
    def __init__(self, **kwargs):
        super(Message, self).__init__(**kwargs)

    def on_touch_down(self, touch):
        if self.collide_point(*touch.pos):
            print("Touch within {}".format(self))

class Chat(Screen):
    pass

class MessageInput(TextInput):
    def __init__(self, **kwargs):
        super(MessageInput, self).__init__(**kwargs)

class ChatApp(App):
    def build(self):
        def msg_in(btn):
            global pr_msg_y
            inst = Message()
            inst.ids['msg'].text = "test" * 15
            inst.width = 456 # something random, the sizing should be dynamic
            inst.height = 40         
            for i in inst.walk():
                i.height = inst.height
                i.width = inst.width

            inst.y = sv1_main.height - 5 - pr_msg_y - inst.height
            msg_float.add_widget(inst)
            pr_msg_y += inst.height + 5

        Screens = ScreenManager(transition = NoTransition())
        chat = Chat(name = "main")        
        sv1_main = ScrollView(pos_hint = {"top":0.87, "center_x":0.5},
                              size_hint = (0.97, 0.65))
        msg_float = FloatLayout()

        bt1_main = Button(pos_hint = {"top":0.097, "center_x":0.951},
                          on_press = msg_in)

        Screens.add_widget(chat)
        chat.add_widget(sv1_main)
        sv1_main.add_widget(msg_float)
        chat.add_widget(bt1_main)

        return Screens

ChatApp().run()

1 个答案:

答案 0 :(得分:0)

size_hint会“覆盖”size。默认情况下,size_hint设置为1,1,因此,如果您只设置大小并将窗口小部件放入识别size_hints的布局中,则窗口小部件将获得最大可用大小。

size_hint = None, None设置为修复。