2016-04-18 2 views
0

Я делаю пользовательскую обработку касания для своего виджета. Способ, которым я настроен, заключается в том, что начальный размер виджета установлен и исправлен, однако позже я меняю его динамически в зависимости от содержимого. Я сейчас отключил эту функцию, чтобы сократить код, это не влияет на проблему. Я заметил что-то странное, когда я щелкнул по пустому пятну справа от виджета, и касание было зарегистрировано, поэтому я добавил фон холста для проверки. Видимо, фактические границы виджета установлены намного больше, чем фактический экземпляр виджета, и я действительно не знаю, что вызывает это. Эти виджеты расположены в FloatLayout, но я никогда не устанавливал size_hints, только размеры. Может ли так быть? Как сократить границы виджета до того, какими они должны быть?Виджет Kivy из ожидаемых границ

Вот весь исходный код, то проблема, скорее всего, в определении 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

Всегда используйте 'size_hint = [None, None]', если вы не уверены. И да, это вызвано тем, что вы не писали его там (например, в разделе «Сообщение») – KeyWeeUsr

ответ

0

size_hint означает "перезапись" size. По умолчанию size_hint установлен в 1,1, поэтому, если вы задаете только размер и вы помещаете виджет в макет, который распознает size_hints, виджет получит максимальный доступный размер.

Установить size_hint = None, None исправить.

Смежные вопросы