Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added ___init___.py
Empty file.
16 changes: 11 additions & 5 deletions clickableGear.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import sys
import math

from PyQt6.QtWidgets import QGridLayout, QLabel, QPushButton, QSizePolicy
from PyQt6.QtGui import QPixmap, QCursor
from PyQt6 import QtCore
from PyQt6.QtCore import QTimer
from PyQt6.QtWidgets import QWidget
from PyQt6.QtCore import Qt, QRect, QPointF, pyqtSignal
from PyQt6.QtGui import QPainter, QColor, QPen, QFont, QPainterPath

class ClickableWidget(QWidget):
clicked = pyqtSignal(int) # signal to emit widget ID when clicked


def __init__(self, parent=None):
super().__init__(parent)

self.setWindowTitle("Questions in Topic Name")
self.setMinimumSize(700,750)

Expand All @@ -27,10 +32,11 @@ def __init__(self, parent=None):
self.gear_states=["unanswered"]*10

# positions for gears (adjusted for your window size)

positions = [
(74, 103),
(75, 164),
(191, 232),
(185, 232),
(177, 302),
(309, 370),
(301, 439),
Expand All @@ -39,7 +45,7 @@ def __init__(self, parent=None):
(574, 645),
(624, 705)
]

for i, (x, y) in enumerate(positions):
self.widgets.append({
'center': QPointF(x, y),
Expand All @@ -65,7 +71,7 @@ def setQuestions(self,questions):

def mark_gear_state(self, gear_id, state):
widget = self.widgets[gear_id]
widget["staet"]=state
widget["state"]=state
if state == "correct":
widget["color"] = QColor("#efbc50")
widget["enabled"] = False
Expand Down Expand Up @@ -233,4 +239,4 @@ def mouseMoveEvent(self, event):
needs_update = True

if needs_update:
self.update() # Trigger repaint
self.update() # Trigger repaint
40 changes: 40 additions & 0 deletions frame1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from PyQt6 import QtCore
from PyQt6.QtGui import QPixmap, QCursor
from PyQt6.QtWidgets import QLabel, QGridLayout, QWidget, QPushButton
from helperfunctions import grid, widgets, clear_stretch
from frames.frame2 import frame2


def frame1():
clear_stretch()

background = QLabel()
background.setPixmap(QPixmap("logo1.png"))
background.setScaledContents(True) # Makes image fill the whole window
widgets["background"] = [background]
grid.addWidget(background, 0, 0, 5, 5)

button = QPushButton("PLAY NOW!")
button.setCursor(QCursor(QtCore.Qt.CursorShape.PointingHandCursor))
button.clicked.connect(frame2)
button.setStyleSheet(
'''
*{
border: 1px solid '#262124';
border-radius: 15px;
font-size: 15px;
color: white;
padding: 15px 15px;
background-color: rgba(0, 0, 0, 80);
}
*:hover{
background-color: rgba(56, 53, 55, 180)
}
'''
)

widgets["button"].append(button)

grid.addWidget(button, 3, 0, 1, 5, QtCore.Qt.AlignmentFlag.AlignCenter)

# grid.addWidget(button, 3, 2, 1, 1, QtCore.Qt.AlignmentFlag.AlignCenter)
192 changes: 192 additions & 0 deletions frame2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
from PyQt6 import QtCore
from PyQt6.QtGui import QCursor
from PyQt6.QtWidgets import QGridLayout, QLabel, QPushButton, QWidget, QHBoxLayout
from helperfunctions import widgets, grid, progress, save_progress, clear_widgets
from frames.statsframe import frame_stats
from frames.gearpage import open_topic_window

def frame2():
clear_widgets()

#Back button
from frames.frame1 import frame1
button = QPushButton("⬅️")
button.setCursor(QCursor(QtCore.Qt.CursorShape.PointingHandCursor))
button.clicked.connect(frame1)
button.setStyleSheet(
'''
*{
border-radius: 70px;
font-size: 26px;
color: white;
padding: 0px 0px;
}
'''
)
widgets["button"].append(button)

grid.addWidget(button, 0, 0, 1, 1, QtCore.Qt.AlignmentFlag.AlignLeft)

# Title
title = QLabel("Choose Topic")
title.setStyleSheet('''
color: white;
font-family: "Arial";
font-size: 28px;
font-weight: bold;
margin-top: 40px;
''')
title.setAlignment(QtCore.Qt.AlignmentFlag.AlignLeft)
widgets["title"] = [title]
grid.addWidget(title, 1, 0, 1, 1)


# Score label (auto-updates)
score_label = QLabel(f"Score: {progress['score']}")
score_label.setStyleSheet('''
color: white;
font-family: "Arial";
font-size: 18px;
font-weight: bold;
margin-right:20px;
''')
score_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignRight)
widgets["score"] = [score_label]
#grid.addWidget(score_label, 1, 1, 1, 1)
grid.addWidget(score_label, 2, 1, QtCore.Qt.AlignmentFlag.AlignRight)

# Topics list
topics = [
"Fundamentals",
"Control Structures",
"Data Structures",
"Functions & Scope",
"OOP",
"Error & Exception Handling",
"File Handling",
"Advanced Topics"
]

unlocked = progress["unlocked_topics"]

# Topic buttons
for i, topic in enumerate(topics):
button = QPushButton(topic)
button.setFixedHeight(90)
button.setCursor(QCursor(QtCore.Qt.CursorShape.PointingHandCursor))

if topic in progress["completed_topics"]:
# ✅ Completed topic
button.setEnabled(False)
button.setText("✅ " + topic)
button.setStyleSheet("""
QPushButton {
background-color: #4CAF50;
color: white;
border-radius: 15px;
font-size: 18px;
text-align: left;
padding-left: 15px;
}
""")
elif i < unlocked:
# 🟢 Unlocked topic
button.setStyleSheet("""
QPushButton {
background-color: #4fa3d1;
color: white;
border-radius: 15px;
font-size: 18px;
text-align: left;
padding-left: 15px;
}
QPushButton:hover {
background-color: #00C080;
}
""")
button.clicked.connect(lambda _, t=topic: open_topic_window(t))
else:
# 🔒 Locked topic
button.setEnabled(False)
button.setText("🔒 " + topic)
button.setStyleSheet("""
QPushButton {
background-color: #2e5a77;
color: #aaaaaa;
border-radius: 15px;
font-size: 18px;
text-align: left;
padding-left: 15px;
}
""")

grid.addWidget(button, i + 3, 0, 1, 2)


# ====RESET FUNCTION===
def reset_progress():
# Reset the JSON file
global progress
progress = {
"unlocked_topics": 1,
"score": 0,
"completed_topics": set(),
"topic_scores": {}
}

save_progress()

frame2()

# === RESET BUTTON ===
reset_btn = QPushButton("Reset Progress")
reset_btn.setCursor(QCursor(QtCore.Qt.CursorShape.PointingHandCursor))
reset_btn.setFixedHeight(50)
reset_btn.setStyleSheet("""
QPushButton {
color: white;
border-radius: 8px;
font-size: 18px;
background-color: #c97b37;
}
QPushButton:hover {
background-color: #956b48;
}
""")
reset_btn.clicked.connect(reset_progress)

#Statistics Button
stats_btn = QPushButton("📊")
stats_btn.setCursor(QCursor(QtCore.Qt.CursorShape.PointingHandCursor))
stats_btn.setFixedSize(40,40)
stats_btn.clicked.connect(frame_stats)
stats_btn.setStyleSheet("""
QPushButton {
color: white;
border-radius: 15px;
font-size: 40px;
}

""")
#grid.addWidget(stats_btn, len(topics) + 4, 0, 1, 2)


#grid.setRowStretch(len(topics) + 3, 2)
# Add to the grid, below the topics
#grid.addWidget(reset_btn, len(topics) + 3, 0, 1, 2)

grid.setRowStretch(len(topics) + 2, 2)

bottom_row = QWidget()
hbox = QHBoxLayout()
hbox.setContentsMargins(10, 10, 10, 10)
#hbox.setSpacing(20)

hbox.addWidget(stats_btn)
hbox.addWidget(reset_btn)

bottom_row.setLayout(hbox)
# Place stats button at the top-right
grid.addWidget(stats_btn, 0, 1, 1, 1, QtCore.Qt.AlignmentFlag.AlignRight)

grid.addWidget(bottom_row, len(topics) + 4, 0, 1, 2)
59 changes: 59 additions & 0 deletions frame3.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
from PyQt6 import QtCore
from PyQt6.QtGui import QCursor, QPixmap
from PyQt6.QtWidgets import QLabel,QPushButton
from helperfunctions import grid, widgets, clear_widgets, progress

#*********************************************
# FRAME 3 - WIN GAME
#*********************************************
def frame3():
clear_widgets()
#clear_widgets(widgets, grid)
#congradulations widget
message = QLabel("Your score is:")
message.setAlignment(QtCore.Qt.AlignmentFlag.AlignRight)
message.setStyleSheet(
"font-family: 'Shanti'; font-size: 25px; color: 'white'; margin: 100px 0px;"
)
widgets["message"].append(message)

#score widget
score = QLabel(str(progress["score"]))
score.setStyleSheet("font-size: 100px; color: #8FC740; margin: 0 75px 0px 75px;")
widgets["score"].append(score)

#go back to work widget
message2 = QLabel("Congratulations! You passed all the challenges!")
message2.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
message2.setStyleSheet(
"font-family: 'Shanti'; font-size: 30px; color: 'white'; margin-top:0px; margin-bottom:75px;"
)
widgets["message2"].append(message2)

#button widget
button = QPushButton('TRY AGAIN!')
button.setStyleSheet(
"*{background:'#BC006C'; padding:25px 0px; border: 1px solid '#BC006C'; color: 'white'; font-family: 'Arial'; font-size: 25px; border-radius: 40px; margin: 10px 300px;} *:hover{background:'#ff1b9e';}"
)
button.setCursor(QCursor(QtCore.Qt.CursorShape.PointingHandCursor))
from frames.frame2 import frame2
button.clicked.connect(frame2)

widgets["button"].append(button)

#logo widget
pixmap = QPixmap('logo_bottom.png')
logo = QLabel()
logo.setPixmap(pixmap)
logo.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
logo.setStyleSheet(
"padding :10px; margin-top:75px; margin-bottom: 20px;"
)
widgets["logo"].append(logo)

#place widgets on the grid
grid.addWidget(widgets["message"][-1], 2, 0)
grid.addWidget(widgets["score"][-1], 2, 1)
grid.addWidget(widgets["message2"][-1], 3, 0, 1, 2)
grid.addWidget(widgets["button"][-1], 4, 0, 1, 2)
grid.addWidget(widgets["logo"][-1], 5, 0, 2, 2)
Loading