kivy - canvas , i problemy z zmiennymi

0

Hejka ,

w tytule mam canvas , bo sam probowalem obejsc inny problem a natknolem sie na nowy , czyli zadam pytanie o dwa 😀

  1. canvas

mam clase :

class Rama1(Widget):
    def __init__(self,x,y,szer,wys):
        self.x=x
        self.y=y
        self.szer=szer
        self.wys=wys
        super().__init__()
        with self.canvas:
            Color(1,0,0)
            Line(rectangle=(self.x,self.y,self.width,self.height))

nie mam zadnego wywolania w pliku kv, tylko z pythona

self.add_widget(F.Rama1(100,100,100,500))

no i rysuje mi czerwony kwadracik , o stalych wymiarach , a jak moglbym odniesc sie do wielkosci okna rodzica, tak zeby kwadrat zmienial sie gdy rozciagne okno, bo wywolanie jest w screen

class MieszkanieWindow(Screen):
      ...
      def on_enter(self, *args):
        ...
        self.add_widget(F.Rama1(100,100,100,500))
  1. error

    sam probowalem sie troche bawic i mam pewien error, tu bedzie mi ciezej wytlumaczyc , ale sprubuje

    w pyhonie:

    class RamaOpis(Label):
    pass

    w kv mam (jakos formatu tekstu na kod nie moge zmienic t tym moim zapytaniu)

    <RamaOpis>:
    wys: 1
    szer: 1
    kF: 0,1,0,1
    kB: 1,0,0,0.5
    tS:20

       color: root.kF
       font_size: root.tS
    
       wysY:root.height+((root.wys-0.5)*root.height)
       dolY:root.y-(root.wys*root.height)
       szerX:root.szer*root.width
    
       canvas.before:        
           Color:
               rgba: root.kF
           Line:    # --- adds a border --- #
               width: 1
               rectangle: root.x-1, root.dolY, root.szerX, root.wysY
           Color:
               rgba: root.kB
           Rectangle:    
               size: self.size
               pos: self.pos
    

    rysuje ramke, w gornym lewym rogu wstawia text ( taka funkcja ktora mi sie juz nie podoba no ale od tego zaczolem , ale problemy chcialbym rozwiazac)

    self.add_widget(F.RamaOpis(pos_hint={'x':0.35,'y':0.74},text='Mieszkanie',size_hint=[0.1,0.198],kB =BlB,tS=20,wys=3,szer=3))

    no i zauwazylem ze w niektorych screenach to mi dziala a w innych nie.

    pisze ze:

    TypeError: Properties ['kB', 'tS1'szer', 'wys''] passed to init may not be existing property names. Valid properties are......

    problem rozwiazuje w ten sposob ze w kv :

      ### inicjalizacja ramki ????
     RamaOpis:
         text: "TTTTTTTTT"
         pos_hint: {"x": 1.1 , "y":1}
         size_hint: 0.1, 0.1
    

    wywoluje te ramke, gdzies poza ekranem, no i bledu nie ma

    No ale dlaczego on jest?

0

Ad 1. Skoro rysujesz na canvasie podczas wywołania __init__ to dość naturalne, że będzie rysowany tylko raz, bo klasa tworzy się tylko raz. Jeżeli chcesz, aby canvas się zmieniał w momencie jak zmienisz rozmiar okna, to musisz obserwować zdarzenie jakim jest zmiana rozmiaru (co najprościej robić obserwując property size, przy pomocy bind lub zdefiniowania w klasie metody on_size), wyczyścić canvas i przerysować na nowo. W praktyce:

from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.widget import Widget
from kivy.graphics import Color, Rectangle


class MyWidget(Widget):
    def on_size(self, instance, value):
        with self.canvas:
            self.canvas.clear()
            Color(1., 0, 0)
            Rectangle(size=(self.size[0]/2, self.size[1]/2), pos=(0, 0))


class MyApp(App):
    def build(self):
        return MyWidget()


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

Ad 2. Aby można było wstrzyknąć w __init__ argumenty musisz jawnie zadeklarować swoje atrybuty jako własności, w rodzaju:

class Rama1(Widget):
    kb = VariableListProperty(length=4)
    tS = NumericProperty()
    # ...
0
  1. AI podpowiedzialo mi cos podobnego, ale ja troche chialelem miec przykombinowany widget, powiedzmy ze dziala, czyli sie skaluje przy zmianie rozmiaru okna.
    ale poniewaz podaje wspozedne prz pomocy pos no to okno sie zmienia ale dolny rog jest przyklejony. Nic to na razie to mi pasuje

  2. o to pomoglo, czyli musze trzymac sie tego schematu, co prawda urzywalem kilku funkcji po swojemu i tylko ta jedna dawala blad, moze byla jeszcze jedna jak z czyms eksperymentowalem

0

pos też sobie możesz policzyć i wstawić jaki ci trzeba. Na przykład Rectangle(size=(100, 100), pos=(self.size[0]/2-50, self.size[1]/2-50)) da kwadrat o stałym rozmiarze, ale za to zawsze na środku.

1 użytkowników online, w tym zalogowanych: 0, gości: 1