Всех с наступающими праздниками! Надеюсь, каждый отдохнёт и восполнит силы за праздничные дни, а не будет зависать за очередными багами/фичами/обновлениями!
Помню, лет так 12 назад, когда я был ещё школьником, у всех моих знакомых стояла windows XP. И в моменты нового года у нас была традиция, скачать на каком-нибудь сайте новогоднюю ёлочку, которая запускается отдельной программой и просто на рабочем столе (либо на любом другом окне, если её открыть поверх окон) играет гифка с этой ёлочкой. Мелочь, но к новогоднему настроению она давала в те года +100 очков.
Если раньше такую штуку приходилось искать, где скачать, то теперь пришло время сделать всё самому.
Приступим к написанию своей версии "ёлочки"
Создание окна
Главная идея приложения такая: в правом углу приложения должна отображаться анимированная картинка, должна быть возможность перетянуть в любую точку экрана эту картинку, а также приложение не должно отображаться в панеле задач.
Для этого первым делом установим нужные библиотеки:
screeninfo - нужна для получения информации о мониторе
pygame - нужна для создания окна и отрисовки графики
pypiwin32 - понадобится в будущем для изменения отображения окна
P.s. большая часть объяснений будет представлена в коде
import pygame
from screeninfo import get_monitors
import os
# получаем информацию о мониторах
monitors = get_monitors()
# получаем данные о разрешении
screen_width = monitors[0].width
screen_height = monitors[0].height
print(screen_width, screen_height) # в моём случае вывод: 1920 1080
# -> создаем окно PyGame
pygame.init()
# сразу укажем, что окно должно открываться в левом верхнем углу экрана
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (0,0)
# размер окна - максимальный по нашим параметрам,
# pygame.NOFRAME - означает, что окно должно открываться без рамок
screen = pygame.display.set_mode([screen_width, screen_height], pygame.NOFRAME)
# Clock нужен быть для того, чтобы ограничить fps программы
# ограничение fps необходимо для того, чтобы сделать анимацию картинок более простой
Clock = pygame.time.Clock()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# закрашиваем окно в черный
screen.fill((0,0,0))
# обновляем экран
pygame.display.update()
# ограничиваем fps
Clock.tick(30)
Результатом выполнения этого кода станет черный экран (скрин не буду предоставлять, так как это бессмысленно). Первая часть программы выполнена.
Делаем прозрачный фон и убираем иконку из панели задач
Следующим шагом необходимо сделать фон программы полностью прозрачным, т.е. должны отображаться картинки, но при этом вокруг картинок должна быть возможность кликать по элементам рабочего стола (или другого окна).
Для этого нам поможет библиотека pypiwin32. Модифицируем немного код главного файла:
import pygame
from screeninfo import get_monitors
import os
import win32api
import win32con
import win32gui
# получаем информацию о мониторах
monitors = get_monitors()
# получаем данные о разрешении
screen_width = monitors[0].width
screen_height = monitors[0].height
# -> создаем окно PyGame
pygame.init()
# сразу укажем, что окно должно открываться в левом верхнем углу экрана
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (0,0)
# размер окна - максимальный по нашим параметрам,
# pygame.NOFRAME - означает, что окно должно открываться без рамок
screen = pygame.display.set_mode([screen_width, screen_height], pygame.NOFRAME)
# Clock нужен быть для того, чтобы ограничить fps программы
# ограничение fps необходимо для того, чтобы сделать анимацию картинок более простой
Clock = pygame.time.Clock()
running = True
# -> делаем прозрачный фон
# для этого определим цвет, который будет меняться на прозрачный
fuchsia = (255, 0, 128)
# получаем окно pygame
hwnd = pygame.display.get_wm_info()["window"]
# указываем параметры, какой цвет в программе должен меняться на прозрачный
win32gui.SetLayeredWindowAttributes(hwnd, win32api.RGB(*fuchsia), 0, win32con.LWA_COLORKEY)
# -> убираем с панели задач иконку программы
# для этого возьмем текущее окно, которое получили в hwnd = pygame.display.get_wm_info()["window"]
# указываем параметры для того, чтобы скрыть иконки
win32gui.SetWindowLong(hwnd, win32con.GWL_EXSTYLE,win32gui.GetWindowLong(hwnd, win32con.GWL_EXSTYLE)| win32con.WS_EX_TOOLWINDOW)
# -> Главный цикл программы
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# закрашиваем окно в тот цвет, который будет становиться прозрачным
screen.fill(fuchsia)
# обновляем экран
pygame.display.update()
# ограничиваем fps
Clock.tick(30)
Выполнив теперь код можно увидеть, что фон стал прозрачным (так как программа запущена, но ничего нет), а иконки программы в панеделе задач нет.
Начинаем работу с анимацией
Для того, чтобы отображать анимации понадобятся гифки. Но так как pygame сам по себе не отображает гифки, то необходимо каждую гифку преобразовать в набор картинок. Я скачал несколько гиф и преобразовал их в набор картинок при помощи бесплатных онлайн сервисов (так что эта часть не сама интересная). Однако, картинки получились с фоном. Что будет выглядеть не очень красиво на рабочем, так как ёлочка будет отображаться с фоном. Это легко изменить, открыв gimp и убрав у каждой картинки фон (сделав его прозрачным и сохранив в формате png).
Также каждую картинку я выровнял так, чтобы все они были 500х500 размером и сама картинка находилась в правом нижнем углу. В итоге для каждой картинки должна получиться папка с набором спрайтов: