From 2d8b977f5d02f69ff15118a30a639cc9f831f4cd Mon Sep 17 00:00:00 2001 From: Jan Feil <11638228+jfeil@users.noreply.github.com> Date: Fri, 13 May 2022 22:31:53 +0200 Subject: [PATCH] Implement stress mode for self testing --- res/self_test_dockwidget.ui | 64 ++++++- res/self_test_widget.ui | 323 ++++++++++++++++++++++++--------- src/dock_widgets.py | 5 + src/main_widgets.py | 120 +++++++++++- src/ui_self_test_dockwidget.py | 56 +++++- src/ui_self_test_widget.py | 234 +++++++++++++++--------- 6 files changed, 617 insertions(+), 185 deletions(-) diff --git a/res/self_test_dockwidget.ui b/res/self_test_dockwidget.ui index d4458a9..e6fd5e1 100644 --- a/res/self_test_dockwidget.ui +++ b/res/self_test_dockwidget.ui @@ -40,15 +40,67 @@ - - - - Modus + + + + Fragenauswahl + + + + + Modus + + + + + + + - - + + + + Stressmodus + + + + + + Sekunden + + + + + + + + + + Frage ist sichtbar für + + + + + + + Automatische Evaluierung nach + + + + + + + Sekunden + + + + + + + + diff --git a/res/self_test_widget.ui b/res/self_test_widget.ui index 4b54ee9..45306ec 100644 --- a/res/self_test_widget.ui +++ b/res/self_test_widget.ui @@ -21,7 +21,78 @@ - + + + + Nächste Frage + + + + + + + Evaluieren + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> + <html><head><meta name="qrichtext" content="1" + /><meta charset="utf-8" /><style type="text/css"> + p, li { white-space: pre-wrap; } + </style></head><body style=" font-family:'Segoe UI'; + font-size:9pt; font-weight:400; font-style:normal;"> + <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; + margin-right:0px; -qt-block-indent:0; text-indent:0px;"> </p> + <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; + margin-right:0px; -qt-block-indent:0; text-indent:0px;"> </p> + <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; + margin-right:0px; -qt-block-indent:0; text-indent:0px;">Strafstoß, + Linie gehört zum Strafraum </p></body></html> + + + + + + + + + 0 + 0 + + + + + + + Statistiken + + + + 8 + 8 + + + + true + + + QToolButton::DelayedPopup + + + Qt::ToolButtonTextBesideIcon + + + true + + + Qt::RightArrow + + + + @@ -29,7 +100,7 @@ 0 - + 0 @@ -42,7 +113,7 @@ 0 - + @@ -87,7 +158,7 @@ - + @@ -103,69 +174,14 @@ - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> - <html><head><meta name="qrichtext" content="1" - /><meta charset="utf-8" /><style type="text/css"> - p, li { white-space: pre-wrap; } - </style></head><body style=" font-family:'Segoe UI'; - font-size:9pt; font-weight:400; font-style:normal;"> - <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; - margin-right:0px; -qt-block-indent:0; text-indent:0px;"> </p> - <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; - margin-right:0px; -qt-block-indent:0; text-indent:0px;">Strafstoß, - Linie gehört zum Strafraum </p></body></html> - - - - - - - - Nächste Frage - - - - - - - - 0 - 0 - - - - - + + - Statistiken - - - - 8 - 8 - - - - true - - - QToolButton::DelayedPopup - - - Qt::ToolButtonTextBesideIcon - - - true - - - Qt::RightArrow + Vorherige Frage - + QFrame::StyledPanel @@ -199,33 +215,158 @@ - - - - Evaluieren - - - - - - - Vorherige Frage - - - - - - Bei einem Angriff foult der Verteidiger den Stürmer direkt auf der - Strafraumlinie: Wie hat der Schiedsrichter zu entscheiden? - - - - true - - - 20 - + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QProgressBar::chunk { + background-color: #06b025; + } + + QProgressBar { + max-width: 10px; + } + + + + 24 + + + Qt::AlignCenter + + + false + + + Qt::Vertical + + + false + + + + + + + 300s + + + Qt::AlignCenter + + + + + + + + + + true + + + + + 0 + 0 + 636 + 274 + + + + + + + Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Phasellus rhoncus massa quis + turpis congue interdum. Suspendisse interdum + ipsum sit amet enim cursus vehicula. Praesent + non mauris augue. Cras est nisl, sagittis in + tempor ac, laoreet ac ex. Etiam dolor sapien, + ullamcorper a pellentesque vitae, ultrices nec + felis. Maecenas a justo a neque vehicula posuere + a vitae urna. Aliquam maximus lectus ut sapien + suscipit sagittis. Cras mauris lectus, molestie + ac auctor quis, hendrerit quis nisi. + Pellentesque porta justo nisi. Cras elementum + turpis et convallis ultrices. Proin ut tristique + tellus, ut faucibus est. Etiam convallis in + ipsum ac efficitur. Curabitur ultricies metus at + lorem pretium, at lobortis velit aliquet. Duis + pretium nec est sed luctus. Maecenas viverra + felis eu ex vestibulum gravida. + + Morbi id dui dui. Pellentesque sit amet ante ut + ligula euismod sollicitudin. Mauris lobortis + consequat accumsan. Praesent rutrum consectetur + diam, non viverra urna volutpat sit amet. Etiam + sit amet elit odio. Aliquam erat volutpat. + Integer semper justo nec arcu consequat commodo. + In egestas egestas orci at gravida. Integer + iaculis malesuada posuere. Aliquam turpis nunc, + eleifend sit amet sodales ac, luctus nec metus. + + Phasellus ultricies congue rutrum. In egestas + odio velit. Integer eget mi a dui egestas tempus + vitae eget mauris. Etiam lacinia, tellus nec + eleifend feugiat, nisl orci facilisis urna, at + vehicula felis sapien sit amet turpis. + Vestibulum dapibus, augue facilisis pharetra + gravida, ante metus consequat tortor, + sollicitudin ultrices ipsum. + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + true + + + 0 + + + + + + + + @@ -264,6 +405,8 @@ <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"> </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; + margin-right:0px; -qt-block-indent:0; text-indent:0px;"> </p> + <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">In dieser Situation ist es erforderlich auf Strafstoß zu entschieden. Die jeweiligen Begrenzungslinien gehören zum Raum, den sie umschließen (Der Strafraum wird @@ -287,6 +430,8 @@ <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"> </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; + margin-right:0px; -qt-block-indent:0; text-indent:0px;"> </p> + <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Strafstoß, Linie gehört zum Strafraum </p></body></html> diff --git a/src/dock_widgets.py b/src/dock_widgets.py index fcab876..7d4cda4 100644 --- a/src/dock_widgets.py +++ b/src/dock_widgets.py @@ -80,6 +80,8 @@ def create_regeltest(self): class SelfTestDockWidget(QWidget, Ui_self_test_dockwidget): changed = Signal() mode = SelfTestMode(0) # type: SelfTestMode + timer_question = Signal(int) + timer_answer = Signal(int) def __init__(self, main_window: MainWindow): super(SelfTestDockWidget, self).__init__(main_window) @@ -89,6 +91,9 @@ def __init__(self, main_window: MainWindow): self.ui.self_test_question_groups.clear() self.ui.self_test_question_groups.setSelectionMode(QListWidget.ExtendedSelection) + self.ui.question_visibility_spinbox.valueChanged.connect(self.timer_question) + self.ui.auto_evaluate_spinbox.valueChanged.connect(self.timer_answer) + self._question_groups = db.get_all_question_groups() for question in self._question_groups: item = QListWidgetItem(f"{question.id:02d} - {question.name}") diff --git a/src/main_widgets.py b/src/main_widgets.py index 73e826f..0b982f5 100644 --- a/src/main_widgets.py +++ b/src/main_widgets.py @@ -5,7 +5,7 @@ from typing import List, Tuple, Dict from typing import TYPE_CHECKING, Optional -from PySide6.QtCore import Signal, QSortFilterProxyModel +from PySide6.QtCore import Signal, QSortFilterProxyModel, QTimer from PySide6.QtGui import QKeySequence, QShortcut, Qt from PySide6.QtWidgets import QWidget, QListView, QMessageBox, QDialog, QDialogButtonBox, QListWidgetItem, \ QTreeWidgetItem @@ -262,12 +262,44 @@ def load_dataset(self): self.action_done.emit() +class Timer: + def __init__(self, value: int): + self.init_value = value + self.current_value = value + + def __sub__(self, other): + self.current_value = max(0, self.current_value - other) + return self + + def __add__(self, other): + self.init_value = other + self.current_value = other + return self + + def __int__(self): + return int(self.current_value) + + def __bool__(self): + return self.current_value > 0 + + def __eq__(self, other): + return self.init_value == other + + def __ne__(self, other): + return self.init_value != other + + def reset(self): + self.current_value = self.init_value + + class SelfTestWidget(QWidget, Ui_SelfTestWidget): def __init__(self, main_window: MainWindow, dock_widget: SelfTestDockWidget): super(SelfTestWidget, self).__init__(main_window) self.ui = Ui_SelfTestWidget() self.ui.setupUi(self) + self.ui.time_label.setMinimumSize(self.ui.time_label.sizeHint()) + self.main_window = main_window self.dock_widget = dock_widget self.ui.stackedWidget.setCurrentIndex(0) @@ -276,10 +308,23 @@ def __init__(self, main_window: MainWindow, dock_widget: SelfTestDockWidget): self._previous_questions = [] # type: List[Question] self._current_question = None # type: Optional[Question] + self.timer_question = QTimer(self) + self.timer_question.setInterval(1000) + self.timer_question.timeout.connect(lambda: self.update_timer(self.timer_question)) + self.timer_answer = QTimer(self) + self.timer_answer.setInterval(1000) + self.timer_answer.timeout.connect(lambda: self.update_timer(self.timer_answer)) + + self.time_question = Timer(0) # type: Timer + self.time_answer = Timer(0) # type: Timer + self.current_question = None # type: Optional[Question] self.previous_questions = [] self.next_questions = [] + self.dock_widget.changed.connect(self.selected_groups_changed) + self.dock_widget.timer_question.connect(self.update_timer_question) + self.dock_widget.timer_answer.connect(self.update_timer_answer) self.ui.next_button.pressed.connect(self.next_question) self.ui.previous_button.pressed.connect(self.previous_question) @@ -289,6 +334,7 @@ def __init__(self, main_window: MainWindow, dock_widget: SelfTestDockWidget): self.ui.statistics_button.set_content(self.ui.statistics_frame) self.update_progressbar(0, 0) + self.init_timer_display() def create_statistics(self): if not self.current_question: @@ -315,14 +361,17 @@ def current_question(self, value): self.ui.user_answer_test.setDisabled(not value) self.ui.statistics_button.setDisabled(not value) if not value: + self.stop_timer() self.ui.user_answer_test.setText("") self.ui.question_label_test.setText("Keine Frage verfügbar.") self.ui.statistics_button.setChecked(False) else: + self.start_timer() self.ui.question_label_test.setText(self._current_question.question) self.ui.question_label_test.setToolTip(self.create_statistics()) self.ui.statistics_label.setText(self.create_statistics()) self.ui.statistics_button.update_animation() + self.update_timer_display() @property def previous_questions(self): @@ -460,6 +509,40 @@ def update_progressbar(self, current_index: int, question_count: int): self.ui.progressbar_bar.setValue(current_index) self.ui.progressbar_label.setText(f"{current_index + 1} / {question_count}") + def init_timer_display(self): + time = self.time_question.init_value + self.time_answer.init_value + if time == 0: + time = 1 + self.ui.time_progressbar.setValue(0) + else: + self.ui.time_progressbar.setValue(time) + self.ui.time_progressbar.setMaximum(time) + self.update_timer_display() + + def update_timer_display(self): + time = int(self.time_question) + int(self.time_answer) + self.ui.time_label.setText(f"{time}s") + self.ui.time_progressbar.setValue(time) + + def update_timer_question(self, value: int): + if value == 0: + self.timer_question.stop() + else: + if self.timer_answer.isActive(): + self.timer_answer.stop() + self.time_answer.reset() + self.timer_question.start() + self.time_question += value + self.init_timer_display() + + def update_timer_answer(self, value: int): + if value == 0: + self.timer_answer.stop() + elif self.time_question == 0: + self.timer_answer.start() + self.time_answer += value + self.init_timer_display() + @staticmethod def prepare_random_mode(dataset) -> List[Question]: dataset = dataset.order_by(func.random()) @@ -485,3 +568,38 @@ def prepare_prioritize_new(dataset) -> List[Question]: # order the last_tested_date ascending and put the nones before them (already randomized in step 1) dataset = dataset.order_by(Statistics.last_tested.asc().nulls_first()) return dataset.all() + + def start_timer(self): + self.timer_question.stop() + self.timer_answer.stop() + self.time_question.reset() + self.time_answer.reset() + self.update_timer_display() + if self.time_question and self.time_question != 0: + self.timer_question.start() + elif self.time_answer and self.time_answer != 0: + self.timer_answer.start() + + def update_timer(self, timer_type: QTimer): + if timer_type == self.timer_question: + self.time_question -= self.timer_question.interval() / 1000 + if not self.time_question: + self.ui.question_label_test.setText("") + self.timer_question.stop() + if self.time_answer != 0: + self.timer_answer.start() + elif timer_type == self.timer_answer: + self.time_answer -= self.timer_answer.interval() / 1000 + if not self.time_answer: + self.evaluate_question() + self.timer_answer.stop() + else: + raise ValueError("Wrong timer") + self.update_timer_display() + + def stop_timer(self): + self.timer_question.stop() + self.time_question.reset() + self.timer_answer.stop() + self.time_answer.reset() + self.ui.time_progressbar.setDisabled(True) diff --git a/src/ui_self_test_dockwidget.py b/src/ui_self_test_dockwidget.py index adbfe17..2f80163 100644 --- a/src/ui_self_test_dockwidget.py +++ b/src/ui_self_test_dockwidget.py @@ -9,9 +9,8 @@ ################################################################################ from PySide6.QtCore import (QCoreApplication, QMetaObject, Qt) -from PySide6.QtWidgets import (QComboBox, QGridLayout, QLabel, - QListWidget, QListWidgetItem, QVBoxLayout, - QWidget) +from PySide6.QtWidgets import (QComboBox, QGridLayout, QGroupBox, + QLabel, QListWidget, QListWidgetItem, QSpinBox, QVBoxLayout, QWidget) class Ui_self_test_dockwidget(object): def setupUi(self, self_test_dockwidget): @@ -34,15 +33,47 @@ def setupUi(self, self_test_dockwidget): self.widget.setObjectName(u"widget") self.gridLayout = QGridLayout(self.widget) self.gridLayout.setObjectName(u"gridLayout") - self.label = QLabel(self.widget) + self.groupBox_2 = QGroupBox(self.widget) + self.groupBox_2.setObjectName(u"groupBox_2") + self.gridLayout_4 = QGridLayout(self.groupBox_2) + self.gridLayout_4.setObjectName(u"gridLayout_4") + self.label = QLabel(self.groupBox_2) self.label.setObjectName(u"label") - self.gridLayout.addWidget(self.label, 0, 0, 1, 1) + self.gridLayout_4.addWidget(self.label, 0, 0, 1, 1) - self.mode_comboBox = QComboBox(self.widget) + self.mode_comboBox = QComboBox(self.groupBox_2) self.mode_comboBox.setObjectName(u"mode_comboBox") - self.gridLayout.addWidget(self.mode_comboBox, 0, 1, 1, 1) + self.gridLayout_4.addWidget(self.mode_comboBox, 0, 1, 1, 1) + + self.gridLayout.addWidget(self.groupBox_2, 0, 0, 1, 2) + + self.groupBox = QGroupBox(self.widget) + self.groupBox.setObjectName(u"groupBox") + self.gridLayout_2 = QGridLayout(self.groupBox) + self.gridLayout_2.setObjectName(u"gridLayout_2") + self.question_visibility_spinbox = QSpinBox(self.groupBox) + self.question_visibility_spinbox.setObjectName(u"question_visibility_spinbox") + + self.gridLayout_2.addWidget(self.question_visibility_spinbox, 0, 1, 1, 1) + + self.question_visibility_label = QLabel(self.groupBox) + self.question_visibility_label.setObjectName(u"question_visibility_label") + + self.gridLayout_2.addWidget(self.question_visibility_label, 0, 0, 1, 1) + + self.auto_evaluate_label = QLabel(self.groupBox) + self.auto_evaluate_label.setObjectName(u"auto_evaluate_label") + + self.gridLayout_2.addWidget(self.auto_evaluate_label, 1, 0, 1, 1) + + self.auto_evaluate_spinbox = QSpinBox(self.groupBox) + self.auto_evaluate_spinbox.setObjectName(u"auto_evaluate_spinbox") + + self.gridLayout_2.addWidget(self.auto_evaluate_spinbox, 1, 1, 1, 1) + + self.gridLayout.addWidget(self.groupBox, 1, 0, 1, 2) self.verticalLayout.addWidget(self.widget) @@ -63,6 +94,17 @@ def retranslateUi(self, self_test_dockwidget): QCoreApplication.translate("self_test_dockwidget", u"2: M\u00f6gliche Antwort", None)); self.self_test_question_groups.setSortingEnabled(__sortingEnabled) + self.groupBox_2.setTitle(QCoreApplication.translate("self_test_dockwidget", u"Fragenauswahl", None)) self.label.setText(QCoreApplication.translate("self_test_dockwidget", u"Modus", None)) + self.groupBox.setTitle(QCoreApplication.translate("self_test_dockwidget", u"Stressmodus", None)) + self.question_visibility_spinbox.setSuffix( + QCoreApplication.translate("self_test_dockwidget", u" Sekunden", None)) + self.question_visibility_spinbox.setPrefix("") + self.question_visibility_label.setText( + QCoreApplication.translate("self_test_dockwidget", u"Frage ist sichtbar f\u00fcr", None)) + self.auto_evaluate_label.setText( + QCoreApplication.translate("self_test_dockwidget", u"Automatische Evaluierung nach", None)) + self.auto_evaluate_spinbox.setSuffix(QCoreApplication.translate("self_test_dockwidget", u" Sekunden", None)) + self.auto_evaluate_spinbox.setPrefix("") # retranslateUi diff --git a/src/ui_self_test_widget.py b/src/ui_self_test_widget.py index 9c4f9eb..c8146fa 100644 --- a/src/ui_self_test_widget.py +++ b/src/ui_self_test_widget.py @@ -8,9 +8,10 @@ ## WARNING! All changes made in this file will be lost when recompiling UI file! ################################################################################ -from PySide6.QtCore import (QCoreApplication, QMetaObject, QSize, Qt) -from PySide6.QtWidgets import (QFrame, QGridLayout, QHBoxLayout, - QLabel, QProgressBar, QPushButton, QSizePolicy, +from PySide6.QtCore import (QCoreApplication, QMetaObject, QRect, + QSize, Qt) +from PySide6.QtWidgets import (QFrame, QGridLayout, QLabel, + QProgressBar, QPushButton, QScrollArea, QSizePolicy, QStackedWidget, QTextEdit, QToolButton, QVBoxLayout, QWidget) @@ -30,78 +31,89 @@ def setupUi(self, SelfTestWidget): self.test_page.setObjectName(u"test_page") self.gridLayout = QGridLayout(self.test_page) self.gridLayout.setObjectName(u"gridLayout") - self.progressbar_widget = QWidget(self.test_page) - self.progressbar_widget.setObjectName(u"progressbar_widget") - sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) + self.next_button = QPushButton(self.test_page) + self.next_button.setObjectName(u"next_button") + + self.gridLayout.addWidget(self.next_button, 7, 3, 1, 1) + + self.switch_eval_button = QPushButton(self.test_page) + self.switch_eval_button.setObjectName(u"switch_eval_button") + + self.gridLayout.addWidget(self.switch_eval_button, 7, 1, 1, 2) + + self.user_answer_test = QTextEdit(self.test_page) + self.user_answer_test.setObjectName(u"user_answer_test") + + self.gridLayout.addWidget(self.user_answer_test, 4, 0, 1, 4) + + self.statistics_button = CollapseButton(self.test_page) + self.statistics_button.setObjectName(u"statistics_button") + sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.progressbar_widget.sizePolicy().hasHeightForWidth()) - self.progressbar_widget.setSizePolicy(sizePolicy) - self.horizontalLayout = QHBoxLayout(self.progressbar_widget) - self.horizontalLayout.setObjectName(u"horizontalLayout") - self.horizontalLayout.setContentsMargins(0, 0, 0, 0) - self.progressbar_bar = QProgressBar(self.progressbar_widget) - self.progressbar_bar.setObjectName(u"progressbar_bar") - sizePolicy1 = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) + sizePolicy.setHeightForWidth(self.statistics_button.sizePolicy().hasHeightForWidth()) + self.statistics_button.setSizePolicy(sizePolicy) + self.statistics_button.setStyleSheet(u"") + self.statistics_button.setIconSize(QSize(8, 8)) + self.statistics_button.setCheckable(True) + self.statistics_button.setPopupMode(QToolButton.DelayedPopup) + self.statistics_button.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) + self.statistics_button.setAutoRaise(True) + self.statistics_button.setArrowType(Qt.RightArrow) + + self.gridLayout.addWidget(self.statistics_button, 2, 0, 1, 4) + + self.progressbar_widget = QWidget(self.test_page) + self.progressbar_widget.setObjectName(u"progressbar_widget") + sizePolicy1 = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) sizePolicy1.setHorizontalStretch(0) sizePolicy1.setVerticalStretch(0) - sizePolicy1.setHeightForWidth(self.progressbar_bar.sizePolicy().hasHeightForWidth()) - self.progressbar_bar.setSizePolicy(sizePolicy1) + sizePolicy1.setHeightForWidth(self.progressbar_widget.sizePolicy().hasHeightForWidth()) + self.progressbar_widget.setSizePolicy(sizePolicy1) + self.gridLayout_3 = QGridLayout(self.progressbar_widget) + self.gridLayout_3.setObjectName(u"gridLayout_3") + self.gridLayout_3.setContentsMargins(0, 0, 0, 0) + self.progressbar_bar = QProgressBar(self.progressbar_widget) + self.progressbar_bar.setObjectName(u"progressbar_bar") + sizePolicy2 = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) + sizePolicy2.setHorizontalStretch(0) + sizePolicy2.setVerticalStretch(0) + sizePolicy2.setHeightForWidth(self.progressbar_bar.sizePolicy().hasHeightForWidth()) + self.progressbar_bar.setSizePolicy(sizePolicy2) self.progressbar_bar.setMaximumSize(QSize(16777215, 1)) - self.progressbar_bar.setStyleSheet(u" QProgressBar::chunk {\n" - " background-color: #06b025;\n" - "}\n" + self.progressbar_bar.setStyleSheet(u"QProgressBar::chunk {\n" + " background-color: #06b025;\n" + " }\n" "\n" - "QProgressBar {\n" - " text-align: right;\n" - " max-height: 1px;\n" - "}") + " QProgressBar {\n" + " text-align: right;\n" + " max-height: 1px;\n" + " }\n" + " ") self.progressbar_bar.setMaximum(255) self.progressbar_bar.setValue(30) self.progressbar_bar.setTextVisible(False) self.progressbar_bar.setOrientation(Qt.Horizontal) self.progressbar_bar.setInvertedAppearance(False) - self.horizontalLayout.addWidget(self.progressbar_bar) + self.gridLayout_3.addWidget(self.progressbar_bar, 0, 0, 1, 1) self.progressbar_label = QLabel(self.progressbar_widget) self.progressbar_label.setObjectName(u"progressbar_label") - sizePolicy2 = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Minimum) - sizePolicy2.setHorizontalStretch(0) - sizePolicy2.setVerticalStretch(0) - sizePolicy2.setHeightForWidth(self.progressbar_label.sizePolicy().hasHeightForWidth()) - self.progressbar_label.setSizePolicy(sizePolicy2) - - self.horizontalLayout.addWidget(self.progressbar_label) - - self.gridLayout.addWidget(self.progressbar_widget, 5, 0, 1, 4) - - self.user_answer_test = QTextEdit(self.test_page) - self.user_answer_test.setObjectName(u"user_answer_test") - - self.gridLayout.addWidget(self.user_answer_test, 3, 0, 1, 4) + sizePolicy3 = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Minimum) + sizePolicy3.setHorizontalStretch(0) + sizePolicy3.setVerticalStretch(0) + sizePolicy3.setHeightForWidth(self.progressbar_label.sizePolicy().hasHeightForWidth()) + self.progressbar_label.setSizePolicy(sizePolicy3) - self.next_button = QPushButton(self.test_page) - self.next_button.setObjectName(u"next_button") + self.gridLayout_3.addWidget(self.progressbar_label, 0, 1, 1, 1) - self.gridLayout.addWidget(self.next_button, 6, 3, 1, 1) + self.gridLayout.addWidget(self.progressbar_widget, 6, 0, 1, 4) - self.statistics_button = CollapseButton(self.test_page) - self.statistics_button.setObjectName(u"statistics_button") - sizePolicy3 = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) - sizePolicy3.setHorizontalStretch(0) - sizePolicy3.setVerticalStretch(0) - sizePolicy3.setHeightForWidth(self.statistics_button.sizePolicy().hasHeightForWidth()) - self.statistics_button.setSizePolicy(sizePolicy3) - self.statistics_button.setStyleSheet(u"") - self.statistics_button.setIconSize(QSize(8, 8)) - self.statistics_button.setCheckable(True) - self.statistics_button.setPopupMode(QToolButton.DelayedPopup) - self.statistics_button.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) - self.statistics_button.setAutoRaise(True) - self.statistics_button.setArrowType(Qt.RightArrow) + self.previous_button = QPushButton(self.test_page) + self.previous_button.setObjectName(u"previous_button") - self.gridLayout.addWidget(self.statistics_button, 1, 0, 1, 4) + self.gridLayout.addWidget(self.previous_button, 7, 0, 1, 1) self.statistics_frame = QFrame(self.test_page) self.statistics_frame.setObjectName(u"statistics_frame") @@ -115,24 +127,70 @@ def setupUi(self, SelfTestWidget): self.verticalLayout_3.addWidget(self.statistics_label) - self.gridLayout.addWidget(self.statistics_frame, 2, 0, 1, 4) - - self.switch_eval_button = QPushButton(self.test_page) - self.switch_eval_button.setObjectName(u"switch_eval_button") - - self.gridLayout.addWidget(self.switch_eval_button, 6, 1, 1, 2) + self.gridLayout.addWidget(self.statistics_frame, 3, 0, 1, 4) + + self.widget = QWidget(self.test_page) + self.widget.setObjectName(u"widget") + self.gridLayout_4 = QGridLayout(self.widget) + self.gridLayout_4.setObjectName(u"gridLayout_4") + self.gridLayout_4.setContentsMargins(0, 0, 0, 0) + self.widget_2 = QWidget(self.widget) + self.widget_2.setObjectName(u"widget_2") + sizePolicy4 = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred) + sizePolicy4.setHorizontalStretch(0) + sizePolicy4.setVerticalStretch(0) + sizePolicy4.setHeightForWidth(self.widget_2.sizePolicy().hasHeightForWidth()) + self.widget_2.setSizePolicy(sizePolicy4) + self.verticalLayout_4 = QVBoxLayout(self.widget_2) + self.verticalLayout_4.setObjectName(u"verticalLayout_4") + self.verticalLayout_4.setContentsMargins(0, 0, 0, 0) + self.time_progressbar = QProgressBar(self.widget_2) + self.time_progressbar.setObjectName(u"time_progressbar") + self.time_progressbar.setStyleSheet(u"QProgressBar::chunk {\n" + "background-color: #06b025;\n" + " }\n" + "\n" + " QProgressBar {\n" + " max-width: 10px;\n" + " }\n" + " ") + self.time_progressbar.setValue(24) + self.time_progressbar.setAlignment(Qt.AlignCenter) + self.time_progressbar.setTextVisible(False) + self.time_progressbar.setOrientation(Qt.Vertical) + self.time_progressbar.setInvertedAppearance(False) + + self.verticalLayout_4.addWidget(self.time_progressbar, 0, Qt.AlignHCenter) + + self.time_label = QLabel(self.widget_2) + self.time_label.setObjectName(u"time_label") + self.time_label.setAlignment(Qt.AlignCenter) + + self.verticalLayout_4.addWidget(self.time_label, 0, Qt.AlignHCenter) + + self.gridLayout_4.addWidget(self.widget_2, 0, 1, 2, 1) + + self.scrollArea = QScrollArea(self.widget) + self.scrollArea.setObjectName(u"scrollArea") + self.scrollArea.setWidgetResizable(True) + self.scrollAreaWidgetContents = QWidget() + self.scrollAreaWidgetContents.setObjectName(u"scrollAreaWidgetContents") + self.scrollAreaWidgetContents.setGeometry(QRect(0, 0, 636, 274)) + self.verticalLayout_5 = QVBoxLayout(self.scrollAreaWidgetContents) + self.verticalLayout_5.setObjectName(u"verticalLayout_5") + self.question_label_test = QLabel(self.scrollAreaWidgetContents) + self.question_label_test.setObjectName(u"question_label_test") + self.question_label_test.setAlignment(Qt.AlignLeading | Qt.AlignLeft | Qt.AlignTop) + self.question_label_test.setWordWrap(True) + self.question_label_test.setMargin(0) - self.previous_button = QPushButton(self.test_page) - self.previous_button.setObjectName(u"previous_button") + self.verticalLayout_5.addWidget(self.question_label_test) - self.gridLayout.addWidget(self.previous_button, 6, 0, 1, 1) + self.scrollArea.setWidget(self.scrollAreaWidgetContents) - self.question_label_test = QLabel(self.test_page) - self.question_label_test.setObjectName(u"question_label_test") - self.question_label_test.setWordWrap(True) - self.question_label_test.setMargin(20) + self.gridLayout_4.addWidget(self.scrollArea, 0, 0, 1, 1) - self.gridLayout.addWidget(self.question_label_test, 0, 0, 1, 4) + self.gridLayout.addWidget(self.widget, 0, 0, 1, 4) self.stackedWidget.addWidget(self.test_page) self.eval_widget = QWidget() @@ -184,32 +242,41 @@ def setupUi(self, SelfTestWidget): self.stackedWidget.setCurrentIndex(0) + QMetaObject.connectSlotsByName(SelfTestWidget) # setupUi def retranslateUi(self, SelfTestWidget): SelfTestWidget.setWindowTitle(QCoreApplication.translate("SelfTestWidget", u"Form", None)) - self.progressbar_bar.setFormat(QCoreApplication.translate("SelfTestWidget", u"%v/%m", None)) - self.progressbar_label.setText(QCoreApplication.translate("SelfTestWidget", u"20 / 255", None)) + self.next_button.setText(QCoreApplication.translate("SelfTestWidget", u"N\u00e4chste Frage", None)) + self.switch_eval_button.setText(QCoreApplication.translate("SelfTestWidget", u"Evaluieren", None)) self.user_answer_test.setHtml(QCoreApplication.translate("SelfTestWidget", u"\n" "\n" "

\n" + "

\n" "

Strafsto\u00df, Linie geh\u00f6rt zum Strafraum

", None)) - self.next_button.setText(QCoreApplication.translate("SelfTestWidget", u"N\u00e4chste Frage", None)) self.statistics_button.setText(QCoreApplication.translate("SelfTestWidget", u"Statistiken", None)) - self.statistics_label.setText(QCoreApplication.translate("SelfTestWidget", u"Das ist\n" - "ein\n" - "Test", None)) - self.switch_eval_button.setText(QCoreApplication.translate("SelfTestWidget", u"Evaluieren", None)) + self.progressbar_bar.setFormat(QCoreApplication.translate("SelfTestWidget", u"%v/%m", None)) + self.progressbar_label.setText(QCoreApplication.translate("SelfTestWidget", u"20 / 255", None)) self.previous_button.setText(QCoreApplication.translate("SelfTestWidget", u"Vorherige Frage", None)) + self.statistics_label.setText(QCoreApplication.translate("SelfTestWidget", u"Das ist\n" + " ein\n" + " Test\n" + " ", + None)) + self.time_label.setText(QCoreApplication.translate("SelfTestWidget", u"300s", None)) self.question_label_test.setText(QCoreApplication.translate("SelfTestWidget", - u"Bei einem Angriff foult der Verteidiger den St\u00fcrmer direkt auf der\n" - " Strafraumlinie: Wie hat der Schiedsrichter zu entscheiden?\n" - " ", None)) + u"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus rhoncus massa quis turpis congue interdum. Suspendisse interdum ipsum sit amet enim cursus vehicula. Praesent non mauris augue. Cras est nisl, sagittis in tempor ac, laoreet ac ex. Etiam dolor sapien, ullamcorper a pellentesque vitae, ultrices nec felis. Maecenas a justo a neque vehicula posuere a vitae urna. Aliquam maximus lectus ut sapien suscipit sagittis. Cras mauris lectus, molestie ac auctor quis, hendrerit quis nisi. Pellentesque porta justo nisi. Cras elementum turpis et convallis ultrices. Proin ut tristique tellus, ut faucibus est. Etiam convallis in ipsum ac efficitur. Curabitur ultricies metus at lorem pretium, at lobortis velit aliquet. Duis pretium nec est sed luctus. Maecenas viverra felis eu ex vestibulum gravida.\n" + "\n" + "Morbi id dui dui. Pellentesque sit amet ante ut ligula euismod sollicitudin. Mauris lobortis consequat accumsan. Praesent rutrum consectetur diam, non viverra urna volutpat sit amet. Etiam sit amet elit odio." + " Aliquam erat volutpat. Integer semper justo nec arcu consequat commodo. In egestas egestas orci at gravida. Integer iaculis malesuada posuere. Aliquam turpis nunc, eleifend sit amet sodales ac, luctus nec metus.\n" + "\n" + "Phasellus ultricies congue rutrum. In egestas odio velit. Integer eget mi a dui egestas tempus vitae eget mauris. Etiam lacinia, tellus nec eleifend feugiat, nisl orci facilisis urna, at vehicula felis sapien sit amet turpis. Vestibulum dapibus, augue facilisis pharetra gravida, ante metus consequat tortor, sollicitudin ultrices ipsum. ", + None)) self.incorrect_button.setText(QCoreApplication.translate("SelfTestWidget", u"Falsch", None)) self.correct_button.setText(QCoreApplication.translate("SelfTestWidget", u"Richtig", None)) self.correct_answer_eval.setHtml(QCoreApplication.translate("SelfTestWidget", @@ -218,14 +285,17 @@ def retranslateUi(self, SelfTestWidget): "p, li { white-space: pre-wrap; }\n" "\n" "

\n" - "

In dieser Situation ist es erforderlich auf Strafsto\u00df zu entschieden. Die jeweiligen Begrenzungslinien geh\u00f6ren zum Raum, den sie umschlie\u00dfen (Der Strafraum wird von der Strafraumlinie umschlossen). " - "

", None)) + "

\n" + "

In dieser Situation ist es erforderlich auf Strafsto\u00df zu entschieden. Die jeweiligen Begrenzungslinien " + "geh\u00f6ren zum Raum, den sie umschlie\u00dfen (Der Strafraum wird von der Strafraumlinie umschlossen).

", + None)) self.user_answer_eval.setHtml(QCoreApplication.translate("SelfTestWidget", u"\n" "\n" "

\n" + "

\n" "

Strafsto\u00df, Linie geh\u00f6rt zum Strafraum

", None)) self.question_label_eval.setText(QCoreApplication.translate("SelfTestWidget",