Reputation: 111
I am trying to create an app that draws a small ellipse at the point where I click my mouse. Then if I click again, I want it to delete the old ellipse and draw a new one at the new mouse click location. I have gotten this part to work. The next step is to get the mouse click location to print to the text of two labels. For some reason I can't figure out how to properly reference the label text to update it. My code is below. The ColorLoopWidget is mostly based off of the A Simple Paint App in the Kivy tutorials.
main.py
from kivy.config import Config
Config.set('graphics', 'width', '1000')
Config.set('graphics', 'height', '500')
Config.set('graphics', 'resizable', 0)
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
from kivy.properties import ObjectProperty
from kivy.graphics import Color, Ellipse, Line
Builder.load_file('hueLayout.kv')
class ColorLoopWidget(Widget):
xlabel = ObjectProperty
ylabel = ObjectProperty
def on_touch_down(self, touch):
with self.canvas:
self.canvas.clear()
d = 10
Ellipse(pos=(touch.x - d/2, touch.y - d/2), size=(d,d))
touch.ud['line'] = Line(points=(touch.x, touch.y))
## self.xlabel.text = 'x: '+str(touch.x)
## self.ylabel.text = 'y: '+str(touch.y)
## def on_touch_move(self, touch):
## touch.ud['line'].points += [touch.x, touch.y]
class HueLayout(Widget):
colorloopwidget = ObjectProperty
xlabel = ObjectProperty
ylabel = ObjectProperty
## def on_touch_down():
## ColorLoopWidget.on_touch_down()
##
## def on_touch_move():
## ColorLoopWidget.on_touch_move()
def clear_canvas(self):
self.colorloopwidget.canvas.clear()
class HueApp(App):
def build(self):
return HueLayout()
if __name__ == '__main__':
HueApp().run()
HueLayout.kv
<HueLayout>:
colorloopwidget: colorloopwidget
xlabel: xlabel
ylabel: ylabel
BoxLayout:
size: 1000, 500
orientation: 'horizontal'
ColorLoopWidget:
id: colorloopwidget
size: 500, 500
BoxLayout:
orientation: 'vertical'
Button:
text: 'Clear'
on_release: root.clear_canvas()
Label:
id: xlabel
text: 'x: '
size_hint_y: 0.2
Label:
id: ylabel
text: 'y: '
size_hint_y: 0.2
Upvotes: 2
Views: 2157
Reputation: 29478
Two problems:
1) You do xlabel = ObjectProperty
, but this just doesn't instantiate an ObjectProperty, it sets xlabel to ObjectProperty itself. You instead want to do xlabel = ObjectProperty()
, the brackets create an instance of ObjectProperty.
2) Your on_touch_down
method is in the ColorLoopWidget, and tries (in your commented out code) to reference self.xlabel and self.ylabel. This doesn't work because those properties are never set; if you check the kv you see that HueLayout has xlabel: xlabel
and ylabel: ylabel
but the interior ColorLoopWidget does not. The code below adds these properties, so that the ColorLoopWidget knows about the labels and its on_touch_down method is able to reference them.
The following code fixes both issues, and seems to work fine for me.
main.py:
from kivy.config import Config
Config.set('graphics', 'width', '1000')
Config.set('graphics', 'height', '500')
Config.set('graphics', 'resizable', 0)
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
from kivy.properties import ObjectProperty
from kivy.graphics import Color, Ellipse, Line
Builder.load_file('hueLayout.kv')
class ColorLoopWidget(Widget):
xlabel = ObjectProperty()
ylabel = ObjectProperty()
def on_touch_down(self, touch):
with self.canvas:
self.canvas.clear()
d = 10
Ellipse(pos=(touch.x - d/2, touch.y - d/2), size=(d,d))
touch.ud['line'] = Line(points=(touch.x, touch.y))
self.xlabel.text = 'x: '+str(touch.x)
self.ylabel.text = 'y: '+str(touch.y)
## def on_touch_move(self, touch):
## touch.ud['line'].points += [touch.x, touch.y]
class HueLayout(Widget):
colorloopwidget = ObjectProperty()
xlabel = ObjectProperty()
ylabel = ObjectProperty()
## def on_touch_down():
## ColorLoopWidget.on_touch_down()
##
## def on_touch_move():
## ColorLoopWidget.on_touch_move()
def clear_canvas(self):
self.colorloopwidget.canvas.clear()
class HueApp(App):
def build(self):
return HueLayout()
if __name__ == '__main__':
HueApp().run()
hueLayout.kv:
<HueLayout>:
colorloopwidget: colorloopwidget
xlabel: xlabel
ylabel: ylabel
BoxLayout:
size: 1000, 500
orientation: 'horizontal'
ColorLoopWidget:
xlabel: xlabel
ylabel: ylabel
id: colorloopwidget
size: 500, 500
BoxLayout:
orientation: 'vertical'
Button:
text: 'Clear'
on_release: root.clear_canvas()
Label:
id: xlabel
text: 'x: '
size_hint_y: 0.2
Label:
id: ylabel
text: 'y: '
size_hint_y: 0.2
Upvotes: 4