01:44 Изучаем Киви- События и свойства | ||||||||
События и свойстваСобытия являются важной частью программирования Kivy. Это не может быть удивительным для тех, у кого есть опыт разработки в GUI, но это важная концепция для новичков. После того, как вы поймете, как события работают и как связываться с ними, вы увидите их повсюду в Kivy. Они позволяют легко построить любое поведение, которое вы хотите в Kivy. Введение в Event DispatcherОдним из наиболее важных базовых классов каркаса является EventDispatcher объекты зависят от основного цикла для создания и обработки событий. Основной циклЭтот цикл выполняется в течение всего времени жизни приложения и завершает работу при выходе из приложения. Внутри цикла, на каждой итерации, события генерируются из пользовательского ввода, аппаратных датчиков или нескольких других источников, а также кадры визуализируются на дисплее. Ваша заявка будет указать функции обратного вызова (подробнее об этом позже), которые называются в основном цикле. Если обратный вызов занимает слишком много времени или не выходит вообще, основной цикл нарушается, и ваше приложение не работает должным образом больше. В приложениях Kivy, вы должны избегать длинных / бесконечных циклов или спать. Например, следующий код делает так:
while True:
animate_something()
time.sleep(.10)
При запуске этого кода, программа никогда не будет выходить из цикла, запрещая Kivy делать все другие вещи, которые необходимо сделать. В результате, все, что вы увидите, это черное окно, с которым вы не будете иметь возможность взаимодействовать с. Вместо этого вам нужно создать "график" ваш Планирование повторяющихся событийВы можете вызвать функцию или метод каждые Х раз в секунду , используя
def my_callback(dt):
print 'My callback is called', dt
Clock.schedule_interval(my_callback, 1 / 30.)
У вас есть два способа unscheduling ранее запланированное событие. Первым будет использовать
Clock.unschedule(my_callback)
Или, вы можете вернуть значение False в вашей функции обратного вызова:
count = 0
def my_callback(dt):
global count
count += 1
if count == 10:
print 'Last call of my callback, bye bye !'
return False
print 'My callback is called'
Clock.schedule_interval(my_callback, 1 / 30.)
Планирование одноразового событияИспользуя
def my_callback(dt):
print 'My callback is called !'
Clock.schedule_once(my_callback, 1)
Это будет вызывать функцию
-1 В основном используется, когда вы уже в запланированном событии, и если вы хотите запланировать вызов до следующего кадра. Второй способ повторить вызов функции - сначала назначить функцию обратного вызова один раз с
def my_callback(dt):
print 'My callback is called !'
Clock.schedule_once(my_callback, 1)
Clock.schedule_once(my_callback, 1)
В то время как основной цикл будет пытаться сохранить графику в соответствии с просьбой, существует некоторая неопределенность относительно того, когда именно функция запланированного обратного вызова будет вызвана. Иногда другой обратный вызов или какой-либо другой задачи в заявке займет больше времени, чем ожидалось, и, таким образом, сроки могут быть немного не соответствовать . В последнем решении повторяющейся задачи обратного вызова, следующая итерация будет называться по меньшей мере, через одну секунду после последней закончившейся итерации . С Trigger событияЕсли вы хотите запланировать функцию, которая будет вызываться только один раз для следующего кадра, как спусковой крючок, вас может возникнуть соблазн добиться того, чтобы выглядеть примерно так:
Clock.unschedule(my_callback)
Clock.schedule_once(my_callback, 0)
Этот способ программирования триггера является не корректным, так как вы всегда будете называть запланированную функцию, когда вы хотите этого или нет. Кроме того, запланированную функцию должен просматривать список weakref (Часов), чтобы найти свой обратный вызов и удалить его. Используйте триггер вместо того, чтобы:
trigger = Clock.create_trigger(my_callback)
# later
trigger()
Каждый раз, когда вы называете триггер (), он будет планировать один вызов вашего обратного вызова. Если он уже был запланирован, он не будет перенесен. Виджет событийВиджет имеет 2 типа событий по умолчанию:
Для обсуждения о том , как виджет события прикосновения управляются и распространяются, пожалуйста , обратитесь к сенсорным событие пузырьковой Widget раздела. Создание пользовательских событийЧтобы создать диспетчер событий с пользовательскими событиями, вам необходимо зарегистрировать имя события в классе, а затем создать метод с тем же именем. Смотрите следующий пример:
class MyEventDispatcher(EventDispatcher):
def __init__(self, **kwargs):
self.register_event_type('on_test')
super(MyEventDispatcher, self).__init__(**kwargs)
def do_something(self, value):
# when do_something is called, the 'on_test' event will be
# dispatched with the value
self.dispatch('on_test', value)
def on_test(self, *args):
print "I am dispatched", args
Прикрепление обратных вызововДля того, чтобы использовать события, вы должны связать обратные вызовы к ним. Когда отправляется событие, ваши обратные вызовы будут вызываться с параметрами, имеющих отношение к конкретному событию. Обратный вызов может быть любой питон вызов, но вы должны убедиться, что он принимает аргументы, испускаемые событием. Для этого, как правило , используют * ARGS аргумент, который будет ловить все аргументы в списке аргументов. Пример:
def my_callback(value, *args):
print "Hello, I got an event!", args
ev = MyEventDispatcher()
ev.bind(on_test=my_callback)
ev.do_something('test')
Радует что к Введение в СвойстваСвойства являются удивительным способом определения событий и связываются с ними. По существу, они производят события таким образом, что, когда изменяется атрибут в ваших объектах, все свойства, которые ссылаются на этот атрибут автоматически обновляются. Существуют различные виды свойств для описания типа данных, которые вы хотите обработать. Декларация о собственностиЧтобы объявить свойства, вы должны объявить их на уровне класса. Класс будет делать свою работу, чтобы создать экземпляр реальных атрибутов при создании объекта. Эти свойства не являются атрибутами: они являются механизмами создания событий на основе ваших атрибутов:
class MyWidget(Widget):
text = StringProperty('')
Когда переопределение __init__, всегда принимают ** kwargs и использовать супер () используется для вызова метода __init__ родителя, проходя в вашем экземпляре класса:
def __init__(self, **kwargs):
super(MyWidget, self).__init__(**kwargs)
Диспетчер свойства событияKivy свойства по умолчанию обеспечивают on_ <property_name> событие. Это событие вызывается, когда значение свойства изменяется. Заметка Если новое значение свойства равно текущему значению, то <property_name> событие on_ не будет называться. Например, рассмотрим следующий код:
class CustomBtn(Widget):
pressed = ListProperty([0, 0])
def on_touch_down(self, touch):
if self.collide_point(*touch.pos):
self.pressed = touch.pos
return True
return super(CustomBtn, self).on_touch_down(touch)
def on_pressed(self, instance, pos):
print ('pressed at {pos}'.format(pos=pos))
В приведенном выше в строке 3 кода:
pressed = ListProperty([0, 0])
Определим отжатый свойство типа В строке 5:
def on_touch_down(self, touch):
if self.collide_point(*touch.pos):
self.pressed = touch.pos
return True
return super(CustomBtn, self).on_touch_down(touch)
Мы переопределили Если сенсорн попадает внутрь нашего виджета, мы меняем значение прижаты к touch.pos и возвращает истину, показывая , что мы коснулись и не хотим, чтобы в дальнейшем использовать любой другой виджет. И, наконец, если сенсор выходит за пределы нашего виджета, мы вызываем исходное событие , используя супер (...) и возвращается результат. Это позволяет зафиксировать сенсорное события, чтобы продолжить, с изменениями которые произошли. Наконец в строке 11:
def on_pressed(self, instance, pos):
print ('pressed at {pos}'.format(pos=pos))
Определим on_pressed функцию , которая будет вызвана свойством всякий раз , когда значение свойства изменяется. Заметка Это on_ <prop_name> событие вызывается в классе , где определяется собственностью. Для контроля / наблюдать какие-либо изменения в собственность за пределами класса, в котором она определена, вы должны привязать к свойству, как показано ниже. Привязка к свойству Как контролировать изменения в собственности, когда все у вас есть доступ к виджет экземпляра? Вы связываете к собственности:
your_widget_instance. Bind (property_name = function_name)
Например, рассмотрим следующий код:
Если вы запустите код, как это, вы заметите два заявления для печати в консоли. Один из on_pressed события , который вызывается внутри класса CustomBtn , а другой из btn_pressed функции , которую мы связываем с изменением свойств. Причина, по которой называются обе функции просто. Связывание не означает подмену. Наличие обоих этих функций является излишним, и вы должны вообще использовать только один из методов прослушивания / реагирующих на изменения свойств. Вы должны также принять во внимание параметры, которые передаются в <property_name> события on_ или функции , связанной с собственностью.
def btn_pressed(self, instance, pos):
Первым параметром является сам, который является экземпляром класса , где определена эта функция. Вы можете использовать функцию в интерактивном режиме, следующим образом:
Первый параметр будет экземпляр класса свойство которого определено. Второй параметр будет значение, которое имеет новое значение свойства. Вот полный пример, полученный из приведенных выше отрывков, которые вы можете использовать, чтобы скопировать и вставить в редактор, чтобы экспериментировать.
Выполнение кода выше даст вам следующий вывод: Наш CustomBtn не имеет визуального представления и, таким образом, кажется черным. Вы можете прикоснуться к / нажать на черную область, чтобы увидеть вывод на консоли. Составные свойстваПри определении Рассмотрим следующий код.
Здесь cursor_pos является Связывают аргумент в конце определяет , что on_cursor_pos событие отправляется , если какой - либо из свойств используется в связывания = изменения аргумента. | ||||||||
|
Всего комментариев: 1 | |
| |