Reputation: 1395
I am trying to reset a text input box with new text when I click the mouse in another widget and I am not quite sure how to make this happen. I have tried altering the code in many ways but clearly do not not what I am doing. Here is the code I am using: Thanks to inclement and qua-non for getting me this far
Builder.load_string('''
<MouseWidget>:
image: image
label: label
orientation: 'vertical'
Image:
id: image
source: root.source
Label:
id: label
size_hint_y: None
height: 50
text: 'Hello World'
''')
class Test(TextInput):
def on_double_tap(self):
# make sure it performs it's original function
super(Test, self).on_double_tap()
def on_word_selection(*l):
selected_word = self.selection_text
print selected_word
# let the word be selected wait for
# next frame and get the selected word
Clock.schedule_once(on_word_selection)
class MouseWidget(BoxLayout):
image = ObjectProperty()
label = ObjectProperty()
source = StringProperty()
It is here in this def that I want to update the textinput box that is created in AccordianAPP and sent through TEST with new text every time the mouse is clicked on the image
def on_touch_down(self, touch):
if self.image.collide_point(*touch.pos):
self.label.text = str(touch.pos)
def on_touch_up(self, touch):
self.label.text = 'Hello World'
class AccordianApp(App):
def build(self):
root = Accordion(orientation='horizontal')
item= AccordionItem(title='Page One')
src = "image.png"
image = MouseWidget(source=src, size_hint = (1.0, 1.0))
This is the textinput that I want to reset the text="" to something else when I click on the image
textinput = Test(text='Testing', size_hint = (0.5, 1.0))
# add image to AccordionItem
item.add_widget(image)
item.add_widget(textinput)
root.add_widget(item)
return root
if __name__ == '__main__':
AccordianApp().run()
Thanks for the help
Upvotes: 0
Views: 1439
Reputation: 29478
What you really need here is a reference to the textinput that the mousewidget can access. As long as the mousewidget can access some variable that's assigned to the textinput, it can do anything it likes to that textinput.
Here's a simple modification that simply adds an attribute 'self.textinput' to the mousewidget, that is then set to point at the textinput. Then in the on_touch_up method it's easy to add text to the textinput...in this case appending the new coordinates each time.
from kivy.lang import Builder
from kivy.uix.textinput import TextInput
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.accordion import *
from kivy.properties import *
from kivy.app import App
Builder.load_string('''
<MouseWidget>:
image: image
label: label
orientation: 'vertical'
Image:
id: image
source: root.source
Label:
id: label
size_hint_y: None
height: 50
text: 'Hello World'
''')
class Test(TextInput):
def on_double_tap(self):
# make sure it performs it's original function
super(Test, self).on_double_tap()
def on_word_selection(*l):
selected_word = self.selection_text
print selected_word
# let the word be selected wait for
# next frame and get the selected word
Clock.schedule_once(on_word_selection)
class MouseWidget(BoxLayout):
image = ObjectProperty()
label = ObjectProperty()
source = StringProperty()
textinput = ObjectProperty()
def on_touch_down(self, touch):
if self.image.collide_point(*touch.pos):
self.label.text = str(touch.pos)
def on_touch_up(self, touch):
self.label.text = 'Hello World'
if self.textinput is not None:
self.textinput.text += ' ... and {}'.format(touch.pos)
class AccordianApp(App):
def build(self):
root = Accordion(orientation='horizontal')
item= AccordionItem(title='Page One')
src = "image.png"
image = MouseWidget(source=src, size_hint = (1.0, 1.0))
textinput = Test(text='Testing', size_hint = (0.5, 1.0))
image.textinput = textinput
# add image to AccordionItem
item.add_widget(image)
item.add_widget(textinput)
root.add_widget(item)
return root
if __name__ == '__main__':
AccordianApp().run()
This isn't the only way to do it - there are lots of ways you could make that reference available, and different ones might be useful in different situations. For instance, you could make another widget containing both your mousewidget and the textinput, and write all the bindings in kv language.
Another trick that can be useful for unrelated widgets (where it isn't easy to pass a reference between them) is to store the reference in your App class. You can do something like
class AccordianApp(App):
some_thing = ObjectProperty()
...
This is useful because you can always access the app with App.get_running_app()
, so even if you have disconnected widgets and can't see how they might communicate, you could store the textinput at app level so anything can easily get at it.
I hope that's clear...I only mean to say, there are several possibilities that might suit different situations. For your particular problem, you can just store a reference to the textinput in the mousewidget, or some similar simple solution.
Upvotes: 1