diff --git a/source/survey/MultipleChoiceQuestion.py b/source/survey/MultipleChoiceQuestion.py index 7574ffa..ba397d5 100644 --- a/source/survey/MultipleChoiceQuestion.py +++ b/source/survey/MultipleChoiceQuestion.py @@ -12,12 +12,16 @@ class MultipleChoiceQuestion(BaseSurvey): self, title: str, choices: dict[Any, str], - other_choice: bool = None, + details_choice_enabled: bool = None, + details_choice_id: str = None, + details_choice_text: str = None, signals: dict[str, pyqtSignal] = None ): super().__init__() - self.other_choice = other_choice if other_choice is not None else None + self.details_choice_enabled = details_choice_enabled if details_choice_enabled is not None else None + self.details_choice_id = details_choice_id if details_choice_id is not None else None + self.details_choice_text = details_choice_text if details_choice_text is not None else None self.signals = signals if signals is not None else {} # set layout @@ -55,11 +59,11 @@ class MultipleChoiceQuestion(BaseSurvey): # save the button self.button_responses[choice_id] = button - if self.other_choice: + if self.details_choice_enabled: self.button_response_other = QCheckBox() self._layout_responses.addWidget(self.button_response_other) - self.button_response_other.setText("Autre") - self.button_response_other.clicked.connect(self._on_response_other_check) # NOQA: connect exist + self.button_response_other.setText(self.details_choice_text) + self.button_response_other.toggled.connect(self._on_response_other_check) # NOQA: connect exist self.entry_response_other = QLineEdit() self._layout_responses.addWidget(self.entry_response_other) @@ -70,7 +74,9 @@ class MultipleChoiceQuestion(BaseSurvey): return cls( title=data["title"], choices=data["choices"], - other_choice=data.get("other_choice"), + details_choice_enabled=data.get("details_choice_enabled"), + details_choice_id=data.get("details_choice_id"), + details_choice_text=data.get("details_choice_text"), signals=signals, ) @@ -85,10 +91,16 @@ class MultipleChoiceQuestion(BaseSurvey): self.entry_response_other.setEnabled(self.button_response_other.isChecked()) def get_collected_data(self) -> dict: - return { - "choice": {choice_id: button.isChecked() for choice_id, button in self.button_responses.items()}, - "other": ( - self.entry_response_other.text() if self.other_choice and self.button_response_other.isChecked() - else None - ) + collected_data = { + "choice": [ + choice_id + for choice_id, button in self.button_responses.items() + if button.isChecked() + ] } + + if self.details_choice_enabled: + collected_data["choice"].append(self.details_choice_id) + collected_data["other"] = self.entry_response_other.text() + + return collected_data diff --git a/source/survey/SingleChoiceQuestion.py b/source/survey/SingleChoiceQuestion.py index 6ae9c7c..112491c 100644 --- a/source/survey/SingleChoiceQuestion.py +++ b/source/survey/SingleChoiceQuestion.py @@ -2,15 +2,30 @@ from typing import Any from PyQt6.QtCore import Qt, pyqtSignal from PyQt6.QtGui import QFont -from PyQt6.QtWidgets import QFrame, QVBoxLayout, QLabel, QRadioButton, QButtonGroup +from PyQt6.QtWidgets import QFrame, QVBoxLayout, QLabel, QRadioButton, QButtonGroup, QLineEdit, QAbstractButton from source.survey.base import BaseSurvey class SingleChoiceQuestion(BaseSurvey): - def __init__(self, title: str, choices: dict[Any, str], signals: dict[str, pyqtSignal]): + def __init__( + self, + title: str, + details_choice_enabled: bool = None, + details_choice_id: str = None, + details_choice_text: str = None, + choices: dict[Any, str] = None, + signals: dict[str, pyqtSignal] = None + ): super().__init__() + self.details_choice_enabled = details_choice_enabled if details_choice_enabled is not None else None + self.details_choice_id = details_choice_id if details_choice_id is not None else None + self.details_choice_text = details_choice_text if details_choice_text is not None else None + + choices = choices if choices is not None else {} + signals = signals if signals is not None else {} + # set layout self._layout = QVBoxLayout() self.setLayout(self._layout) @@ -39,7 +54,7 @@ class SingleChoiceQuestion(BaseSurvey): # checking any button allow the user to go to the next step self.group_responses.buttonClicked.connect(signals["success"].emit) # NOQA: connect and emit exists - self.button_responses_id: dict[QRadioButton, str] = {} + self.button_responses_id: dict[QAbstractButton, str] = {} for choice_id, choice_text in choices.items(): # create a radio button for that choice @@ -53,16 +68,43 @@ class SingleChoiceQuestion(BaseSurvey): self.group_responses.addButton(button) self.button_responses_id[button] = choice_id + if self.details_choice_enabled: + self.button_response_other = QRadioButton() + self._layout_responses.addWidget(self.button_response_other) + self.button_responses_id[self.button_response_other] = self.details_choice_id + + self.button_response_other.setText(self.details_choice_text) + self.group_responses.addButton(self.button_response_other) + self.button_response_other.toggled.connect(self._on_response_other_check) # NOQA: connect exist + + self.entry_response_other = QLineEdit() + self._layout_responses.addWidget(self.entry_response_other) + self.entry_response_other.setEnabled(False) + @classmethod def from_dict(cls, data: dict[str, Any], signals: dict[str, pyqtSignal]) -> "SingleChoiceQuestion": return cls( title=data["title"], choices=data["choices"], + details_choice_enabled=data.get("details_choice_enabled"), + details_choice_id=data.get("details_choice_id"), + details_choice_text=data.get("details_choice_text"), signals=signals, ) def get_collected_data(self) -> dict: - return { - "choice": self.button_responses_id[self.group_responses.checkedButton()] + checked_button = self.group_responses.checkedButton() + + collected_data = { + "choice": self.button_responses_id[checked_button] if checked_button is not None else None, } + + if self.details_choice_enabled: + collected_data["other"] = self.entry_response_other.text() + + return collected_data + + def _on_response_other_check(self): + # refresh the other entry response status + self.entry_response_other.setEnabled(self.button_response_other.isChecked()) diff --git a/surveys.json b/surveys.json index a14d2cd..9ba56bb 100644 --- a/surveys.json +++ b/surveys.json @@ -1,25 +1,66 @@ { "surveys": { - "text-welcome": { + + "welcome": { "type": "text", "title": "Bienvenue !", - "description": "Nous réalisons une étude sur le logiciel Steam afin de déterminer son ergonomie.\nVous serez invité à naviguer sur la plateforme Steam d'une page à l'autre.", + "description": "Salut ...", "abandonable": true }, - "question-usage": { + "age": { + "type": "question-integer", + "title": "Quel est votre âge ?", + "default": 30, + "minimum": 13, + "maximum": 150 + }, + + "usage-steam": { "type": "question-single-choice", - "title": "A quel point êtes-vous familier avec Steam ?", + "title": "Utilisez-vous Steam ?", "choices": { - "0": "Ne connait pas", - "1": "Connait de nom", - "2": "Utilisation rare", - "3": "Utilisation moyenne", - "4": "Utilisation fréquente" + "always": "Tout le temps", + "often": "Souvent", + "sometime": "De temps en temps", + "rarely": "Rarement", + "never": "Jamais" } }, - "web-language": { + "usage-concurrent": { + "type": "question-multiple-choice", + "title": "Quel autre plateforme de jeu en ligne utilisez-vous ?", + "choices": { + "epic": "Epic Games Store", + "gog": "GOG", + "origin": "Origin", + "uplay": "Uplay", + "battle": "Battle.net" + }, + "details_choice_enabled": true, + "details_choice_id": "other", + "details_choice_text": "Autre" + }, + + "difficulty-before": { + "type": "question-single-choice", + "title": "Avez-vous déjà rencontré des difficultés particulières lors de votre utilisation de Steam ?", + "choices": { + "no": "Non" + }, + "details_choice_enabled": true, + "details_choice_id": "yes", + "details_choice_text": "Oui" + }, + + "mission-explanation": { + "type": "text", + "title": "Explication de l'Evaluation", + "description": "Vous allez devoir naviguer dans steam ..." + }, + + "mission-language": { "type": "mission-web", "title": "Changer la langue en français.", "url": "https://steampowered.com/", @@ -27,18 +68,35 @@ "skip_time": 60 }, - "web-point-shop": { - "type": "mission-web", - "title": "Rendez-vous sur la boutique des points.", - "url": "https://steampowered.com/", - "check": "true", - "skip_time": 90 - }, - "question-experience": { "type": "question-text", "title": "Qu'avez vous pensé de l'interface de Steam ?" + }, + + "difficulty-after": { + "type": "question-single-choice", + "title": "Avez-vous rencontré des difficultés particulières lors de ce test ?", + "choices": { + "no": "Non" + }, + "details_choice_enabled": true, + "details_choice_id": "yes", + "details_choice_text": "Oui" + }, + + "hardest-mission": { + "type": "question-single-choice", + "title": "Parmi les tâches, laquelle avez-vous trouvée la plus difficile ?", + "choices": { + "mission-language": "Changer la langue" + } + }, + + "comment": { + "type": "question-text", + "title": "Vous pouvez laisser un commentaire sur votre ressenti général (optionnel)" } + } }