added a proper language selection menu

This commit is contained in:
Faraphel 2024-01-01 11:30:08 +01:00
parent 4a8a80a206
commit 1ffcf5cdb8
17 changed files with 107 additions and 48 deletions

View file

@ -4,7 +4,7 @@
<context> <context>
<name>SurveyEngine</name> <name>SurveyEngine</name>
<message> <message>
<location filename="../../source/widget/SurveyEngine.py" line="177"/> <location filename="../../source/ui/SurveyEngine.py" line="177"/>
<source>WARNING</source> <source>WARNING</source>
<translation>Warning</translation> <translation>Warning</translation>
</message> </message>
@ -12,17 +12,17 @@
<context> <context>
<name>SurveyNavigation</name> <name>SurveyNavigation</name>
<message> <message>
<location filename="../../source/widget/SurveyNavigation.py" line="19"/> <location filename="../../source/ui/SurveyNavigation.py" line="19"/>
<source>ABANDON</source> <source>ABANDON</source>
<translation>Abandon</translation> <translation>Abandon</translation>
</message> </message>
<message> <message>
<location filename="../../source/widget/SurveyNavigation.py" line="29"/> <location filename="../../source/ui/SurveyNavigation.py" line="29"/>
<source>SKIP</source> <source>SKIP</source>
<translation>Skip</translation> <translation>Skip</translation>
</message> </message>
<message> <message>
<location filename="../../source/widget/SurveyNavigation.py" line="38"/> <location filename="../../source/ui/SurveyNavigation.py" line="38"/>
<source>NEXT</source> <source>NEXT</source>
<translation>Next</translation> <translation>Next</translation>
</message> </message>
@ -30,7 +30,7 @@
<context> <context>
<name>SurveyWindow</name> <name>SurveyWindow</name>
<message> <message>
<location filename="../../source/widget/SurveyWindow.py" line="16"/> <location filename="../../source/ui/SurveyWindow.py" line="17"/>
<source>SURVEY</source> <source>SURVEY</source>
<translation>Survey</translation> <translation>Survey</translation>
</message> </message>

View file

@ -4,7 +4,7 @@
<context> <context>
<name>SurveyEngine</name> <name>SurveyEngine</name>
<message> <message>
<location filename="../../source/widget/SurveyEngine.py" line="177"/> <location filename="../../source/ui/SurveyEngine.py" line="177"/>
<source>WARNING</source> <source>WARNING</source>
<translation>Atención</translation> <translation>Atención</translation>
</message> </message>
@ -12,17 +12,17 @@
<context> <context>
<name>SurveyNavigation</name> <name>SurveyNavigation</name>
<message> <message>
<location filename="../../source/widget/SurveyNavigation.py" line="19"/> <location filename="../../source/ui/SurveyNavigation.py" line="19"/>
<source>ABANDON</source> <source>ABANDON</source>
<translation>Abandonar</translation> <translation>Abandonar</translation>
</message> </message>
<message> <message>
<location filename="../../source/widget/SurveyNavigation.py" line="29"/> <location filename="../../source/ui/SurveyNavigation.py" line="29"/>
<source>SKIP</source> <source>SKIP</source>
<translation>Pasar</translation> <translation>Pasar</translation>
</message> </message>
<message> <message>
<location filename="../../source/widget/SurveyNavigation.py" line="38"/> <location filename="../../source/ui/SurveyNavigation.py" line="38"/>
<source>NEXT</source> <source>NEXT</source>
<translation>Siguiente</translation> <translation>Siguiente</translation>
</message> </message>
@ -30,7 +30,7 @@
<context> <context>
<name>SurveyWindow</name> <name>SurveyWindow</name>
<message> <message>
<location filename="../../source/widget/SurveyWindow.py" line="16"/> <location filename="../../source/ui/SurveyWindow.py" line="17"/>
<source>SURVEY</source> <source>SURVEY</source>
<translation>Encuesta</translation> <translation>Encuesta</translation>
</message> </message>

View file

