помогите разобраться, все функции работают корректно. Вопрос с вставкой видео на задний фон, а вывод рамки и текста на передний, так чтобы у текста не было подложки. Не получается сделать
puthon 3.13.0
Package Version
------------------------- -----------
altgraph 0.17.4
colorama 0.4.6
configobj 5.0.9
contourpy 1.3.1
cycler 0.12.1
decorator 5.1.1
distlib 0.3.9
filelock 3.16.1
fonttools 4.55.0
iniconfig 2.0.0
keyboard 0.13.5
kiwisolver 1.4.7
matplotlib 3.9.2
numpy 2.1.3
packaging 24.2
pefile 2023.2.7
pillow 11.0.0
pip 23.2.1
platformdirs 4.3.6
pluggy 1.5.0
pprofile 2.2.0
py-heat 0.0.6
pyinstaller 6.11.1
pyinstaller-hooks-contrib 2024.10
pyparsing 3.2.0
pytest 8.3.3
python-dateutil 2.9.0.post0
python-qt5 0.1.10
pyusb 1.2.1
pywin32-ctypes 0.2.3
self 2020.12.3
setuptools 75.6.0
six 1.16.0
virtualenv 20.27.1
wxPython 4.2.2
Windows 11 23H2
puthon 3.13.0
Package Version
------------------------- -----------
altgraph 0.17.4
colorama 0.4.6
configobj 5.0.9
contourpy 1.3.1
cycler 0.12.1
decorator 5.1.1
distlib 0.3.9
filelock 3.16.1
fonttools 4.55.0
iniconfig 2.0.0
keyboard 0.13.5
kiwisolver 1.4.7
matplotlib 3.9.2
numpy 2.1.3
packaging 24.2
pefile 2023.2.7
pillow 11.0.0
pip 23.2.1
platformdirs 4.3.6
pluggy 1.5.0
pprofile 2.2.0
py-heat 0.0.6
pyinstaller 6.11.1
pyinstaller-hooks-contrib 2024.10
pyparsing 3.2.0
pytest 8.3.3
python-dateutil 2.9.0.post0
python-qt5 0.1.10
pyusb 1.2.1
pywin32-ctypes 0.2.3
self 2020.12.3
setuptools 75.6.0
six 1.16.0
virtualenv 20.27.1
wxPython 4.2.2
Windows 11 23H2
Python:
import json
import keyboard
import wx
import wx.media
import os
import time
import threading
class MyApp(wx.App):
def __init__(self):
super().__init__()
self.frame = None
def OnInit(self):
self.frame = MyFrame()
self.frame.ShowFullScreen(True) # Открыть окно в полноэкранном режиме
self.frame.SetWindowStyle(wx.STAY_ON_TOP) # Окно всегда сверху
return True
def enable_keys():
"""Разблокировать управляющие клавиши."""
for key in ['left', 'right', 'enter']:
keyboard.unblock_key(key)
def disable_keys():
"""Заблокировать управляющие клавиши."""
for key in ['left', 'right', 'enter']:
keyboard.block_key(key)
class MyFrame(wx.Frame):
def __init__(self):
super().__init__(None, title="Оплата игры", size=(1920, 1080))
# Основная панель
self.panel = wx.Panel(self)
self.panel.SetBackgroundColour(wx.Colour(0, 0, 0))
# Настройки
self.counter = 0
self.target_key = wx.WXK_SPACE
self.required_presses = 5 # Значение по умолчанию
self.load_config()
# Текстовые метки
self.label = self.create_label("Оплатите для старта", 40, wx.Colour(255, 0, 0))
self.counter_label = self.create_label(f"Оплата: {self.counter}/{self.required_presses}", 32, wx.Colour(255, 255, 255))
# Видео
self.media_ctrl = self.setup_video("demo.mp4")
# Слой с элементами интерфейса
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.sizer.Add(self.media_ctrl, 1, wx.EXPAND) # Видео на фоне
self.sizer.Add(self.label, 0, wx.ALIGN_CENTER) # Текст сверху
self.sizer.Add(self.counter_label, 0, wx.ALIGN_CENTER) # Счётчик сверху
self.panel.SetSizer(self.sizer)
# Добавить изображение-рамку поверх
self.frame_image = self.add_frame_image("ramka.png")
disable_keys() # Заблокировать клавиши
# События
self.Bind(wx.EVT_CHAR_HOOK, self.on_key_press)
self.panel.Bind(wx.EVT_SIZE, self.on_resize)
# Поток для мигающего текста
self.flashing_text_thread = threading.Thread(target=self.flash_text)
self.flashing_text_thread.daemon = True
self.flashing_text_thread.start()
def create_label(self, text, font_size, color):
"""Создать текстовую метку."""
label = wx.StaticText(self.panel, label=text, style=wx.ALIGN_CENTER)
label.SetFont(wx.Font(font_size, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD))
label.SetForegroundColour(color)
label.SetBackgroundColour(wx.Colour(0, 0, 0)) # Фон для предотвращения перекрытия видео
return label
def on_resize(self, event):
"""Обновить расположение элементов при изменении размера окна."""
size = self.panel.GetSize()
center_x = size[0] // 2
bottom_y = size[1] - 100 # Отступ 100px от нижнего края
# Переместить текстовые метки
self.label.SetPosition((center_x - self.label.GetSize()[0] // 2, bottom_y - 80))
self.counter_label.SetPosition((center_x - self.counter_label.GetSize()[0] // 2, bottom_y))
# Изменить размер рамки
if self.frame_image:
self.frame_image.SetSize(size)
event.Skip()
def on_key_press(self, event):
"""Обработать нажатие клавиш."""
key_code = event.GetKeyCode()
if key_code == self.target_key: # Пробел
self.counter += 1
self.update_counter_label()
if self.counter >= self.required_presses:
self.complete_payment()
elif key_code == ord('R'): # Клавиша 'R' для настроек
self.open_settings()
else:
event.Skip()
def update_counter_label(self):
"""Обновить метку счётчика оплаты."""
self.counter_label.SetLabel(f"Оплата: {self.counter}/{self.required_presses}")
def load_config(self):
"""Загрузить конфигурацию из файла."""
try:
with open('config.json') as f:
config = json.load(f)
self.required_presses = config.get('required_presses', 5)
self.counter = config.get('payment', 0)
except FileNotFoundError:
self.save_config()
def save_config(self):
"""Сохранить конфигурацию в файл."""
with open('config.json', 'w') as f:
json.dump({'required_presses': self.required_presses, 'payment': self.counter}, f)
def setup_video(self, video_path):
"""Настроить видео."""
if not os.path.exists(video_path):
raise FileNotFoundError(f"Файл видео '{video_path}' не найден!")
media_ctrl = wx.media.MediaCtrl(self.panel, style=wx.SIMPLE_BORDER)
if not media_ctrl.Load(video_path):
raise RuntimeError("Не удалось загрузить видео!")
media_ctrl.SetSize(1920, 1080)
media_ctrl.SetBackgroundColour(wx.Colour(0, 0, 0))
wx.CallLater(500, media_ctrl.Play) # Задержка перед воспроизведением
media_ctrl.Bind(wx.media.EVT_MEDIA_FINISHED, self.on_video_finished)
return media_ctrl
def on_video_finished(self):
"""Обработать завершение видео."""
self.media_ctrl.Seek(0)
self.media_ctrl.Play()
def add_frame_image(self, image_path):
"""Добавить изображение рамки."""
if not os.path.exists(image_path):
raise FileNotFoundError(f"Изображение рамки '{image_path}' не найдено!")
bitmap = wx.Bitmap(image_path, wx.BITMAP_TYPE_PNG)
static_bitmap = wx.StaticBitmap(self.panel, bitmap=bitmap)
static_bitmap.SetSize(self.GetSize())
static_bitmap.Raise()
return static_bitmap
def open_settings(self):
"""Открыть настройки для изменения количества нажатий."""
dlg = wx.TextEntryDialog(self, "Введите количество нажатий для разблокировки:", "Настройки")
if dlg.ShowModal() == wx.ID_OK:
try:
presses = int(dlg.GetValue())
if presses > 0:
self.required_presses = presses
self.save_config()
self.update_counter_label()
wx.MessageBox(f"Количество нажатий обновлено до {presses}.", "Настройки", wx.OK | wx.ICON_INFORMATION)
else:
wx.MessageBox("Число должно быть положительным!", "Ошибка", wx.OK | wx.ICON_ERROR)
except ValueError:
wx.MessageBox("Введите корректное число!", "Ошибка", wx.OK | wx.ICON_ERROR)
dlg.Destroy()
def flash_text(self):
"""Мигать текстом через интервал."""
while True:
time.sleep(1)
wx.CallAfter(self.toggle_flash_text)
def toggle_flash_text(self):
"""Переключить видимость мигающего текста."""
if self.label:
current_text = self.label.GetLabel()
if current_text == "Оплатите для старта":
self.label.SetLabel("")
else:
self.label.SetLabel("Оплатите для старта")
def complete_payment(self):
"""Завершить оплату и разблокировать клавиши."""
enable_keys()
wx.CallLater(500, self.close_application)
def close_application(self):
"""Закрыть приложение и сохранить состояние."""
self.counter -= self.required_presses
self.save_config()
self.Close()
if __name__ == "__main__":
app = MyApp()
app.MainLoop()
Вложения
Последнее редактирование: