added MultipleChoiceQuestion and IntegerQuestion

This commit is contained in:
Faraphel 2023-12-23 18:17:08 +01:00
parent 445be46cd9
commit 660669ea89
8 changed files with 162 additions and 15 deletions

View file

@ -0,0 +1,57 @@
from typing import Any
from PyQt6.QtCore import Qt, pyqtSignal
from PyQt6.QtGui import QFont, QIntValidator
from PyQt6.QtWidgets import QVBoxLayout, QLabel, QDoubleSpinBox, QSpinBox
from source.survey.base import BaseSurvey
class IntegerQuestion(BaseSurvey):
def __init__(self, title: str, signals: dict[str, pyqtSignal] = None):
super().__init__()
self.signals = signals if signals is not None else {}
# set layout
self._layout = QVBoxLayout()
self.setLayout(self._layout)
# question title
self.label_question = QLabel()
self._layout.addWidget(self.label_question)
self.label_question.setText(title)
self.label_question.setAlignment(Qt.AlignmentFlag.AlignCenter)
font_title = self.label_question.font()
font_title.setPointSize(24)
font_title.setWeight(QFont.Weight.Bold)
self.label_question.setFont(font_title)
# response
self.entry_response = QSpinBox()
self.entry_response.setMinimum(13)
self.entry_response.setMaximum(200)
self.entry_response.setValue(30)
self._layout.addWidget(self.entry_response)
@classmethod
def from_dict(cls, data: dict[str, Any], signals: dict[str, pyqtSignal]) -> "IntegerQuestion":
return cls(
title=data["title"],
signals=signals,
)
# events
def on_show(self) -> None:
# immediately mark the survey as successful
if "success" in self.signals:
self.signals["success"].emit() # NOQA: emit exist
# data collection
def get_collected_data(self) -> dict:
return {
"value": self.entry_response.value()
}

View file

@ -0,0 +1,94 @@
from typing import Any
from PyQt6.QtCore import Qt, pyqtSignal
from PyQt6.QtGui import QFont
from PyQt6.QtWidgets import QFrame, QVBoxLayout, QLabel, QCheckBox, QLineEdit
from source.survey.base import BaseSurvey
class MultipleChoiceQuestion(BaseSurvey):
def __init__(
self,
title: str,
choices: dict[Any, str],
other_choice: bool = None,
signals: dict[str, pyqtSignal] = None
):
super().__init__()
self.other_choice = other_choice if other_choice is not None else None
self.signals = signals if signals is not None else {}
# set layout
self._layout = QVBoxLayout()
self.setLayout(self._layout)
# question title
self.label_question = QLabel()
self._layout.addWidget(self.label_question)
self.label_question.setText(title)
self.label_question.setAlignment(Qt.AlignmentFlag.AlignCenter)
font_title = self.label_question.font()
font_title.setPointSize(24)
font_title.setWeight(QFont.Weight.Bold)
self.label_question.setFont(font_title)
# responses
self.frame_responses = QFrame()
self._layout.addWidget(self.frame_responses)
self._layout_responses = QVBoxLayout()
self.frame_responses.setLayout(self._layout_responses)
self.button_responses: dict[str, QCheckBox] = {}
for choice_id, choice_text in choices.items():
# create a radio button for that choice
button = QCheckBox()
button.setText(choice_text)
# add the button to the frame
self._layout_responses.addWidget(button)
# save the button
self.button_responses[choice_id] = button
if self.other_choice:
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.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]) -> "MultipleChoiceQuestion":
return cls(
title=data["title"],
choices=data["choices"],
other_choice=data.get("other_choice"),
signals=signals,
)
def on_show(self) -> None:
if "success" in self.signals:
# the user can skip a text whenever he wants to, directly signal a success
self.signals["success"].emit() # NOQA: emit exist
def _on_response_other_check(self):
# refresh the other entry response status
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
)
}

View file