@ -4,7 +4,7 @@
<context> <context>
<name>SurveyEngine</name> <name>SurveyEngine</name>
<message> <message>
<location filename="../../source/widget/SurveyEngine.py" line="177"/> <location filename="../../source/ui/SurveyEngine.py" line="177"/>
<source>WARNING</source> <source>WARNING</source>
<translation>Avertissement</translation> <translation>Avertissement</translation>
</message> </message>
@ -12,17 +12,17 @@
<context> <context>
<name>SurveyNavigation</name> <name>SurveyNavigation</name>
<message> <message>
<location filename="../../source/widget/SurveyNavigation.py" line="19"/> <location filename="../../source/ui/SurveyNavigation.py" line="19"/>
<source>ABANDON</source> <source>ABANDON</source>
<translation>Abandonner</translation> <translation>Abandonner</translation>
</message> </message>
<message> <message>
<location filename="../../source/widget/SurveyNavigation.py" line="29"/> <location filename="../../source/ui/SurveyNavigation.py" line="29"/>
<source>SKIP</source> <source>SKIP</source>
<translation>Passer</translation> <translation>Passer</translation>
</message> </message>
<message> <message>
<location filename="../../source/widget/SurveyNavigation.py" line="38"/> <location filename="../../source/ui/SurveyNavigation.py" line="38"/>
<source>NEXT</source> <source>NEXT</source>
<translation>Suivant</translation> <translation>Suivant</translation>
</message> </message>
@ -30,7 +30,7 @@
<context> <context>
<name>SurveyWindow</name> <name>SurveyWindow</name>
<message> <message>
<location filename="../../source/widget/SurveyWindow.py" line="16"/> <location filename="../../source/ui/SurveyWindow.py" line="17"/>
<source>SURVEY</source> <source>SURVEY</source>
<translation>Sondage</translation> <translation>Sondage</translation>
</message> </message>

17
main.py
View file

@ -1,29 +1,14 @@
import sys import sys
from PyQt6.QtCore import QTranslator, QLocale
from PyQt6.QtWidgets import QApplication from PyQt6.QtWidgets import QApplication
from source import translate from source.ui import SurveyWindow
from source import assets_path
from source.widget import SurveyWindow
if __name__ == "__main__": if __name__ == "__main__":
# create the application # create the application
application = QApplication(sys.argv) application = QApplication(sys.argv)
# get the user language
local = QLocale()
language_code: str = local.languageToCode(local.language(), QLocale.LanguageCodeType.ISO639)
# apply the language on the translator
translate.set_language(language_code)
# load the translator to support multiple languages
translator = QTranslator()
application.installTranslator(translator)
translator.load(str(assets_path / f"language/{language_code}.qm"))
# create the window # create the window
window = SurveyWindow("./surveys.json") window = SurveyWindow("./surveys.json")
window.show() window.show()

View file

@ -3,7 +3,7 @@ from pathlib import Path
assets_path = Path("./assets/") assets_path = Path("./assets/")
__appname__ = "Survey Engine" __appname__ = "Survey Engine"
__version__ = (1,0,0) __version__ = (1,0,2)
__str_version__ = ".".join(map(str, __version__)) __str_version__ = ".".join(map(str, __version__))
__author__ = "Faraphel" __author__ = "Faraphel"
__mail__ = "rc60650@hotmail.com" __mail__ = "rc60650@hotmail.com"

View file

@ -4,7 +4,7 @@ from PyQt6.QtCore import Qt, pyqtSignal
from PyQt6.QtGui import QFont from PyQt6.QtGui import QFont
from PyQt6.QtWidgets import QVBoxLayout, QLabel, QSpinBox from PyQt6.QtWidgets import QVBoxLayout, QLabel, QSpinBox
from source import translate, widget from source import translate, ui
from source.survey.base import BaseSurvey from source.survey.base import BaseSurvey
@ -47,7 +47,7 @@ class IntegerQuestion(BaseSurvey):
self._layout.addWidget(self.entry_response) self._layout.addWidget(self.entry_response)
# navigation # navigation
self.navigation = widget.SurveyNavigation(signals=signals) self.navigation = ui.SurveyNavigation(signals=signals)
self._layout.addWidget(self.navigation) self._layout.addWidget(self.navigation)
self.navigation.show_forward() self.navigation.show_forward()

View file

@ -4,7 +4,7 @@ from PyQt6.QtCore import Qt, pyqtSignal
from PyQt6.QtGui import QFont from PyQt6.QtGui import QFont
from PyQt6.QtWidgets import QVBoxLayout, QLabel from PyQt6.QtWidgets import QVBoxLayout, QLabel
from source import translate, widget from source import translate, ui
from source.survey.base import BaseSurvey from source.survey.base import BaseSurvey
@ -43,7 +43,7 @@ class Text(BaseSurvey):
self.label_description.setAlignment(Qt.AlignmentFlag.AlignCenter) self.label_description.setAlignment(Qt.AlignmentFlag.AlignCenter)
# navigation # navigation
self.navigation = widget.SurveyNavigation(signals=signals) self.navigation = ui.SurveyNavigation(signals=signals)
self._layout.addWidget(self.navigation) self._layout.addWidget(self.navigation)
self.navigation.show_forward() # always show forward self.navigation.show_forward() # always show forward

