

엔터를 치면 정답을 확인 -> 다음 문제로 넘어감
self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
→ 위젯 느낌 내려면 꼭 해야 하는 설정.
창 테두리 싹 없애고 항상 위에 떠 있게 만들 수 있음.
그리고 드래그 이동도 구현함.
진짜 위젯처럼 마우스로 꾹 누르고 이동 가능:
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
self.offset = event.pos()
def mouseMoveEvent(self, event):
if event.buttons() == Qt.LeftButton:
self.move(self.pos() + event.pos() - self.offset)
def apply_dark_theme(self):
dark_palette = QPalette()
dark_palette.setColor(QPalette.Window, QColor(30, 30, 30))
...
QApplication.instance().setPalette(dark_palette)
df = pd.read_excel(filepath)
self.current_quiz = random.choice(self.quiz_data)
이 프로젝트 핵심은 결국 엑셀로 문제 등록해서 내가 외우고 싶은 표현 넣는 거니까
표현/뜻/뉘앙스/예문 등을 엑셀에서 불러오고, 매번 랜덤 출제하도록 했다.
뭔가 반복 학습 자동화 느낌으로 편한듯?
self.answer_input.returnPressed.connect(self.check_answer)
→ 키보드만으로 퀴즈 진행 가능.
from PySide2.QtWidgets import QApplication, QWidget, QLabel, QPushButton, QLineEdit, QVBoxLayout, QDialog
from PySide2.QtGui import QPalette, QColor, QFont
from PySide2.QtCore import Qt, QPoint
import sys, random
from expression_loader import load_expressions
class QuizWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Daily English Quiz")
self.setFixedSize(350, 200)
self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint) # 창 프레임 제거 + 항상 위에
self.offset = QPoint() # 드래그 관련 속성
self.apply_dark_theme()
self.quiz_data = load_expressions("assets/english_sentenses.xlsx")
self.current_quiz = {}
# 문제 칸
self.meaning_label = QLabel()
self.meaning_label.setWordWrap(True)
self.meaning_label.setAlignment(Qt.AlignTop)
self.meaning_label.setFont(QFont("나눔 고딕", 12))
self.nuance_label = QLabel()
self.nuance_label.setWordWrap(True)
self.nuance_label.setAlignment(Qt.AlignTop)
self.nuance_label.setFont(QFont("D2Coding", 9))
self.nuance_label.setStyleSheet("color: #cc99ff;")
self.example_label = QLabel()
self.example_label.setFont(QFont("Courier New", 10))
self.example_label.setVisible(False) # 퀴즈 유형 따라 표시 유무
self.answer_input = QLineEdit()
self.answer_input.returnPressed.connect(self.check_answer)
self.answer_input.setStyleSheet("""
color: #ffffff; /* 입력 글자 색 */
background-color: #2e2e2e; /* 배경색 */
border: 1px solid #555;
""")
self.feedback_label = QLabel()
layout = QVBoxLayout()
layout.addWidget(self.meaning_label)
layout.addWidget(self.nuance_label)
layout.addWidget(self.example_label)
layout.addWidget(self.answer_input)
self.setLayout(layout)
self.next_question()
def apply_dark_theme(self):
dark_palette = QPalette()
dark_palette.setColor(QPalette.Window, QColor(30, 30, 30))
dark_palette.setColor(QPalette.WindowText, QColor(220, 220, 220))
dark_palette.setColor(QPalette.Base, QColor(45, 45, 45))
dark_palette.setColor(QPalette.Text, QColor(220, 220, 220))
dark_palette.setColor(QPalette.Button, QColor(50, 50, 50))
dark_palette.setColor(QPalette.ButtonText, QColor(200, 200, 200))
QApplication.instance().setPalette(dark_palette)
def check_answer(self):
user_input = self.answer_input.text().strip().lower()
correct = self.current_quiz['expression'].lower()
if user_input == correct:
message = ("✅ 정답입니다!")
else:
message = (f"❌ 틀렸습니다.\n정답은: {correct}")
dialog = ResultDialog(message, self)
dialog.exec_()
self.next_question()
def next_question(self):
self.current_quiz = random.choice(self.quiz_data)
self.meaning_label.setText(f"{self.current_quiz['meaning']}")
self.nuance_label.setText(f"{self.current_quiz['nuance']}")
self.example_label.setVisible(False) # 예문은 이 퀴즈에서는 비활성화
self.answer_input.clear()
self.feedback_label.setText("")
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
self.offset = event.pos()
def mouseMoveEvent(self, event):
if event.buttons() == Qt.LeftButton:
self.move(self.pos() + event.pos() - self.offset)
def keyPressEvent(self, event):
if event.key() == Qt.Key_Escape:
self.close()
class ResultDialog(QDialog):
def __init__(self, message, parent=None):
super().__init__(parent)
self.setWindowFlags(Qt.FramelessWindowHint | Qt.Dialog)
self.setStyleSheet("""
background-color: #2e2e2e;
color: #ffffff;
""")
self.setFixedSize(280, 150)
label = QLabel(message)
label.setFont(QFont("D2Coding", 9))
label.setAlignment(Qt.AlignCenter)
ok_button = QPushButton("OK")
ok_button.setStyleSheet("""
QPushButton {
background-color: #444;
color: white;
border: 1px solid #666;
padding: 5px;
}
QPushButton:hover {
background-color: #555;
}
""")
ok_button.clicked.connect(self.accept)
layout = QVBoxLayout()
layout.addWidget(label)
layout.addWidget(ok_button)
self.setLayout(layout)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = QuizWindow()
window.show()
sys.exit(app.exec_())
import pandas as pd
def load_expressions(filepath):
df = pd.read_excel(filepath)
expressions = []
for _, row in df.iterrows():
entry = {
"expression": str(row.get("표현", "")).strip(),
"meaning": str(row.get("의미", "")).strip(),
"nuance": str(row.get("뉘앙스", "")).strip()
}
expressions.append(entry)
return expressions
숙어 | 뜻 | 뉘앙스 | 예문1 | 예문2 의 형식으로 데이터 정리
데이터를 어디서 받아오면 좋을듯? 수작업으로 하기엔 손이 많이 간다.