@ -7,7 +7,7 @@ from PyQt6.QtWidgets import QFrame, QVBoxLayout, QLabel, QRadioButton, QButtonGr
from source.survey.base import BaseSurvey from source.survey.base import BaseSurvey
class ChoiceQuestion(BaseSurvey): class SingleChoiceQuestion(BaseSurvey):
def __init__(self, title: str, choices: dict[Any, str], signals: dict[str, pyqtSignal]): def __init__(self, title: str, choices: dict[Any, str], signals: dict[str, pyqtSignal]):
super().__init__() super().__init__()
@ -51,7 +51,7 @@ class ChoiceQuestion(BaseSurvey):
self.group_responses.addButton(button, int(choice_id)) self.group_responses.addButton(button, int(choice_id))
@classmethod @classmethod
def from_dict(cls, data: dict[str, Any], signals: dict[str, pyqtSignal]) -> "ChoiceQuestion": def from_dict(cls, data: dict[str, Any], signals: dict[str, pyqtSignal]) -> "SingleChoiceQuestion":
return cls( return cls(
title=data["title"], title=data["title"],
choices=data["choices"], choices=data["choices"],

View file

@ -1,7 +1,9 @@
from .Empty import Empty from .Empty import Empty
from .Text import Text from .Text import Text
from .ChoiceQuestion import ChoiceQuestion from .SingleChoiceQuestion import SingleChoiceQuestion
from .MultipleChoiceQuestion import MultipleChoiceQuestion
from .TextQuestion import TextQuestion from .TextQuestion import TextQuestion
from .IntegerQuestion import IntegerQuestion
from .WebMission import WebMission from .WebMission import WebMission
from .get import survey_get from .get import survey_get

View file

@ -2,7 +2,7 @@ from typing import Type
from PyQt6.QtCore import pyqtSignal from PyQt6.QtCore import pyqtSignal
from . import Text, ChoiceQuestion, WebMission, Empty, TextQuestion from . import Text, SingleChoiceQuestion, MultipleChoiceQuestion, WebMission, Empty, TextQuestion, IntegerQuestion
from .base import BaseSurvey from .base import BaseSurvey
@ -11,8 +11,10 @@ all_survey: dict[str, Type[BaseSurvey]] = {
"empty": Empty, "empty": Empty,
"text": Text, "text": Text,
# questions # questions
"question-choice": ChoiceQuestion, "question-single-choice": SingleChoiceQuestion,
"question-multiple-choice": MultipleChoiceQuestion,
"question-text": TextQuestion, "question-text": TextQuestion,
"question-integer": IntegerQuestion,
# missions # missions
"mission-web": WebMission, "mission-web": WebMission,
} }

View file

@ -29,8 +29,6 @@ class FrameSurvey(QFrame):
self.signal_success.connect(self._on_signal_success) # NOQA: connect exist self.signal_success.connect(self._on_signal_success) # NOQA: connect exist
# prepare the survey collected data # prepare the survey collected data
self.survey_name = None
self.collected_data_url = None
self.collected_datas: dict[str, dict] = {"time": time.time(), "surveys": {}} self.collected_datas: dict[str, dict] = {"time": time.time(), "surveys": {}}
self.survey_screens: list[tuple[str, BaseSurvey]] = [] self.survey_screens: list[tuple[str, BaseSurvey]] = []
self.current_survey_index = 0 self.current_survey_index = 0
@ -91,9 +89,6 @@ class FrameSurvey(QFrame):
with open(survey_path, encoding="utf-8") as file: with open(survey_path, encoding="utf-8") as file:
surveys_data = json.load(file) surveys_data = json.load(file)
self.survey_name = surveys_data.get("name")
self.collected_data_url = surveys_data.get("collected_data_url")
self.survey_screens = [ self.survey_screens = [
( (
survey_id, survey_id,

View file

@ -12,6 +12,6 @@ class MyMainWindow(QMainWindow):
super().__init__() super().__init__()
self.setWindowIcon(QIcon(str(icon_path.resolve()))) self.setWindowIcon(QIcon(str(icon_path.resolve())))
self.setWindowTitle("Sondage - Steam") self.setWindowTitle("Sondage")
self.setCentralWidget(widget.FrameSurvey("./surveys.json")) self.setCentralWidget(widget.FrameSurvey("./surveys.json"))

View file

@ -1,7 +1,4 @@
{ {
"name": "steam-navigation",
"collected_data_url": "http://127.0.0.1:8000/rest/university/recherche/survey/",
"surveys": { "surveys": {
"text-welcome": { "text-welcome": {
"type": "text", "type": "text",
@ -11,7 +8,7 @@
}, },
"question-usage": { "question-usage": {
"type": "question-choice", "type": "question-single-choice",
"title": "A quel point êtes-vous familier avec Steam ?", "title": "A quel point êtes-vous familier avec Steam ?",
"choices": { "choices": {
"0": "Ne connait pas", "0": "Ne connait pas",