Уведомления

Группа в Telegram: @pythonsu

#1 Март 23, 2010 13:44:49

python4ik
От:
Зарегистрирован: 2010-01-05
Сообщения: 251
Репутация: +  0  -
Профиль   Отправить e-mail  

def redraw(rect)

Всем привет. Меня всё интересует поучающий код - Robot.py(где надо довести квадратик к цели). Считаю,что пока не разберёшся хотя-бы с одной программкой,пока не поймёш весь смысл,вложенный в коде,не стоит и переходить к другим вопросам по Питону.Вообщем логику,классы,смысл я понял этого кода,. В частности меня интересует такие вопросы:

1) def redraw(rect): что в этой функции управления прорисовкой значит rect ? Когда он(rect) вызывается?
2) if canvas:
canvas.blit(img) - как это понять?(Если обновился экран,то на этот экран вывести img ?). Меня интересует смысл этих двух выражений: if canvas
Или как надо понимать?(.......................................................................................)



Офлайн

#2 Март 23, 2010 15:03:06

igor.kaist
От:
Зарегистрирован: 2007-11-12
Сообщения: 1879
Репутация: +  3  -
Профиль   Отправить e-mail  

def redraw(rect)

1. Вызывается периодически UI сервером, когда нужно перерисовать экран. В аргумент rect попадает тьюпл с областью экрана, который нужно перерисовать. Но дополнительно эту функцию обычно вызывают вручную, чтоб перерисовать принудительно.
2. Тут без всего кода трудно сказать, зачем автор так сделал. (до app.body=canvas, redraw все равно вызываться не будет)



Офлайн

#3 Март 24, 2010 01:00:22

python4ik
От:
Зарегистрирован: 2010-01-05
Сообщения: 251
Репутация: +  0  -
Профиль   Отправить e-mail  

def redraw(rect)