View file

@ -4,7 +4,7 @@ from PyQt6.QtCore import Qt, pyqtSignal
from PyQt6.QtGui import QFont from PyQt6.QtGui import QFont
from PyQt6.QtWidgets import QVBoxLayout, QLabel, QTextEdit from PyQt6.QtWidgets import QVBoxLayout, QLabel, QTextEdit
from source import translate, widget from source import translate, ui
from source.survey.base import BaseSurvey from source.survey.base import BaseSurvey
@ -34,7 +34,7 @@ class TextQuestion(BaseSurvey):
self._layout.addWidget(self.entry_response) self._layout.addWidget(self.entry_response)
# navigation # navigation
self.navigation = widget.SurveyNavigation(signals=signals) self.navigation = ui.SurveyNavigation(signals=signals)
self._layout.addWidget(self.navigation) self._layout.addWidget(self.navigation)
self.navigation.show_forward() self.navigation.show_forward()

View file

@ -5,7 +5,7 @@ from PyQt6.QtCore import Qt, QTimer, pyqtSignal, QUrl, QEvent, QObject, QPointF
from PyQt6.QtGui import QFont, QMouseEvent, QResizeEvent, QKeyEvent from PyQt6.QtGui import QFont, QMouseEvent, QResizeEvent, QKeyEvent
from PyQt6.QtWidgets import QLabel, QVBoxLayout, QSizePolicy from PyQt6.QtWidgets import QLabel, QVBoxLayout, QSizePolicy
from source import translate, widget from source import translate, ui
from source.survey.base import BaseSurvey from source.survey.base import BaseSurvey
@ -47,7 +47,7 @@ class WebMission(BaseSurvey):
self.label_title.setFont(font_title) self.label_title.setFont(font_title)
# web page # web page
self.browser = widget.Browser() self.browser = ui.Browser()
self._layout.addWidget(self.browser) self._layout.addWidget(self.browser)
self.browser.web.focusProxy().installEventFilter(self) # capture the event in eventFilter self.browser.web.focusProxy().installEventFilter(self) # capture the event in eventFilter
self.browser.web.urlChanged.connect(self._on_url_changed) # NOQA: connect exist self.browser.web.urlChanged.connect(self._on_url_changed) # NOQA: connect exist
@ -73,7 +73,7 @@ class WebMission(BaseSurvey):
self.browser.web.page().scrollPositionChanged.connect(self._on_scroll_position_changed) self.browser.web.page().scrollPositionChanged.connect(self._on_scroll_position_changed)
# navigation # navigation
self.navigation = widget.SurveyNavigation(signals=signals) self.navigation = ui.SurveyNavigation(signals=signals)
self._layout.addWidget(self.navigation) self._layout.addWidget(self.navigation)
# initialize the start time # initialize the start time

View file

@ -5,7 +5,7 @@ from PyQt6.QtCore import Qt, pyqtSignal
from PyQt6.QtGui import QFont from PyQt6.QtGui import QFont
from PyQt6.QtWidgets import QFrame, QVBoxLayout, QLabel, QButtonGroup, QLineEdit, QAbstractButton from PyQt6.QtWidgets import QFrame, QVBoxLayout, QLabel, QButtonGroup, QLineEdit, QAbstractButton
from source import translate, widget from source import translate, ui
from source.survey.base import BaseSurvey from source.survey.base import BaseSurvey
@ -54,7 +54,7 @@ class BaseChoiceQuestion(BaseSurvey):
self.label_question.setFont(font_title) self.label_question.setFont(font_title)
# prepare navigation # prepare navigation
self.navigation = widget.SurveyNavigation(signals=signals) self.navigation = ui.SurveyNavigation(signals=signals)
# responses # responses
self.frame_responses = QFrame() self.frame_responses = QFrame()

View file

