diff --git a/component/button.py b/component/button.py index 9b072bb..aaf6760 100644 --- a/component/button.py +++ b/component/button.py @@ -1,11 +1,27 @@ -from PyQt6.QtWidgets import QPushButton +from PyQt6.QtWidgets import QPushButton,QApplication,QPushButton, QLabel, QVBoxLayout, QApplication +from PyQt6.QtCore import QSize,Qt +from PyQt6.QtGui import QIcon from PyQt6.QtCore import QSize + class SquareButton(QPushButton): - def __init__(self, icon, parent=None): - super().__init__(icon, "", parent) + def __init__(self, icon, text, parent=None): + super().__init__("", parent) # Initialize without text + + # Create the icon and text label + self.icon_label = QLabel() + self.icon_label.setPixmap(icon.pixmap(50, 50)) # Set icon size + self.text_label = QLabel(text) + self.setFixedSize(100, 100) + # Create a vertical layout to stack icon and text + layout = QVBoxLayout() + layout.addWidget(self.icon_label) + layout.addWidget(self.text_label) + self.setLayout(layout) - def sizeHint(self): - size = super(SquareButton, self).sizeHint() - dimension = max(size.width(), size.height()) - return QSize(dimension, dimension) + # def sizeHint(self): + # screen = QApplication.screens()[0] + # screen_size = screen.availableGeometry() + # # Calculate the button size based on screen size + # button_size = screen_size.width() / 10 + # return QSize(button_size, button_size) \ No newline at end of file diff --git a/component/modal.py b/component/modal.py index a6aaa5c..71d911e 100644 --- a/component/modal.py +++ b/component/modal.py @@ -1,24 +1,26 @@ -from PyQt6.QtWidgets import QPushButton, QDialog, QHBoxLayout +from PyQt6.QtWidgets import QPushButton, QDialog, QHBoxLayout,QLabel,QVBoxLayout class ConfirmDialog(QDialog): - def __init__(self, parent=None): + def __init__(self,message, parent=None): super().__init__(parent) + self.message = message self.initUI() def initUI(self): self.setWindowTitle("Confirm") - - layout = QHBoxLayout() - + main_layout = QVBoxLayout() + button_layout = QHBoxLayout() + self.message_label = QLabel(self.message, self) # Label to display the message + main_layout.addWidget(self.message_label) confirm_btn = QPushButton("Confirm", self) confirm_btn.clicked.connect(self.confirm) - layout.addWidget(confirm_btn) + button_layout.addWidget(confirm_btn) cancel_btn = QPushButton("Cancel", self) cancel_btn.clicked.connect(self.cancel) - layout.addWidget(cancel_btn) - - self.setLayout(layout) + button_layout.addWidget(cancel_btn) + main_layout.addLayout(button_layout) + self.setLayout(main_layout) def confirm(self): self.accept() diff --git a/component/screen/end_screen.py b/component/screen/end_screen.py index c9bfef4..dcecd5a 100644 --- a/component/screen/end_screen.py +++ b/component/screen/end_screen.py @@ -2,6 +2,8 @@ import pandas as pd from PyQt6.QtWidgets import QWidget, QLabel, QPushButton, QVBoxLayout import logging +from PyQt6.QtCore import Qt + class EndScreen(QWidget,): def __init__(self,navigator,screen_height,screen_width, result): @@ -23,16 +25,22 @@ def initUI(self): # Thank you message thank_you_label = QLabel("Thank you for participating!", self) + + thank_you_label.setAlignment(Qt.AlignmentFlag.AlignCenter) + thank_you_label.setStyleSheet("font-size: 24px; font-weight: bold;") # Increase font size and make it bold layout.addWidget(thank_you_label) # Replay button replay_btn = QPushButton("Replay", self) replay_btn.clicked.connect(self.navigator.navigate_to_start_screen) + # settings_btn.setSizePolicy(QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Minimum) + replay_btn.setStyleSheet("background-color: green; color: white; font-size: 20px; padding: 10px;") layout.addWidget(replay_btn) # Quit button quit_btn = QPushButton("Quit", self) quit_btn.clicked.connect(self.navigator.close_all) + quit_btn.setStyleSheet("background-color: red; color: white; font-size: 20px; padding: 10px;") layout.addWidget(quit_btn) self.setLayout(layout) diff --git a/component/screen/setting_screen.py b/component/screen/setting_screen.py index 3657a7e..e290cf6 100644 --- a/component/screen/setting_screen.py +++ b/component/screen/setting_screen.py @@ -75,10 +75,4 @@ def confirm(self): def cancel(self): print("Reset cancelled") - # def navigate_main_screen(self): - # logging.info("Open the user start screen") - # self.next_screen = StartScreen(self.screen_height,self.screen_width) - # self.next_screen.show() - # self.close() - \ No newline at end of file diff --git a/component/screen/start_screen.py b/component/screen/start_screen.py index dcdac46..dcfb291 100644 --- a/component/screen/start_screen.py +++ b/component/screen/start_screen.py @@ -1,5 +1,5 @@ import logging -from PyQt6.QtWidgets import QWidget, QVBoxLayout, QPushButton,QLabel,QSizePolicy +from PyQt6.QtWidgets import QWidget, QVBoxLayout, QPushButton,QLabel,QSizePolicy,QSpacerItem from PyQt6.QtCore import Qt class StartScreen(QWidget): @@ -16,12 +16,14 @@ def initUI(self): logging.info("Setting up UI for StartScreen") layout = QVBoxLayout() - + spacer_left = QSpacerItem(40, 20, QSizePolicy.Policy.Expanding,QSizePolicy.Policy.Expanding) + spacer_right = QSpacerItem(40, 20, QSizePolicy.Policy.Expanding,QSizePolicy.Policy.Expanding) + layout.addItem(spacer_left) # Add stretch to center the widgets vertically layout.addStretch() # Title - title = QLabel("Quiz Experiment", self) + title = QLabel("PAMSimulator", self) title.setAlignment(Qt.AlignmentFlag.AlignCenter) title.setStyleSheet("font-size: 24px; font-weight: bold;") # Increase font size and make it bold layout.addWidget(title) @@ -29,19 +31,19 @@ def initUI(self): # Start button start_btn = QPushButton("Start", self) start_btn.clicked.connect(self.navigator.navigate_to_user_info_screen) - start_btn.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding) + start_btn.setSizePolicy(QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Minimum) start_btn.setStyleSheet("background-color: green; color: white; font-size: 20px; padding: 10px;") layout.addWidget(start_btn) # Settings button settings_btn = QPushButton("Settings", self) settings_btn.clicked.connect(self.navigator.navigate_to_setting_screen) - settings_btn.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding) + settings_btn.setSizePolicy(QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Minimum) settings_btn.setStyleSheet("background-color: gray; color: white; font-size: 20px; padding: 10px;") layout.addWidget(settings_btn) # Add another stretch to ensure buttons are centered layout.addStretch() - + layout.addItem(spacer_right) self.setLayout(layout) self.setWindowTitle('Start Screen') \ No newline at end of file diff --git a/component/screen/test_screen.py b/component/screen/test_screen.py index 7bcdeb6..44e96b0 100644 --- a/component/screen/test_screen.py +++ b/component/screen/test_screen.py @@ -6,6 +6,8 @@ import random from PyQt6.QtWidgets import QWidget, QLabel, QPushButton, QVBoxLayout,QProgressBar,QSizePolicy,QHBoxLayout,QSpacerItem, QGridLayout from PyQt6.QtGui import QIcon +from PyQt6.QtCore import Qt,QSize +from typing import List import logging from pydub.playback import play @@ -21,17 +23,18 @@ def __init__(self,navigator, screen_height, screen_width): self.navigator = navigator self.screen_height = screen_height self.screen_width = screen_width - self.resize(screen_width, screen_height) + self.resize(screen_height,screen_width) + self.keyboard_list:List[QPushButton] = [] + self.similarities_list = [] self.setWindowTitle("Test Screen") logging.info("Initializing TestScreen") + self.initUI() - self.answerList = self.loadQuestion(audio_dir) - self.current_index = 0 + self.answerList:List[Answer] = self.loadQuestion(audio_dir) + self.current_index:int = 0 self.updateProcess() self.update_button_states() - self.answerList = self.loadQuestion(audio_dir) - self.current_index = 0 def initUI(self): logging.info("Setting up UI for TestScreen") @@ -41,42 +44,53 @@ def initUI(self): #Grid 1: Audio and Progress grid1_layout = QHBoxLayout() grid1_1_layout = QVBoxLayout() - grid1_1_layout.setSpacing(0) self.progress_label = QLabel("Test Number: 0/0") + self.progress_label.setSizePolicy(QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Minimum) grid1_1_layout.addWidget(self.progress_label) - self.progress_bar = QProgressBar(self) - grid1_1_layout.addWidget(self.progress_bar) - - - self.playSoundButton = QPushButton("Play Sound") + # self.progress_bar = QProgressBar(self) + # grid1_1_layout.addWidget(self.progress_bar) - self.playSoundButton = SquareButton(QIcon(volume_icon), self) + self.playSoundButton = SquareButton(QIcon(volume_icon), "Play Sound",self) self.playSoundButton.clicked.connect(self.play_sound) + self.playSoundButton.setSizePolicy(QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Minimum) grid1_layout.addWidget(self.playSoundButton) - grid1_layout.addLayout(grid1_1_layout) + + grid1_layout.addLayout(grid1_1_layout) + main_layout.addItem(QSpacerItem(0, 0, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Minimum)) + main_layout.addLayout(grid1_layout) - + grid2_layout = QHBoxLayout(self) self.bofomo_consonants_grid = QGridLayout() self.bofomo_consonants_grid.setHorizontalSpacing(0) self.bofomo_consonants_grid.setVerticalSpacing(0) + button_size = QSize(80, 80) # Adjust the size as needed + for i, text in enumerate(pofomopo_consonants): button = QPushButton(str(text), self) + self.keyboard_list.append(button) button.clicked.connect(lambda checked, text=text: self.bofomo_consonant_action(text)) + button.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed) + button.setMinimumSize(button_size) row, col = divmod(i, 5) self.bofomo_consonants_grid.addWidget(button, row, col) grid2_layout.addLayout(self.bofomo_consonants_grid) - # Create grid layout for similarities self.similarities_grid = QGridLayout() + button_size = QSize(80, 80) # Adjust the size as needed for i, text in enumerate(similarity_list): button = QPushButton(str(text), self) + self.similarities_list.append(button) button.clicked.connect(lambda checked, text=text: self.similarity_action(text)) + button.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed) + button.setMinimumSize(button_size) row, col = divmod(i, 1) self.similarities_grid.addWidget(button, row, col) + spacer = QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum) + grid2_layout.addItem(spacer) grid2_layout.addLayout(self.similarities_grid) main_layout.addLayout(grid2_layout) @@ -101,13 +115,13 @@ def initUI(self): grid3.addLayout(grid_3_1) # Add the horizontal layout to the main layout + main_layout.addItem(QSpacerItem(0, 0, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)) main_layout.addLayout(grid3) - self.setLayout(main_layout) - self.setWindowTitle('TestScreen') - + self.setLayout(main_layout) + self.setWindowTitle('TestScreen') def next_question(self): self.current_index += 1 @@ -120,11 +134,11 @@ def previous_question(self): self.updateProcess() def play_sound(self): - current_question = self.answerList[self.current_index] + current_question:Answer = self.answerList[self.current_index] play(current_question.get_question()) - def loadQuestion(self, audio_dir): + def loadQuestion(self, audio_dir)->List[Answer]: question_df = dataHandaler.get_exam() quetionList = [] for index, row in question_df.iterrows(): @@ -144,8 +158,21 @@ def update_button_states(self): self.previousButton.setVisible(not is_first_question) self.nextButton.setVisible(not is_last_question) - current_question = self.answerList[self.current_index] - + current_question:Answer = self.answerList[self.current_index] + for button in self.keyboard_list: + if button.text() == current_question.get_answer(): + self.update_button_style(button) + else: + self.reset_button_style(button) + for button in self.similarities_list: + if button.text() == current_question.get_similarity(): + self.update_button_style(button) + else: + self.reset_button_style(button) + + print(current_question.get_answer()) + print(current_question.get_similarity()) + def handling_submit_button(self): self.submit_test() self.navigator.navigate_to_end_screen() @@ -162,11 +189,11 @@ def updateProcess(self): self.progress_label.setText(f"Test Number: {self.current_index + 1}/{len(self.answerList)}") # Update the progress bar - if len(self.answerList) > 0: - progress_value = int((self.current_index + 1) / len(self.answerList) * 100) - self.progress_bar.setValue(progress_value) - else: - self.progress_bar.setValue(0) + # if len(self.answerList) > 0: + # progress_value = int((self.current_index + 1) / len(self.answerList) * 100) + # self.progress_bar.setValue(progress_value) + # else: + # self.progress_bar.setValue(0) # self.progress.set_text("Test Number:{}/{}".format(self.current_index+1,len(self.answerList))) # Action for BofoMo consonants @@ -179,4 +206,11 @@ def bofomo_consonant_action(self, button_index): def similarity_action(self, button_index): current_question = self.answerList[self.current_index] current_question.set_similarity(button_index) - # self.similarities_list.updateState(button_index) \ No newline at end of file + # self.similarities_list.updateState(button_index) + + + def update_button_style(self, button): + button.setStyleSheet("background-color: #D3D3D3") + + def reset_button_style(self, button): + button.setStyleSheet("") \ No newline at end of file diff --git a/component/screen/user_information_screen.py b/component/screen/user_information_screen.py index ac85737..a46c2b1 100644 --- a/component/screen/user_information_screen.py +++ b/component/screen/user_information_screen.py @@ -16,7 +16,6 @@ def __init__(self,navigator,screen_height:int,screen_width:int): def initUI(self)->None: logging.info("Setting up UI for StartScreen") layout = QVBoxLayout() - # Labels and fields self.fields = { "中文姓名": QLineEdit(self), "英文姓名": QLineEdit(self), @@ -46,7 +45,7 @@ def save_data(self): print("User Info Saved:", user_info) def show_confirm_dialog(self): - dialog = ConfirmDialog(self) + dialog = ConfirmDialog("save the information?",self) result = dialog.exec() if result == QDialog.DialogCode.Accepted: