wxPython проблема с видеофоном

Morcool

Новичок
Пользователь
Ноя 28, 2024
1
0
1
помогите разобраться, все функции работают корректно. Вопрос с вставкой видео на задний фон, а вывод рамки и текста на передний, так чтобы у текста не было подложки. Не получается сделать
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()
 

Вложения

  • Скриншот 28-11-2024 163814.jpg
    Скриншот 28-11-2024 163814.jpg
    277 КБ · Просмотры: 5
Последнее редактирование:

Форум IT Специалистов