@ -0,0 +1,67 @@
from typing import Callable
from PyQt6.QtCore import Qt, QLocale, QTranslator
from PyQt6.QtWidgets import QWidget, QLabel, QVBoxLayout, QComboBox, QApplication, QPushButton
from source import assets_path, translate
class LanguageSelection(QWidget):
def __init__(self, after: Callable):
super().__init__()
self.after = after
# layout
self._layout = QVBoxLayout()
self.setLayout(self._layout)
# title
self.title = QLabel()
self._layout.addWidget(self.title)
self.title.setText("Select your language.")
self.title.setAlignment(Qt.AlignmentFlag.AlignCenter)
# language selection
self.select_language = QComboBox()
self._layout.addWidget(self.select_language)
language_default = QLocale().language() # get the default locale
for i, language_file in enumerate((assets_path / "language").glob("*.qm")):
# add every translated language to the selection
language_code: str = language_file.stem
language = QLocale.codeToLanguage(language_code, QLocale.LanguageCodeType.ISO639)
self.select_language.addItem(language.name, language_code)
# if the added language is the default one, select it directly
if language == language_default:
self.select_language.setCurrentIndex(i)
# start button
self.button_start = QPushButton()
self._layout.addWidget(self.button_start)
self.button_start.setText("Start")
self.button_start.clicked.connect(self.start) # NOQA: connect exist
def start(self) -> None:
language_code = self.select_language.currentData()
# load the correct translator
translator = QTranslator()
translator.load(str(assets_path / f"language/{language_code}.qm"))
# apply the language on the custom translator
translate.set_language(language_code)
# install the translator on the application
application = QApplication.instance()
application.installTranslator(translator)
# call the after event
self.after()
# delete the language selection
self.deleteLater()

View file

@ -8,7 +8,7 @@ from typing import Optional
from PyQt6.QtCore import pyqtSignal from PyQt6.QtCore import pyqtSignal
from PyQt6.QtWidgets import QVBoxLayout, QProgressBar, QWidget, QMessageBox from PyQt6.QtWidgets import QVBoxLayout, QProgressBar, QWidget, QMessageBox
from source import translate, widget, save from source import translate, ui, save
from source.survey.base import BaseSurvey from source.survey.base import BaseSurvey
from source.survey import Empty, survey_get from source.survey import Empty, survey_get
from source.utils import compress from source.utils import compress
@ -93,7 +93,7 @@ class SurveyEngine(QWidget):
def _on_signal_abandon(self): def _on_signal_abandon(self):
# on abandon, quit the survey # on abandon, quit the survey
window = typing.cast(widget.SurveyWindow, self.window()) window = typing.cast(ui.SurveyWindow, self.window())
window.quit() window.quit()
def _on_signal_skip(self): def _on_signal_skip(self):
@ -166,7 +166,7 @@ class SurveyEngine(QWidget):
) )
# finally, close the window # finally, close the window
window = typing.cast(widget.SurveyWindow, self.window()) window = typing.cast(ui.SurveyWindow, self.window())
window.quit() window.quit()
# signals # signals

View file

@ -3,7 +3,7 @@ from pathlib import Path
from PyQt6.QtGui import QIcon from PyQt6.QtGui import QIcon
from PyQt6.QtWidgets import QMainWindow from PyQt6.QtWidgets import QMainWindow
from source import widget, assets_path, __icon_png__ from source import ui, assets_path, __icon_png__
icon_path = assets_path / "icon.png" icon_path = assets_path / "icon.png"
@ -12,10 +12,16 @@ class SurveyWindow(QMainWindow):
def __init__(self, survey_path: Path | str): def __init__(self, survey_path: Path | str):
super().__init__() super().__init__()
# window style
self.setWindowIcon(QIcon(__icon_png__)) self.setWindowIcon(QIcon(__icon_png__))
self.setWindowTitle(self.tr("SURVEY")) self.setWindowTitle(self.tr("SURVEY"))
self.setCentralWidget(widget.SurveyEngine.from_file(survey_path)) # start by asking the user his language
language_selection = ui.LanguageSelection(
# after the language is selected, start the survey
after=lambda: self.setCentralWidget(ui.SurveyEngine.from_file(survey_path))
)
self.setCentralWidget(language_selection)
def quit(self): def quit(self):
# quit the application by closing and deleting the window # quit the application by closing and deleting the window

View file

@ -1,4 +1,5 @@
from .Browser import Browser from .Browser import Browser
from .LanguageSelection import LanguageSelection
from .SurveyEngine import SurveyEngine from .SurveyEngine import SurveyEngine
from .SurveyWindow import SurveyWindow from .SurveyWindow import SurveyWindow
from .SurveyNavigation import SurveyNavigation from .SurveyNavigation import SurveyNavigation