2017-02-03 6 views
0

Я использую цикл для создания 27 экземпляров ярлыков. Эти метки должны быть пронумерованы с использованием метода Label.text. Этого я достиг.Kivy rectangle redraw, self.pos и self.size являются (0,0)

Мне также нужно иметь возможность перекрасить эти метки (прямоугольник canvas) с помощью функции python (на основе других входов). Это бит, который не работает

В основном, инициализации метод GridLayout создает 29 экземпляров custButton() Label. Этот цикл также переписывает (label.text) кнопки, но перекраска одна метка не работает.

я изолирован, что self.pos и self.size оба возвращаются (0,0) в функции xBackground_Color - именно поэтому новый прямоугольник не рисовать после того, как старый очищается (прозрачный работает).

Почему не работает self.pos и self.size со стороны python?

Я пробовал soooooooo много вещей! Пожалуйста, помоги, если можешь.

Вот kvMain.kv:

#:kivy 1.0.9 

FloatLayout: 
    canvas: 
     Color: 
      rgba: (64/255, 64/255, 64/255, 1) #Whole screen background 
     Rectangle: 
      pos: self.pos 
      size: self.size 
    BoxLayout: 
     orientation: 'vertical' 
     padding: 10 
     FloatLayout: #Dummy widget 
     myGrid: 


<myGrid>: 
    cols: 9 
    spacing: 3 
    padding: 3 
    canvas.before: 
     Color: 
      rgba: (216/255, 216/255, 216/255, 1) 
     Rectangle: 
      pos: self.pos 
      size: self.size 

<custButtom>: 
    canvas.before: 
     Color: 
      rgba: (191/255, 191/255, 191/255, 1) 
     Rectangle: 
      pos: self.pos 
      size: self.size 
    font_size: 14 
    color: (90/255, 90/255, 90/255, 1) 
    text: 'Er' #Don't ever want to see this text. Will set each label in loop 
    size: self.texture_size 

Вот main.py:

from kivy.app import App 
from kivy.lang import Builder 

from kivy.uix.gridlayout import GridLayout 
from kivy.uix.boxlayout import BoxLayout 
from kivy.uix.floatlayout import FloatLayout 
from kivy.uix.label import Label 

from kivy.graphics.vertex_instructions import Rectangle, Line 
from kivy.graphics.context_instructions import Color 

IN_Labels = {} 

class custButtom(Label): 
    def __init__(self, **kwargs): 
     super(custButtom, self).__init__(**kwargs) 

    def xtext(self, newText): 
     self.text = newText 
     self.size = self.texture_size 

    def xbackground_color(self, newR, newG, newB, newA): 
     print('IN_Labels[14] pos ('+ str(IN_Labels[14].pos[0]) + ',' + str(IN_Labels[14].pos[1]) + ') size ('+ str(IN_Labels[14].size[0]) + ',' + str(IN_Labels[14].size[1]) + ')') 
     print('self pos ('+ str(self.pos[0]) + ',' + str(self.pos[1]) + ') size ('+ str(self.size[0]) + ',' + str(self.size[1]) + ')') 
     self.canvas.before.clear() 

     with self.canvas.before: 
      Color(newR, newG, newB, newA) 
      #Problem is that self.size and self.pos are both (0,0) 
      Rectangle(size=self.size, pos=self.pos) 


class myGrid(GridLayout): 
    def __init__(self, **kwargs): 
     super(myGrid, self).__init__(**kwargs) 

     for i in range(0, 27, 1): 
      IN_Labels[i] = custButtom() 
      self.add_widget(IN_Labels[i]) 
      #CAN change text, needs more work to get it right 
      IN_Labels[i].xtext(str(i)) 

     # I need to be able to change backgroundcolor programatically 
     IN_Labels[14].xbackground_color(1,0,0,1) 

class MainApp(App): 
    def build(self): 
     return kvMain 

kvMain = Builder.load_file("kvMain.kv") 

if __name__ == '__main__': 
    MainApp().run() 

ответ

1

Нашел! Я думаю, проблема заключается в том, что на этикетке действительно нет размера и pos в то время, когда его просят self.size и self.pos.

Привязка функции для изменения размера и изменения положения решает проблему.

Спасибо Александру Тейлором за его отличные видео на YouTube и его блог, где я нашел ответ: https://blog.kivy.org/2014/10/updating-canvas-instructions-declared-in-python/

kvMain.kv становится:

#:kivy 1.0.9 

FloatLayout: 
    canvas: 
     Color: 
      rgba: (64/255, 64/255, 64/255, 1) #Whole screen background 
     Rectangle: 
      pos: self.pos 
      size: self.size 
    BoxLayout: 
     orientation: 'vertical' 
     padding: 10 
     FloatLayout: #Dummy widget 
     myGrid: 


<myGrid>: 
    cols: 9 
    spacing: 3 
    padding: 3 
    canvas.before: 
     Color: 
      rgba: (216/255, 216/255, 216/255, 1) 
     Rectangle: 
      pos: self.pos 
      size: self.size 

<custButtom>: 
    #CANVAS INSTRUCTION MOVED TO PYTHON INIT 
    font_size: 14 
    color: (90/255, 90/255, 90/255, 1) 
    text: 'Er' #Don't ever want to see this text. Will set each label in loop 
    size: self.texture_size 

main.py становится:

from kivy.app import App 
from kivy.lang import Builder 

from kivy.uix.gridlayout import GridLayout 
from kivy.uix.boxlayout import BoxLayout 
from kivy.uix.floatlayout import FloatLayout 
from kivy.uix.label import Label 

from kivy.graphics.vertex_instructions import Rectangle, Line 
from kivy.graphics.context_instructions import Color 

IN_Labels = {} 

class custButtom(Label): 
    def __init__(self, **kwargs): 
     super(custButtom, self).__init__(**kwargs) 

     with self.canvas.before: 
      Color(191/255, 191/255, 191/255, 1) 
      self.rect = Rectangle(pos=self.pos, size=self.size) 

     #Ensure that everytime the Rectangle is updated, it's repositioned correctly 
     self.bind(pos=self.update_rect, size=self.update_rect) 

    def update_rect(self, *args): 
     self.rect.pos = self.pos 
     self.rect.size = self.size 

    def xtext(self, newText): 
     self.text = newText 
     self.size = self.texture_size 

    def xbackground_color(self, newR, newG, newB, newA): 
     print('IN_Labels[14] pos ('+ str(IN_Labels[14].pos[0]) + ',' + str(IN_Labels[14].pos[1]) + ') size ('+ str(IN_Labels[14].size[0]) + ',' + str(IN_Labels[14].size[1]) + ')') 
     print('self pos ('+ str(self.pos[0]) + ',' + str(self.pos[1]) + ') size ('+ str(self.size[0]) + ',' + str(self.size[1]) + ')') 
     self.canvas.before.clear() 

     with self.canvas.before: 
      Color(newR, newG, newB, newA) 
      self.rect = Rectangle(size=self.size, pos=self.pos) 


class myGrid(GridLayout): 
    def __init__(self, **kwargs): 
     super(myGrid, self).__init__(**kwargs) 

     for i in range(0, 27, 1): 
      IN_Labels[i] = custButtom() 
      self.add_widget(IN_Labels[i]) 
      #CAN change text, needs more work to get it right 
      IN_Labels[i].xtext(str(i)) 

     # I need to be able to change backgroundcolor programatically 
     IN_Labels[14].xbackground_color(1,0,0,1) 

class MainApp(App): 
    def build(self): 
     return kvMain 

kvMain = Builder.load_file("kvMain.kv") 

if __name__ == '__main__': 
    MainApp().run() 

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

  • Нет связанных вопросов^_^