Найти - Пользователи
Полная версия: Цикл. Непонятная проблема.
Начало » GUI » Цикл. Непонятная проблема.
1 2
leonid_10
Не пойму, как работает цикл. Написал, вроде нормально получилось, что и требовалось, а вот попытка растянуть его во времени не получается. Я же включаю sleep в цикл, а у меня получается задержка перед рисованием, а потом бац, и всё готово. Что я делаю не так?
# coding:utf-8

import wx
import wx.lib.wxcairo
from time import sleep

class myframe(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1, "Каир", size=(500,400))
self.Bind(wx.EVT_PAINT, self.OnPaint)

def OnPaint(self, event):
dc = wx.PaintDC(self)
cr = wx.lib.wxcairo.ContextFromDC(dc)

#cairo drawing calls
x = 0
y = 0
h = 220
w = 30
while x < 230 and y < 230:
x += 10
y += 20
cr.set_source_rgba (0.1, 0.5, 0.2, 1)
cr.set_line_width (10)
cr.move_to (x, y)
cr.line_to (x + h, y + w)
cr.move_to (x, y + w)
cr.line_to (x + h, y + w)
cr.stroke()
sleep(0.5)



app = wx.App()
f = myframe()
f.Show()
app.MainLoop()
pasaranax
Это вероятно происходит из-за буферизации. Не знаю как в wx, но в qt надо вызывать метод update у виджета, чтобы он обновлялся на каждом шаге.

Тему надо было в раздел GUI.
igor.kaist
Да и не очень то хорошая идея использовать sleep в GUI потоке…
bw
> Да и не очень то хорошая идея использовать sleep в GUI потоке…
Здесь я с тобой не соглашусь. Вообще-то за это руки отрывать надо.

По поводу вопроса. Реализация вывода может быть самая разная. Это и отрисовка непосредственно в момент вызова функции, что встречается редко, буферизация (как было сказано) растра или буферизация команд (координаты, цвета, методы и пр.) с последующим их исполнением ядром граф. библиотеки (как в GDI, если я правильно помню).

Дальше включаем голову и делаем что-то типа такого:
import time

class Foo2DIterator(object):

def __init__(self):
self.start_time = time.time()
self.step_time = 0.5

def __iter__(self):
now_time = time.time()

x = y = 0

while self.start_time <= now_time:
yield x, y

x += 10
y += 20

now_time -= self.step_time
Как исправить OnPaint и вставить туда Foo2DIterator сообразишь сам. OnPaint должен вызываться дважды в секудну, естественно не руками, читаешь API по wx и ищешь там методы типа update, refresh, repaint, invalidate и т.д., выбираешь подходящее и вызываешь метод используя таймер (наверняка у wx что-то такое можно найти).

..bw
leonid_10
bw
Здесь я с тобой не соглашусь. Вообще-то за это руки отрывать надо.
Неплохое объяснение новичку, почему нельзя использовать sleep :)
Только всё-равно остаётся непонятным, почему этим нельзя пользоваться, если будет получен нужный результат? Ну, если не будет получен нужный результат, то, можно себе сказать: “Предупреждали же, что это типично бычья идея - применять sleep”
Zubchick
очевидно же: слип подвешивает выполнение всей программы, в том числе и гуя
Андрей Светлов
Zubchick, вы безусловно правы, но не корректны.
Попробуйте написать про цикл обработки сообщений и почему сообщение нельзя обрабатывать (простите за тавтологию) долго.
igor.kaist
leonid_10
Неплохое объяснение новичку, почему нельзя использовать sleep :)
Само по себе GUI работает в бесконечном цикле. Запускается этот цикл, когда вы делаете mainloop(). Поэтому то программа и не завершается. В этом цикле происходит реакция на различные события (нажатие клавиш, действия мышью и т.д.) и перерисовка окна. И если этот цикл приостановить (sleep, ресурсоемкие операции), то программа зависает. Вернее не сама программа, а GUI. Поступило событие, а главный цикл так и не добрался до того места, где нужно среагировать на него. Рекция на действие пользователя мы не получили, окно перерисоваться не может.
Как то так :)
leonid_10
Я обязательно приму к рассмотрению ваши замечания, но хочу сказать, что моё GUI как таковым является постольку поскольку. Это всего лишь окно за наблюдением устанавливаемых слайдерами и спинбоксами с текстконтролами параметров. Здесь не нужно будет ничего рисовать и совершать прочие манипуляции мышью в кадре. Если вы проверите дееспособность скрипта у себя на компе, то увидите, что никакого зависания не наблюдается, всё проходит по установленному времени. Насколько я понимаю, проблема в данном случае не со sleep, а с тем, что не определена функция обновления полотна с началом нового цикла. Буду ковырять примеры, ибо english у меня неадекватный относительно документации. Мне нужны оба варианта: if refresh() else
leonid_10
В wxPython-demo есть samples, а в них roses. Фактически, мне нужно разобрать эту программу по косточкам, и всё станет ясно.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB