Files
PyQt6_LaTaniere/src/mainwindow.py
2026-03-10 16:54:09 +01:00

214 lines
8.0 KiB
Python

import sys
import os
import webbrowser
from pathlib import Path
from PySide6 import QtGui
from PySide6.QtCore import Qt, QPropertyAnimation, QEasingCurve, QUrl, QResource
from PySide6.QtGui import QFontDatabase, QFont, QColor
from PySide6.QtUiTools import QUiLoader
from PySide6.QtWidgets import QMainWindow, QApplication, QGraphicsDropShadowEffect
from PySide6.QtMultimedia import QMediaPlayer, QAudioOutput
# Compile resources.qrc into resources_rc.py
# rcc -g python .\resources.qrc -o .\src\resources_rc.py
import resources as resources # This is generated from the .qrc file # noqa: F401
if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'):
bundle_dir = Path(sys._MEIPASS)
else:
bundle_dir = Path(__file__).resolve().parent.parent
# Remove this into final release
from fake_patch_notes import patch_note
NO_STAFF = True
CURRENT = os.path.dirname(os.path.realpath(__file__))
def load_custom_font() -> str:
# Load font from Qt resource
font_id = QFontDatabase.addApplicationFont(":/assets/Avocado-Cake-Demo.otf")
if font_id == -1:
raise RuntimeError("Failed to load font from resources.")
# Get the family name of the loaded font
font_families = QFontDatabase.applicationFontFamilies(font_id)
if not font_families:
raise RuntimeError("No font families found in the loaded font.")
return font_families[0]
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.ui = QUiLoader().load(f"{bundle_dir}/ui/mainwindow.ui", self)
central = self.ui.centralWidget()
self.setCentralWidget(central)
# # Remove the title bar and window frame
self.setWindowFlags(Qt.WindowType.FramelessWindowHint | Qt.WindowType.Window)
# # Optional: Make background transparent (if you want rounded corners, etc.)
self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground)
# Initialize audio
self.media_player = QMediaPlayer()
self.audio_output = QAudioOutput()
self.media_player.setAudioOutput(self.audio_output)
# USE RESOURCE
#file_path = os.path.join(f":/assets/the-beat-of-nature-122841.mp3")
self.media_player.setSource(QUrl.fromLocalFile(":/assets/the-beat-of-nature-122841.mp3"))
# Optionnel : Définir la valeur initiale du slider (ici: 10%)
self.ui.audio_volume_adjust.setValue(10)
self.audio_output.setVolume(0.1)
# Initialisation de la mémoire du volume (par défaut 10%)
self.previous_volume = 10
self.is_muted = False
# Connexion du Slider
self.ui.audio_volume_adjust.valueChanged.connect(self.update_volume)
# Lancer la lecture (par exemple ici, ou dans une fonction)
self.media_player.play()
# Track mouse position for dragging
self._drag_pos = None
if NO_STAFF :
self.ui.staff_btn.hide()
self.ui.spacer_substitution.hide()
self.ui.info_text.setMarkdown(patch_note)
# 1. Création de l'effet de lueur intense
self.ui.connexion_btn.glow = QGraphicsDropShadowEffect(self.ui.connexion_btn)
self.ui.connexion_btn.glow.setBlurRadius(20) # Point de départ
self.ui.connexion_btn.glow.setOffset(0, 0) # Centré
self.ui.connexion_btn.glow.setColor(QColor(255, 140, 0, 255)) # Orange pur (Alpha max)
#self.ui.connexion_btn.setGraphicsEffect(self.ui.connexion_btn.glow)
# 2. Animation du "Pulse" avec une grande amplitude
self.ui.connexion_btn.pulse_anim = QPropertyAnimation(self.ui.connexion_btn.glow, b"blurRadius")
self.ui.connexion_btn.pulse_anim.setDuration(1200) # Un peu plus rapide pour le dynamisme
self.ui.connexion_btn.pulse_anim.setStartValue(15) # Lueur de base
self.ui.connexion_btn.pulse_anim.setKeyValueAt(0.5, 70) # Lueur d'explosion (très large)
self.ui.connexion_btn.pulse_anim.setEndValue(15)
self.ui.connexion_btn.pulse_anim.setEasingCurve(QEasingCurve.InOutQuad)
self.ui.connexion_btn.pulse_anim.setLoopCount(-1)
#self.ui.connexion_btn.pulse_anim.start()
# Find the button by its objectName in Qt Designer
# Example: objectName = "close_btn"
self.ui.close_btn.clicked.connect(self.close)
self.ui.minimize_btn.clicked.connect(self.showMinimized)
self.ui.connexion_btn.clicked.connect(self.connexion_btn_link)
self.ui.discord_btn.clicked.connect(self.discord_btn_link)
self.ui.intranet_btn.clicked.connect(self.intranet_btn_link)
self.ui.mute_btn.clicked.connect(self.mute_btn_link)
#self.show()
# On centre la fenêtre avant de l'afficher
self.center_window()
self.show()
def center_window(self):
# On s'assure que la fenêtre a calculé sa taille
self.adjustSize()
screen = QtGui.QGuiApplication.screenAt(QtGui.QCursor.pos())
if not screen:
screen = QtGui.QGuiApplication.primaryScreen()
screen_geometry = screen.availableGeometry()
# On utilise frameGeometry() de la fenêtre elle-même
window_rect = self.frameGeometry()
window_rect.moveCenter(screen_geometry.center())
self.move(window_rect.topLeft())
# Mouse press event to start dragging
def mousePressEvent(self, event: QtGui.QMouseEvent) -> None:
if event.button() == Qt.MouseButton.LeftButton:
self._drag_pos = event.globalPosition().toPoint() - self.frameGeometry().topLeft()
super().mousePressEvent(event)
# Mouse move event to drag window
def mouseMoveEvent(self, event: QtGui.QMouseEvent) -> None:
if event.buttons() & Qt.MouseButton.LeftButton and self._drag_pos is not None:
self.move(event.globalPosition().toPoint() - self._drag_pos)
super().mouseMoveEvent(event)
# Mouse release event to stop dragging
def mouseReleaseEvent(self, event):
self._drag_pos = None
super().mouseReleaseEvent(event)
@staticmethod
def connexion_btn_link():
return None
@staticmethod
def discord_btn_link() -> None:
webbrowser.open('https://discord.gg/A7eanmSkp2')
return None
def intranet_btn_link(self) -> None:
webbrowser.open('https://la-taniere.fun/connexion/')
self.ui.connexion_btn.setGraphicsEffect(self.ui.connexion_btn.glow)
self.ui.connexion_btn.pulse_anim.start()
return None
def update_volume(self, value):
# 'value' est l'entier venant du slider (ex: 0 à 100)
# On convertit en float pour QAudioOutput (0.0 à 1.0)
volume = value / 100.0
self.audio_output.setVolume(volume)
def mute_btn_link(self) -> None:
if not self.is_muted:
# --- PASSAGE EN MUTE ---
# On sauvegarde la valeur actuelle du slider
self.previous_volume = self.ui.audio_volume_adjust.value()
# On met le volume à 0 (moteur audio + interface)
self.audio_output.setVolume(0.0)
self.ui.audio_volume_adjust.setValue(0)
# Optionnel : changer l'icône ou le style du bouton
self.ui.mute_btn.setStyleSheet("background-color: red;")
self.is_muted = True
else:
# --- RETOUR DU SON ---
# On restaure le volume précédent
volume_float = self.previous_volume / 100.0
self.audio_output.setVolume(volume_float)
self.ui.audio_volume_adjust.setValue(self.previous_volume)
# Optionnel : remettre le style d'origine
self.ui.mute_btn.setStyleSheet("")
self.is_muted = False
if __name__ == "__main__":
app = QApplication(sys.argv)
with open(f"{bundle_dir}/styles/styles.qss", 'r') as f:
style = f.read()
# Load and set the global font
custom_font = QFont(load_custom_font(), 16)
if custom_font:
app.setFont(custom_font)
# Set the stylesheet of the application
app.setStyleSheet(style)
window = MainWindow()
sys.exit(app.exec())