Коротко про анімацію в wxPython
ag_fname = r"progress.gif"
ag = wx.animate.GIFAnimationCtrl(self, -1, ag_fname, pos=(0, 0), size=(64,64))
ag.GetPlayer().UseBackgroundColour(True)
ag.Play()
Дядечко робить анімацію на wxPython |
В wxPython засоби для роботи з анімацією - це пакет wx.animate. Пакет досить нехитрий - всього декілька класів, з яких частіше за все в роботі використовуються 2:
- wx.animate.Animation - інкапсулює параметри анімації, а також підтримує завантаження анімації з файлу. Підтримує Gif і Ani формати анімацій.
- wx.animate.GifAnimationCtrl - Контрол для рендера і Gif-анімації в графічному інтерфейсі додатку.
Останній - дуже класний засіб, оскільки дозволяє фактично в декілька рядків додати в вікно готовуу анімацію:
ag_fname = r"progress.gif"
ag = wx.animate.GIFAnimationCtrl(self, -1, ag_fname, pos=(0, 0), size=(64,64))
ag.GetPlayer().UseBackgroundColour(True)
ag.Play()
Досить непогано. І навіть більше ... прозорість.
Прозрачность
Третій рядок наведеного коду натякає нам, що анімація буде використовувати замість кольору, який в ній встановлений прозорим - фоновий колір вікна. Кажуть, що на GTK воно так і є, але я, на жаль, не міг в цьому переконатись, оскільки пишу софт, який дав натхнення на написання цієї сттаті, виключно для ОС Windows.
Що ж, на Windows воно чуть-чуть не зовсім так. У випадку, коли вікно, на якому знаходиться контрол має встановлений колір фону без додаткових надлишків - все прекрасно. Проблеми починаються тоді, коли на формі вручну через графічний контекст малюється картинка чи, форма взагалі не прямокутна, а довільного формату (на жаль, так вийшло, що це вій випадок).
В такому випадку GifAnimationCtrl тільки заважає, оскільки на нашій красивій формі вимальовується анімація з прямокутним сірим (ну, чи яким там у вас буде) фоном.
Выход есть
Що ж, відкидаємо контрол, беремо голу анімацію (благо wx.animate.Animation має всі засоби для отримання інформації про кадри, їх кількість і "прозорий" колір) і малюємо на необхідному вікне, користуючись DC (звісно ж BufferedDC, щоб уникнути неприємних блимань) і таймером. Все, що нам потрібно:
- wx.Timer
- wx.animate.Animation (.GetFrameCount(), .GetFrame(), ...)
- wx.BufferedDC
Єдине, що тут важливо, - метод GetFrame(frame_number) повертає не wx.Bitmap, який малюють, а wx.Image. Тому, щоб отримати картинку для малювання, потрібно зробити Animation.GetFrame(number).ConvertToBitmap().
При цьому, якщо вихідний файл анімації має прозорий колір, картинці навіть не потрібно робити SetMask(), маска будет створена виходячи з кадру і кольору прозорості. Код приводити не буду, в різних ситуаціях він може бути різним, але зміст, думаю, зрозумілий.
Коментарі
Дописати коментар