added a proper language selection menu
This commit is contained in:
parent
4a8a80a206
commit
1ffcf5cdb8
17 changed files with 107 additions and 48 deletions
|
@ -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>
|
||||||
|
|
|
@ -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>
|
|
@ -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
17
main.py
|
@ -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()
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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()
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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()
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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()
|
||||||
|
|
67
source/ui/LanguageSelection.py
Normal file
67
source/ui/LanguageSelection.py
Normal 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()
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
Loading…
Reference in a new issue