import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QLabel, QFrame, QPushButton, QGraphicsDropShadowEffect
from PyQt5.QtCore import Qt, QPoint, QPropertyAnimation, QEasingCurve, pyqtProperty, QTimer
from PyQt5.QtGui import QFont, QColor, QPainter, QPen, QPolygon
class LogoLabel(QLabel):
def __init__(self, text, info_widget):
super().__init__(text)
self.info_widget = info_widget
self._intensity = 0.0
self.shadow = QGraphicsDropShadowEffect(self)
self.shadow.setBlurRadius(0)
self.shadow.setColor(QColor(114, 137, 218, 0))
self.shadow.setOffset(0, 0)
self.setGraphicsEffect(self.shadow)
self.setStyleSheet("""
QLabel {
color: #7289da;
font-size: 36px;
font-weight: bold;
letter-spacing: 4px;
background: qlineargradient(x1:0, y1:0, x2:1, y2:0,
stop:0 #2a2f42, stop:1 #1a1e2c);
padding: 15px 30px;
border-radius: 15px;
border: 2px solid #505878;
}
""")
self.setAlignment(Qt.AlignCenter)
self.pulse_anim = QPropertyAnimation(self, b"intensity")
self.pulse_anim.setDuration(1350)
self.pulse_anim.setStartValue(0.65)
self.pulse_anim.setEndValue(1.0)
self.pulse_anim.setEasingCurve(QEasingCurve.InOutSine)
self.pulse_anim.setLoopCount(-1)
self.fade_anim = QPropertyAnimation(self, b"intensity")
self.fade_anim.setDuration(280)
self.fade_anim.setEasingCurve(QEasingCurve.OutCubic)
def get_intensity(self):
return self._intensity
def set_intensity(self, value):
self._intensity = max(0.0, min(1.0, float(value)))
blur = int(14 + 24 * self._intensity)
alpha = int(160 + 95 * self._intensity)
self.shadow.setBlurRadius(blur)
self.shadow.setColor(QColor(114, 137, 218, alpha))
intensity = pyqtProperty(float, fget=get_intensity, fset=set_intensity)
def enterEvent(self, event):
self.fade_anim.stop()
self.fade_anim.setStartValue(self._intensity)
self.fade_anim.setEndValue(1.0)
self.fade_anim.start()
QTimer.singleShot(300, self.start_pulse)
self.info_widget.start_line_animation(True)
super().enterEvent(event)
def start_pulse(self):
if self.underMouse():
self.pulse_anim.start()
def leaveEvent(self, event):
self.pulse_anim.stop()
self.fade_anim.stop()
self.fade_anim.setStartValue(self._intensity)
self.fade_anim.setEndValue(0.0)
self.fade_anim.start()
self.info_widget.start_line_animation(False)
super().leaveEvent(event)
class InfoWidget(QWidget):
def __init__(self):
super().__init__()
self._progress = 0.0
self.logo = None
self.buttons = []
self.setStyleSheet("background: transparent;")
self.line_anim = QPropertyAnimation(self, b"progress")
self.line_anim.setDuration(280)
self.line_anim.setEasingCurve(QEasingCurve.OutCubic)
def get_progress(self):
return self._progress
def set_progress(self, value):
self._progress = max(0.0, min(1.0, float(value)))
self.update()
progress = pyqtProperty(float, fget=get_progress, fset=set_progress)
def start_line_animation(self, appear):
self.line_anim.stop()
if appear:
self.line_anim.setStartValue(self._progress)
self.line_anim.setEndValue(1.0)
else:
self.line_anim.setStartValue(self._progress)
self.line_anim.setEndValue(0.0)
self.line_anim.start()
def paintEvent(self, event):
super().paintEvent(event)
if not self.logo or not self.buttons or self._progress < 0.01:
return
painter = QPainter(self)
painter.setRenderHint(QPainter.Antialiasing)
color = QColor(114, 137, 218)
color.setAlpha(int(255 * self._progress))
painter.setPen(QPen(color, 2.5, Qt.SolidLine))
painter.setBrush(color)
logo_center = self.logo.geometry().center()
arrow_size = 11
for btn in self.buttons:
btn_center = btn.geometry().center()
dx = btn_center.x() - logo_center.x()
dy = btn_center.y() - logo_center.y()
length = (dx**2 + dy**2)**0.5
if length < 30:
continue
ux = dx / length
uy = dy / length
offset_from_button = 26 if abs(dx) < 60 else 52
max_draw_len = length - offset_from_button
curr_len = max_draw_len * self._progress
if curr_len < 5:
continue
end_x = logo_center.x() + ux * curr_len
end_y = logo_center.y() + uy * curr_len
end_point = QPoint(int(round(end_x)), int(round(end_y)))
painter.drawLine(logo_center, end_point)
back_x = end_x - ux * arrow_size
back_y = end_y - uy * arrow_size
side = arrow_size * 0.45
px = -uy * side
py = ux * side
p1 = QPoint(int(round(back_x + px)), int(round(back_y + py)))
p2 = QPoint(int(round(back_x - px)), int(round(back_y - py)))
poly = QPolygon([end_point, p1, p2])
painter.drawPolygon(poly)
class AnimatedButton(QPushButton):
def __init__(self, text, parent=None):
super().__init__(text, parent)
self._bg_color = QColor(42, 47, 66)
self._hover_color = QColor(58, 64, 85)
self._pressed_color = QColor(30, 35, 50)
self._text_color = QColor(160, 164, 184)
self._hover_text_color = QColor(192, 196, 216)
self._pressed_text_color = QColor(128, 133, 156)
self.setFixedSize(120, 40)
self.setFont(QFont("Segoe UI", 9, QFont.Bold))
self.setCursor(Qt.PointingHandCursor)
self.color_animation = QPropertyAnimation(self, b"bg_color")
self.color_animation.setDuration(1000)
self.color_animation.setEasingCurve(QEasingCurve.OutCubic)
self.text_color_animation = QPropertyAnimation(self, b"text_color")
self.text_color_animation.setDuration(1000)
self.text_color_animation.setEasingCurve(QEasingCurve.OutCubic)
self.press_timer = QTimer()
self.press_timer.setSingleShot(True)
self.press_timer.timeout.connect(self.release_from_press)
self.update_stylesheet()
def get_bg_color(self):
return self._bg_color
def set_bg_color(self, color):
self._bg_color = color
self.update_stylesheet()
def get_text_color(self):
return self._text_color
def set_text_color(self, color):
self._text_color = color
self.update_stylesheet()
bg_color = pyqtProperty(QColor, fget=get_bg_color, fset=set_bg_color)
text_color = pyqtProperty(QColor, fget=get_text_color, fset=set_text_color)
def update_stylesheet(self):
bg_rgb = f"rgb({self._bg_color.red()}, {self._bg_color.green()}, {self._bg_color.blue()})"
text_rgb = f"rgb({self._text_color.red()}, {self._text_color.green()}, {self._text_color.blue()})"
hover_rgb = f"rgb({self._hover_color.red()}, {self._hover_color.green()}, {self._hover_color.blue()})"
pressed_rgb = f"rgb({self._pressed_color.red()}, {self._pressed_color.green()}, {self._pressed_color.blue()})"
self.setStyleSheet(f"""
QPushButton {{
background-color: {bg_rgb};
color: {text_rgb};
border: 1px solid #3d435b;
border-radius: 6px;
}}
QPushButton:hover {{
background-color: {hover_rgb};
border: 1px solid #5d6380;
}}
QPushButton:pressed {{
background-color: {pressed_rgb};
}}
""")
def enterEvent(self, event):
self.color_animation.stop()
self.color_animation.setStartValue(self._bg_color)
self.color_animation.setEndValue(self._hover_color)
self.color_animation.start()
self.text_color_animation.stop()
self.text_color_animation.setStartValue(self._text_color)
self.text_color_animation.setEndValue(self._hover_text_color)
self.text_color_animation.start()
super().enterEvent(event)
def leaveEvent(self, event):
self.color_animation.stop()
self.color_animation.setStartValue(self._bg_color)
self.color_animation.setEndValue(QColor(42, 47, 66))
self.color_animation.start()
self.text_color_animation.stop()
self.text_color_animation.setStartValue(self._text_color)
self.text_color_animation.setEndValue(QColor(160, 164, 184))
self.text_color_animation.start()
super().leaveEvent(event)
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
self.color_animation.stop()
self.color_animation.setStartValue(self._bg_color)
self.color_animation.setEndValue(self._pressed_color)
self.color_animation.start()
self.text_color_animation.stop()
self.text_color_animation.setStartValue(self._text_color)
self.text_color_animation.setEndValue(self._pressed_text_color)
self.text_color_animation.start()
self.press_timer.start(1000)
super().mousePressEvent(event)
def release_from_press(self):
if self.underMouse():
self.color_animation.stop()
self.color_animation.setStartValue(self._bg_color)
self.color_animation.setEndValue(self._hover_color)
self.color_animation.start()
self.text_color_animation.stop()
self.text_color_animation.setStartValue(self._text_color)
self.text_color_animation.setEndValue(self._hover_text_color)
self.text_color_animation.start()
else:
self.color_animation.stop()
self.color_animation.setStartValue(self._bg_color)
self.color_animation.setEndValue(QColor(42, 47, 66))
self.color_animation.start()
self.text_color_animation.stop()
self.text_color_animation.setStartValue(self._text_color)
self.text_color_animation.setEndValue(QColor(160, 164, 184))
self.text_color_animation.start()
def mouseReleaseEvent(self, event):
if event.button() == Qt.LeftButton:
self.press_timer.stop()
if self.underMouse():
self.color_animation.stop()
self.color_animation.setStartValue(self._bg_color)
self.color_animation.setEndValue(self._hover_color)
self.color_animation.start()
self.text_color_animation.stop()
self.text_color_animation.setStartValue(self._text_color)
self.text_color_animation.setEndValue(self._hover_text_color)
self.text_color_animation.start()
else:
self.color_animation.stop()
self.color_animation.setStartValue(self._bg_color)
self.color_animation.setEndValue(QColor(42, 47, 66))
self.color_animation.start()
self.text_color_animation.stop()
self.text_color_animation.setStartValue(self._text_color)
self.text_color_animation.setEndValue(QColor(160, 164, 184))
self.text_color_animation.start()
super().mouseReleaseEvent(event)
class DarkMenu(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowFlags(Qt.FramelessWindowHint)
self.setAttribute(Qt.WA_TranslucentBackground)
self.setFixedSize(500, 560)
self.setWindowOpacity(0.993)
self.oldPos = None
self.active_tab = None
self.underline_anim = None
central_widget = QWidget()
self.setCentralWidget(central_widget)
main_layout = QVBoxLayout(central_widget)
main_layout.setContentsMargins(12, 12, 12, 12)
main_layout.setSpacing(0)
background = QFrame()
background.setObjectName("background")
background.setStyleSheet("""
#background {
background: qlineargradient(x1:0, y1:0, x2:1, y2:1,
stop:0 #1a1e2c, stop:1 #2a2f42);
border-radius: 20px;
border: 1px solid #3d435b;
}
""")
bg_layout = QVBoxLayout(background)
bg_layout.setContentsMargins(20, 16, 20, 25)
bg_layout.setSpacing(18)
tabs_container = QFrame()
tabs_container.setFixedHeight(46)
tabs_container.setStyleSheet("QFrame { background: transparent; border: none; }")
tabs_layout = QHBoxLayout(tabs_container)
tabs_layout.setContentsMargins(8, 6, 8, 6)
tabs_layout.setSpacing(8)
self.underline = QFrame(tabs_container)
self.underline.setFixedSize(45, 2)
self.underline.setStyleSheet("background: #7289da; border-radius: 1px;")
self.underline.hide()
self.content_area = QFrame()
self.content_area.setStyleSheet("QFrame { background: transparent; border: none; }")
self.content_layout = QVBoxLayout(self.content_area)
self.content_layout.setContentsMargins(10, 10, 10, 10)
self.content_layout.setAlignment(Qt.AlignTop)
self.info_widget = InfoWidget()
info_layout = QVBoxLayout(self.info_widget)
info_layout.setContentsMargins(0, 20, 0, 0)
info_layout.setSpacing(40)
info_layout.setAlignment(Qt.AlignTop)
prolog_label = LogoLabel("PROLOG", self.info_widget)
buttons_layout = QHBoxLayout()
buttons_layout.setSpacing(16)
buttons_layout.setContentsMargins(0, 0, 0, 0)
btn_telegram = AnimatedButton("Telegram")
btn_buy = AnimatedButton("BUY")
btn_discord = AnimatedButton("Discord")
self.info_widget.logo = prolog_label
self.info_widget.buttons = [btn_telegram, btn_buy, btn_discord]
buttons_layout.addStretch()
buttons_layout.addWidget(btn_telegram)
buttons_layout.addWidget(btn_buy)
buttons_layout.addWidget(btn_discord)
buttons_layout.addStretch()
info_layout.addWidget(prolog_label, 0, Qt.AlignCenter)
info_layout.addLayout(buttons_layout)
info_layout.addStretch()
self.time_label = QLabel("ACTIVE v2.4.1")
self.time_label.setStyleSheet("""
QLabel {
color: #8d93b0;
font-size: 16px;
background: #1e2335;
padding: 8px 14px;
border-radius: 10px;
border: 1px solid #40486a;
min-width: 150px;
}
""")
self.time_label.setAlignment(Qt.AlignCenter)
tab_names = ["Aim", "NoRecoil", "InvHelper", "Setting", "Info"]
for name in tab_names:
btn = QPushButton(name)
btn.setFixedSize(78, 34)
btn.setProperty("tab_name", name)
btn.setStyleSheet("""
QPushButton {
background: #1e2335;
color: #c0c8e0;
border: 1px solid #40486a;
border-radius: 9px;
padding: 0 8px;
text-align: center;
}
QPushButton:hover {
background: #252b40;
color: #e8f0ff;
border: 1px solid #505878;
}
QPushButton:pressed {
background: #2c334d;
color: #ffffff;
}
QPushButton[active="true"] {
color: #ffffff;
border: 1px solid #60688a;
}
""")
btn.clicked.connect(lambda checked, b=btn: self.set_active_tab(b))
tabs_layout.addWidget(btn)
if name == "Info":
self.set_active_tab(btn, animate=False)
tabs_layout.addStretch()
bg_layout.addWidget(tabs_container)
bg_layout.addWidget(self.content_area)
status_layout = QHBoxLayout()
status_layout.setContentsMargins(0, 0, 0, 0)
status_layout.addStretch()
status_frame = QFrame()
status_frame.setFixedSize(105, 28)
status_frame.setStyleSheet("QFrame { background: #1e2335; border-radius: 7px; }")
frame_layout = QHBoxLayout(status_frame)
frame_layout.setContentsMargins(10, 0, 10, 0)
frame_layout.setSpacing(0)
status_text = QLabel("7D:4H:11M")
status_text.setStyleSheet("""
color: #8d93b0;
letter-spacing: 1px;
font-size: 14px;
""")
status_text.setAlignment(Qt.AlignCenter)
frame_layout.addWidget(status_text)
status_layout.addWidget(status_frame)
bg_layout.addLayout(status_layout)
main_layout.addWidget(background)
def set_active_tab(self, button, animate=True):
if self.active_tab == button:
return
if self.active_tab:
self.active_tab.setProperty("active", "false")
self.active_tab.setStyleSheet(self.active_tab.styleSheet())
button.setProperty("active", "true")
button.setStyleSheet(button.styleSheet())
target_x = button.x() + (button.width() - self.underline.width()) // 2
target_y = button.y() + button.height() + 3
self.underline.show()
if animate and self.underline.isVisible():
if self.underline_anim and self.underline_anim.state() == QPropertyAnimation.Running:
self.underline_anim.stop()
self.underline_anim = QPropertyAnimation(self.underline, b"pos")
self.underline_anim.setDuration(280)
self.underline_anim.setStartValue(self.underline.pos())
self.underline_anim.setEndValue(QPoint(target_x, target_y))
self.underline_anim.setEasingCurve(QEasingCurve.InOutQuad)
self.underline_anim.start()
else:
self.underline.move(target_x, target_y)
for i in range(self.content_layout.count()):
item = self.content_layout.itemAt(i)
if item.widget():
item.widget().hide()
if button.property("tab_name") == "Info":
self.info_widget.show()
if self.content_layout.indexOf(self.info_widget) == -1:
self.content_layout.addWidget(self.info_widget)
if self.content_layout.indexOf(self.time_label) == -1:
self.content_layout.addWidget(self.time_label, 0, Qt.AlignCenter)
self.content_layout.setAlignment(self.time_label, Qt.AlignBottom)
else:
self.time_label.show()
else:
placeholder = QLabel(f"{button.property('tab_name')} Content")
placeholder.setStyleSheet("color: #8d93b0; font-size: 16px;")
placeholder.setAlignment(Qt.AlignCenter)
self.content_layout.addWidget(placeholder)
placeholder.show()
self.active_tab = button
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
self.oldPos = event.globalPos()
def mouseMoveEvent(self, event):
if self.oldPos is not None:
delta = event.globalPos() - self.oldPos
self.move(self.x() + delta.x(), self.y() + delta.y())
self.oldPos = event.globalPos()
def mouseReleaseEvent(self, event):
self.oldPos = None
if __name__ == "__main__":
app = QApplication(sys.argv)
app.setStyle("Fusion")
window = DarkMenu()
window.show()
sys.exit(app.exec_())