Смотрю на “некоторые” задаваемые вопросы “Новичков”(хотя я пока и сам вникающий),аж самому сейчас становится и стыдно и “смешно”,что я даже этого недавно не знал(допустим мне как начинающему очччччччччччччень помогло во вникание в классы перегрузка встроенных оперов:допустим метод в классе:

cl...
def __str__(s):
(и тут можно дать задание (Уважаемому Питону) вывести какое хочеш выражение)
s.spam='hello frends'
return s.spam (это если через print s. А если __str__ заменить на __repr__,то можно вывести без print - экз-р---s(self)"Enter"
А вообще я поддержую такие пояснения (…похожие как выше…) для Новичков!!!

А всё-таки ЛУТЦ(уважаемый мной очень MARK LUTZ) это сила.После прочтения с небольшим фанатизмом “немаленькой” книжоночки мнооооооооооого вопросов отпадает.



Офлайн

#4 Март 24, 2010 01:10:42

python4ik
От:
Зарегистрирован: 2010-01-05
Сообщения: 251
Репутация: +  0  -
Профиль   Отправить e-mail  

def redraw(rect)

Вот небольшой код этой проги.Так можно? немного поподробней на вышеперечисленные вопросы

from graphics import *
from vibra import *
import appuifw as ui
import e32

##### Class
class cl_robot:
def __init__(self,x=1,y=1,exit_x=17,exit_y=17):
self.x=x
self.y=y
self.k=0
self.exit_x=exit_x
self.exit_y=exit_y
#--------------
def show(self,show=1):
# получаем глобальный объект "рисунок" на котором будет изображено положение Робота
global img
# задаём цвет рисования Робота
if show==1: color=0xffffff
else: color=0x0
# рисуем (или стираем) текущее положение Робота
img.rectangle(((self.x-1)*10+2,(self.y-1)*10+2,self.x*10-2,self.y*10-2),color,color)
# выводим в нижней части экрана количество шагов, которые уже сделал Робот
img.rectangle((5,180,100,190),0,0)
img.text((5,190),u'step=%s'%self.k,0xffffff)
#--------------
def step(self,d): #если d= 0 - шаг вправо, 1 - шаг вверх, 2 - шаг влево, 3 - шаг вниз
# run - это глобальный флаг, который будет отвечать за достижение цели (произойдёт останов программы)
global img,run
# рисуем чёрный квадрат на том месте, где раньше был наш Робот
self.show(0)
# это флаг, отвечающий за возможность сделать шаг в направлении d (True - можно, False - нельзя, упёрлись в стенку)
res=True
# проверяем, может ли Робот слелать шаг вправо.
if d==0:
# если может, то делаем этот шаг
if self.x<17: self.x+=1
# если не может - "сбрасываем" флаг
else: res=False
# далее - аналогично для направления "вверх", "влево", "вниз"
elif d==1:
if self.y>1: self.y-=1
else: res=False
elif d==2:
if self.x>1: self.x-=1
else: res=False
elif d==3:
if self.y<17: self.y+=1
else: res=False
# если шаг не был сделан - включаем вибру на 25 миллисекунд
if not res: vibrate(25,100)
# если шаг сделан - увеличиваем счётчик шагов Робота
else: self.k+=1
# проверяем достижение Цели
if (self.exit_x==self.x) and (self.exit_y==self.y):
# вывод сообщения о победе
ui.note(u'You win!!!')
# победная вибра :)
vibrate(100,100)
e32.ao_sleep(0.2)
vibrate(100,100)
e32.ao_sleep(0.2)
vibrate(100,100)
e32.ao_sleep(0.2)
vibrate(700,100)
e32.ao_sleep(0.2)
# цель достигнута! сбрасываем флаг
run=0
# рисуем Робота на новом месте (или на старом, если шаг не сделан)
self.show()
##### Class

# процедура, которая осуществляет завершение скрипта
def exit():
global run,script_lock,scr
run=0
# восстановим вид экрана, как до запуска скрипта
ui.app.screen=scr
script_lock.signal()

# инициализация "канвы"
canvas=None

# функция управления прорисовкой поля, Робота и всего, что будет на экране
def redraw(rect):
global canvas, img, robot
img.clear(0x0)
# рисуем сетку
for i in range (9,161,10):
img.line((0,i,171,i),0x555555)
img.line((i,0,i,171),0x555555)
# и поле
img.rectangle((0,0,171,171),0xffffff)
# рисуем Цель робота
img.rectangle(((robot.exit_x-1)*10+1,(robot.exit_y-1)*10+1,robot.exit_x*10-1,robot.exit_y*10-1),0xff0000,0xff0000)
# вывод поясняющей подсказки
img.text((160,203),u'Exit',0xff0000,u'LatinBold12')
# рисуем Робота
robot.show()
# так надо! :)
if canvas:
# выводим содержимое рисунка "img" на канву
canvas.blit(img)

# функция обработки нажатия клавиш
def event(event):
global robot,run
# вот тут-то и пригодился наш флаг. если флаг run=0, то реагировать на клавиши больше не надо, просто выходим из функции
if run==0: return False
# проверяем, какая кнопка нажата и действуем!
if event['keycode']==63495: robot.step(2)
elif event['keycode']==63496: robot.step(0)
elif event['keycode']==63497: robot.step(1)
elif event['keycode']==63498: robot.step(3)
# после нажатой клавиши надо перерисовать поле
redraw(0)

### ОСНОВНАЯ ПРОГРАММА
# запоминаем вид экрана до запуска скрипта и потом задаём вид "полный без кнопок и заголовка"
scr=ui.app.screen
ui.app.screen='full'
# сообщаем скрипту, как реагировать на нажатие правой софт-клавиши
ui.app.exit_key_handler=exit

# инициализация флага достижения цели. 1 - Цель не достигнута
run=1

# создаём экземпляр класса роботы - объект "Робот" и задаём начальные параметры. С днём рождения, Робот! :)
robot=cl_robot(2,12,17,1)

# создаём объект "рисунок" на котором мы будем рисовать всё
img=Image.new((176,208))
# указываем скрипту, что будем работать с графикой и назначаем процедуры, ответственные за прорисовку экрана (redraw_callback) и обработку нажатий клавиш (event_callback)
ui.app.body=canvas=ui.Canvas(event_callback=event,redraw_callback=redraw)

# первоначальная прорисовка экрана
redraw(canvas.size)

# заставляем скрипт ждать, пока его не закроют программно
script_lock=e32.Ao_lock()
script_lock.wait()



Офлайн

#5 Март 24, 2010 09:26:30

igor.kaist
От:
Зарегистрирован: 2007-11-12
Сообщения: 1879
Репутация: +  3  -
Профиль   Отправить e-mail  

def redraw(rect)

Мда, видно что код написан как раз таки новичком. Обилие global это очень плохой тон. if canvas и “инициализация канвы” canvas=None, вообще непонятно зачем было сделано.
Все можно было сделать в классе cl_robot без применения глобальных переменных.



Офлайн

#6 Март 24, 2010 13:58:22

python4ik
От:
Зарегистрирован: 2010-01-05
Сообщения: 251
Репутация: +  0  -
Профиль   Отправить e-mail  

def redraw(rect)

1. Вызывается периодически UI сервером
Что такое UI сервер? И как понять “В аргумент rect попадает тьюпл с областью экрана”.Что такое тьюпл?
Возьмём другой код:
import appuifw, graphics, e32, key_codes  

BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
key_down = None
clicked = None

def handle_event(event):
global clicked, key_down
if event['type'] == appuifw.EEventKey:
if key_down:
key_down = (event['keycode'], "down")
else:
key_down = (event['keycode'], "pressed")
elif event['type'] == appuifw.EEventKeyUp and key_down:
code, mode = key_down
if mode == "pressed":
clicked = code
key_down = None

def key_is_down(code):
if key_down == (code, "down"):
return True
return False

def quit():
global running
running = False

def handle_redraw(rect): - rect.Когда он вызывается?
if img: canvas.blit(img) - вот ещё пример if img: как это понять?Напишите семантику этого выражения!

img = None
canvas = appuifw.Canvas(event_callback=handle_event,
redraw_callback=handle_redraw)
appuifw.app.screen = 'full'
appuifw.app.body = canvas
appuifw.app.exit_key_handler = quit

x = y = 100
w, h = canvas.size
img = graphics.Image.new((w, h))
img.clear(WHITE)

running = True
while running:
if key_is_down(key_codes.EKeyLeftArrow):
x -= 2
elif key_is_down(key_codes.EKeyRightArrow):
x += 2
elif key_is_down(key_codes.EKeyDownArrow):
y += 2
elif key_is_down(key_codes.EKeyUpArrow):
y -= 2

img.clear(WHITE)
img.point((x, y), outline = BLACK, width = 50)
handle_redraw(None) - Почему (None) ?
e32.ao_yield()



Офлайн

#7 Март 24, 2010 16:53:18

igor.kaist
От:
Зарегистрирован: 2007-11-12
Сообщения: 1879
Репутация: +  3  -
Профиль   Отправить e-mail  

def redraw(rect)

python4ik
Что такое UI сервер?
программный компонент симбиана, который отвечает за работу с графическим интерфейсом.
python4ik
И как понять “В аргумент rect попадает тьюпл с областью экрана”.Что такое тьюпл?
тьюпл он же tuple - встроенный тип http://docs.python.org/tutorial/datastructures.html
python4ik
вот ещё пример if img: как это понять?
если img не None тогда выводим img на экран. Это сделано на тот случай, если img “не успелось” присвоится изображение. Но это тоже достаточно глупо. Легче сначала создать изображение, а потом гарантированно его использовать.



Офлайн

#8 Март 24, 2010 18:42:17

python4ik
От:
Зарегистрирован: 2010-01-05
Сообщения: 251
Репутация: +  0  -
Профиль   Отправить e-mail  

def redraw(rect)

Если тьюпл это кортеж,то про кортеж я конечно знаю что это. :)

Вызывается периодически UI сервером, когда нужно перерисовать экран. В аргумент rect попадает тьюпл с областью экрана, который нужно перерисовать. Но дополнительно эту функцию обычно вызывают вручную, чтоб перерисовать принудительно.
Допустим размер экрана (176,208). (х,у): (x-это коорд-ты точки по горизонтали,где она находится в данный момент,y-тоже самое(но по вертикали))
Если нажимается кнопка допустим влево,точка передвигается на экране, в rect попадает какой участок экрана?-куда переехала точка или где она была до этого?
И как,зачем вызывают функцию вручную,чтобы перерисовать принудительно?



Отредактировано (Март 24, 2010 20:17:35)

Офлайн

#9 Март 25, 2010 09:15:50

igor.kaist
От:
Зарегистрирован: 2007-11-12
Сообщения: 1879
Репутация: +  3  -
Профиль   Отправить e-mail  

def redraw(rect)

В rect попадает координаты участка экрана, который после какие либо событий нужно перерисовать.
Допустим, на экран поверх всего вылезло note, после этого, участок экрана,где был этот note нужно обновить. Ну не запомнил UI сервер что там было под note :) , и он вызывает функцию redraw с параметром rect, куда попадает тьюпл с областью экрана, который желательно обновить. Но многие забивают на это и обновляют весь экран полностью.

python4ik
И как,зачем вызывают функцию вручную,чтобы перерисовать принудительно?
А если логически подумать…. ?! Например, нажал ты на кнопку, положение спрайта изменилось, надо же экран перерисовать а не ждать, пока это сделает UI сервер, вызвав redraw.
P.S. Кроме того, как “учить питона в интернете”, надо логически мыслить и понимать логику работы программы.



Офлайн

#10 Март 25, 2010 17:08:43

python4ik
От:
Зарегистрирован: 2010-01-05
Сообщения: 251
Репутация: +  0  -
Профиль   Отправить e-mail  

def redraw(rect)

Игорь я согласен,что Лутца мало для начала.Надо много-много учить и печатать.А так-как я с английским не совсем дружу,пару статей полезных на русском можно? Ссылку для начинающих про UI сервер и про перерисовку экрана! Я конечно ищу,но совет бы не помешал! Мне даже уже в последнее время жена говорит,когда я к ней подойду за целый день из своего офиса(компьютерной комнаты),а понимает моё увлечение Питоном! :) Учу!



Отредактировано (Март 25, 2010 17:54:34)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version