diff --git a/doc/sources/guide/events.rst b/doc/sources/guide/events.rst index 7833e9fd5..baf217c9d 100644 --- a/doc/sources/guide/events.rst +++ b/doc/sources/guide/events.rst @@ -12,21 +12,23 @@ You have 2 types of events living in Kivy: Clock events ------------ -Before starting the event part, Kivy have a main loop, and must avoid to break -it. The main loop is responsible to read all the inputs, load images -asynchronously, draw the frame etc. If you are looping yourself or sleeping -somewhere, you'll break the main loop. For example, here is the biggest mistake -done:: +Before we discuss events, you need to know that Kivy has a main loop, and that +it's important that you avoid breaking it. The main loop is responsible for +reading from inputs, loading images asynchronously, drawing to the frame, etc. +If you are looping or sleeping, you'll break the main loop. As an example, the +following code does both:: while True: animate_something() time.sleep(.10) -This is wrong. Because you'll never go out of your loop, and you'll see a black -window, no more interaction. You need to "schedule" the call of your function -over the time. You can schedule it in 2 way: repetitive call or one-time call. +When you run this, the program will never exit your loop, preventing Kivy from +doing all of the other things that need doing. As a result, all you'll see is a +black window which you won't be able to interact with. You need to "schedule" +your ``animate_something()`` function call over time. You can do this in 2 ways: +a repetitive call or one-time call. -Scheduling an repetitive event +Scheduling a repetitive event ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ You can call a function or a method every X times per seconds using @@ -37,13 +39,13 @@ function named my_callback 30 times per seconds:: print 'My callback is called', dt Clock.schedule_interval(my_callback, 1 / 30.) -You have 2 ways of unschedule a previously scheduled event. The first would be +You have 2 ways of unscheduling a previously scheduled event. The first would be to use :meth:`~kivy.clock.Clock.unschedule`:: Clock.unschedule(my_callback) Or, you can return False in your callback, and your event will be automatically -unschedule:: +unscheduled:: count = 0 def my_callback(dt): @@ -56,48 +58,48 @@ unschedule:: Clock.schedule_interval(my_callback, 1 / 30.) -Scheduling an one-time call event +Scheduling a one-time event ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Sometime, you can to call a function "later", like in the next frame, or in X -seconds. Use :meth:`~kivy.clock.Clock.schedule_once`:: +Using :meth:`~kivy.clock.Clock.schedule_once`, you can call a function "later", +like in the next frame, or in X seconds:: def my_callback(dt): print 'My callback is called !' Clock.schedule_once(my_callback, 1) -This will call the callback one second after. The second argument is the time -to call the function, but you have achieve tiny tricks here : +This will call ``my_calback`` in one second. The second argument is the amount +of time to wait before calling the function, in seconds. However, you can +achieve some other results with special valus for the second argument: -- If it's more than 0, the callback will be called in the X seconds -- If it's 0, the callback will be called in the next frame, before the drawing -- If it's -1, the callback will be called before the drawing, if the clock is - not overflooded +- If X is greater than 0, the callback will be called in X seconds +- If X is 0, the callback will be called after the next frame +- If X is -1, the callback will be called before the next frame -The -1 is mostly used when you are already is a scheduled event, and if you +The -1 is mostly used when you are already in a scheduled event, and if you want to schedule a call BEFORE the next frame is happening. Trigger events ~~~~~~~~~~~~~~ -If you want to have schedule a call only "one time" for the next frame, the -trigger events is for you. Before, triggering can be achieve with:: +If you want to schedule a function to be called only once for the next frame, +like a trigger, you can achieve that like so:: Clock.unschedule(my_callback) Clock.schedule_once(my_callback, 0) -That way of doing trigger is expensive, because you'll always call unschedule -whatever if the event is already scheduled or not. In addition, it need to -iterate into the weakref list of the Clock to found your callback, and remove -it. Don't do that. Use trigger:: +This way of programming a trigger is expensive, since you'll always call +unschedule, whether or not you've even scheduled it. In addition, unschedule +needs to iterate the weakref list of the Clock in order to find your callback +and remove it. Use a trigger instead:: trigger = Clock.create_trigger(my_callback) # later trigger() -Each time you'll call trigger, it will schedule a call of your callback, only -one. If the schedule was already done, it will be ignored. +Each time you call trigger, it will schedule a single call of your callback. If +it was already scheduled, it will not be rescheduled. @@ -105,38 +107,37 @@ one. If the schedule was already done, it will be ignored. Widget events ------------- -A widget have 2 types of events: +A widget has 2 types of events: -- Property event: if your widget change of pos or size, you'll have an event - fired -- Widget defined event: a Button will have even fired when it's pressed or +- Property event: if your widget changes its position or size, an event is fired. +- Widget-defined event: an event will be fired for a Button when it's pressed or released. Property event ~~~~~~~~~~~~~~ -A widget have many property. You'll find in the doc that every property have a +A widget has many properties. You'll find in the doc that every property has a type like :class:`~kivy.properties.NumericProperty`, :class:`~kivy.properties.StringProperty`, :class:`~kivy.properties.ListProperty`. -Usualy, when you want to create a Python class with properties, you'll do something like this:: +Usualy, when you want to create a Python class with properties, you do something like this:: class MyClass(object): def __init__(self): super(MyClass, self).__init__() self.prop1 = 'bleh' -By doing that, you have not a good way to know when the prop1 is changed, -except by rewriting the class and hook the __getattribute__. But we'll not get -into details here. The Kivy way is that:: +Using this code though, you do not have a good way to know when ``prop1`` is +changed, except by rewriting the class and adding a hook in +``__getattribute__``. The Kivy way to do this is:: class MyClass(Widget): prop1 = StringProperty('bleh') -You can connect a function to that property if you willing to be called when -the value of the property change:: +You can connect a function to this property if you want to be called when the +value of the property changes:: def my_callback(instance, value): print 'the widget', instance, 'prop1 changed to', value @@ -148,29 +149,30 @@ the value of the property change:: # now change prop1 => it will call your callback ! obj.prop1 = 'hello world' -If you want to resign of receiving event from prop1 property, call unbind:: +If you want to stop receiving events from the ``prop1`` property, call unbind:: obj.unbind(prop1=my_callback) -Widget defined event +Widget-defined event ~~~~~~~~~~~~~~~~~~~~ -Sometime, the properties event is not enought to hook on it. For example, a -Button can have a state property that will indicate if the Button is currently -pressed or not ("down " or "normal" actually). We make the choice to add -additionnals event for that: :meth:`~kivy.uix.button.Button.on_press` and -:meth:`~kivy.uix.button.Button.on_release` event:: +Sometimes the property event is not enough to hook onto. For example, a Button +could have a state property that indicates whether the Button is currently +pressed or not. We made the choice to add additional events for this: the +:meth:`~kivy.uix.button.Button.on_press` and +:meth:`~kivy.uix.button.Button.on_release` events:: def my_callback_press(instance): print 'The button', instance, 'is pressed' button = Button(text='Hello world') button.bind(on_press=my_callback_press) -Every widget defined event are in the documentation, at the start of the widget -class. You can find a list of widget defined event that the widget support. +Every event defined by a widget is in the documentation, at the start of the +class. You can find a list of widget-defined events that the widget supports. -If are designing your own widget, you can create your own widget event by using the :meth:`~kivy.event.register_event_type`:: +If you are designing your own widget, you can create a widget event by using +:meth:`~kivy.event.register_event_type`:: class MyClass(Widget): @@ -182,9 +184,9 @@ If are designing your own widget, you can create your own widget event by using # empty handler needed pass -Then, the user can hook on it, same as the Button.on_press event. But the event -is never dispatched here. Let's just add a function for demonstrating how to -dispatch a widget defined event:: +Then, the user can hook to it, same as the Button.on_press event. In this +example, the event is never dispatched. Let's just add a function demonstrating +how to dispatch a widget-defined event:: class MyClass(Widget): @@ -193,5 +195,5 @@ dispatch a widget defined event:: def do_something(self): self.dispatch('on_custom_event') -Now, everytime you'll call do_something() method, it will dispatch -on_custom_event, and call every function attached to this event. +Now, everytime you call the ``do_something()`` method, it will dispatch +``on_custom_event``, and call every function attached to this event.