Skip to content

Commit

Permalink
Add basic possibility to use multiplechoice questions as text question
Browse files Browse the repository at this point in the history
  • Loading branch information
jfeil committed Oct 10, 2022
1 parent 02864f4 commit 8435ca4
Show file tree
Hide file tree
Showing 7 changed files with 365 additions and 105 deletions.
84 changes: 84 additions & 0 deletions res/regeltest_creator_questionwidget.ui
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>RegeltestCreatorQuestionWidget</class>
<widget class="QWidget" name="RegeltestCreatorQuestionWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>508</width>
<height>168</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<layout class="QVBoxLayout" name="verticalLayout_question">
<item>
<widget class="QLabel" name="label_question">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Question Text LOREM IPSUM DOLOR SIT AMED</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QStackedWidget" name="stackedWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="textanswer"/>
<widget class="QWidget" name="multiple_choice"/>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_settings">
<item>
<widget class="QCheckBox" name="checkBox_multiplechoice">
<property name="text">
<string>Multiplechoice?</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QSpinBox" name="spinBox_points">
<property name="suffix">
<string>Punkte</string>
</property>
<property name="value">
<number>2</number>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
93 changes: 55 additions & 38 deletions res/regeltest_save.ui
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>470</width>
<height>189</height>
<height>266</height>
</rect>
</property>
<property name="focusPolicy">
Expand All @@ -17,6 +17,22 @@
<string>Save Regeltest</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="1">
<widget class="QWidget" name="widget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLineEdit" name="icon_path_edit"/>
</item>
<item>
<widget class="QPushButton" name="icon_edit_button">
<property name="text">
<string>Auswählen</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
Expand All @@ -27,34 +43,40 @@
<item row="3" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Speicherort</string>
<string>Speicherort</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QWidget" name="widget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLineEdit" name="icon_path_edit"/>
</item>
<item row="6" column="0" colspan="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QWidget" name="widget_3" native="true">
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QPushButton" name="icon_edit_button">
<property name="text">
<string>Auswählen</string>
</property>
</widget>
<widget class="QLineEdit" name="title_edit"/>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Iconpfad</string>
<string>Iconpfad</string>
</property>
</widget>
</item>
<item row="3" column="2">
<item row="3" column="1">
<widget class="QWidget" name="widget_2" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
Expand All @@ -63,13 +85,30 @@
<item>
<widget class="QPushButton" name="output_edit_button">
<property name="text">
<string>Auswählen</string>
<string>Auswählen</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="5" column="0" colspan="2">
<widget class="QScrollArea" name="scrollArea">
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="question_scrollable">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>450</width>
<height>69</height>
</rect>
</property>
</widget>
</widget>
</item>
<item row="4" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
Expand All @@ -83,28 +122,6 @@
</property>
</spacer>
</item>
<item row="5" column="0" colspan="3">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QWidget" name="widget_3" native="true">
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLineEdit" name="title_edit"/>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<tabstops>
Expand Down
13 changes: 5 additions & 8 deletions src/dock_widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

from src import document_builder
from src.database import db
from src.datatypes import Regeltest, RegeltestIcon, RegeltestQuestion, SelfTestMode
from src.datatypes import Regeltest, RegeltestIcon, SelfTestMode
from src.regeltestcreator import RegeltestSetup, RegeltestSaveDialog
from src.ui_regeltest_creator_dockwidget import Ui_regeltest_creator_dockwidget
from src.ui_self_test_dockwidget import Ui_self_test_dockwidget
Expand Down Expand Up @@ -52,26 +52,23 @@ def create_regeltest(self):
questions = []
for signature in self.ui.regeltest_list.questions:
questions += [db.get_question(signature)]
settings = RegeltestSaveDialog(self)
settings = RegeltestSaveDialog(questions, self)
settings.ui.title_edit.setFocus()
result = settings.exec()
output_path = settings.ui.output_edit.text()
if result == QDialog.Accepted:
selected_questions = settings.get_questions()
QApplication.setOverrideCursor(Qt.WaitCursor)
if settings.ui.icon_path_edit.text():
icon = Image.open(settings.ui.icon_path_edit.text())
icon_db = db.get_or_create(RegeltestIcon, icon=icon.tobytes())
else:
icon = None
icon_db = None
regeltest_questions = [RegeltestQuestion(available_points=2,
question=question,
is_multiple_choice=(question.answer_index != -1))
for question in questions]
regeltest = Regeltest(title=settings.ui.title_edit.text(), icon=icon_db,
selected_questions=regeltest_questions)
selected_questions=selected_questions)
db.add_object(regeltest)
document_builder.create_document(questions, output_path, settings.ui.title_edit.text(),
document_builder.create_document(selected_questions, output_path, settings.ui.title_edit.text(),
icon=icon)
QApplication.restoreOverrideCursor()
webbrowser.open_new(output_path)
Expand Down
38 changes: 20 additions & 18 deletions src/document_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from reportlab.platypus import Flowable, SimpleDocTemplate, Spacer, Paragraph
from reportlab.rl_config import defaultPageSize

from src.datatypes import Question, MultipleChoice
from src.datatypes import Question, MultipleChoice, RegeltestQuestion

PAGE_HEIGHT = defaultPageSize[1]
PAGE_WIDTH = defaultPageSize[0]
Expand All @@ -33,7 +33,7 @@
class QuestionFlowable(Flowable):
canv: Canvas

def __init__(self, question_index: int, question: Question, mchoice: List[MultipleChoice], fontName='Helvetica',
def __init__(self, question_index: int, question: Question, is_multiplechoice: bool, fontName='Helvetica',
fontSize=9, solution: bool = False, shuffle_mchoice: bool = True, max_points: int = 2,
display_points: bool = True, x=0, y=0,
width=4 / 5 * PAGE_WIDTH):
Expand All @@ -59,12 +59,13 @@ def answer_letter(index):

self.question_index = question_index
self.question = question
self.answer_index = self.question.answer_index
self.is_multiplechoice = is_multiplechoice
self.new_mchoice = self.question.multiple_choice
self.new_answer_index = self.question.answer_index
if shuffle_mchoice and self.new_answer_index != -1:
self.new_mchoice, self.new_answer_index = shuffle_mchoice_fun(self.new_mchoice, self.new_answer_index)

if shuffle_mchoice and self.answer_index != -1:
mchoice, self.answer_index = shuffle_mchoice_fun(mchoice, self.answer_index)

self.mchoice = [f"{answer_letter(m.index)}) {m.text}" for m in mchoice]
self.new_mchoice = [f"{answer_letter(m.index)}) {m.text}" for m in self.new_mchoice]
self.solution = solution

self.paragraph_style = ParagraphStyle('DefaultStyle', fontName=fontName, fontSize=fontSize)
Expand All @@ -76,22 +77,21 @@ def answer_letter(index):

self.question_text = f"{self.question_index}. {self.question.question}"

if self.answer_index == -1:
if not self.is_multiplechoice:
self.answer_text = self.question.answer_text
else:
answer_letter = answer_letter(self.answer_index)
self.answer_text = f"{answer_letter}) {self.question.answer_text}"
self.answer_text = f"{answer_letter(self.new_answer_index)}) {self.question.answer_text}"

lines_question = len(simpleSplit(self.question_text, fontName, fontSize, self.width))
self.lines_answer = len(simpleSplit(self.answer_text, fontName, fontSize, ratio_answer * self.width))

if self.answer_index == -1:
if not self.is_multiplechoice:
self.height_answer = [max(self.lines_answer, min_lines) * linespacing]
else:
# noinspection PyTypeChecker
self.height_answer = [
max(len(simpleSplit(a, fontName, fontSize, ratio_answer * self.width)) * linespacing, 1.1 * radio_size)
for a in self.mchoice]
for a in self.new_mchoice]

self.height_question = lines_question * linespacing
self.height = sum(self.height_answer) + space_between + self.height_question + space_bottom
Expand All @@ -110,7 +110,7 @@ def draw(self):
solution.drawOn(self.canv, self.x + 4 * mm,
self.y + space_bottom + max(min_lines - self.lines_answer, 0) * linespacing)
elif not self.solution:
if self.answer_index != -1:
if self.is_multiplechoice:
def create_radio(index, text, x, y, height):
radio_group = f"Question_{self.question_index}"
self.canv.acroForm.radio(f"radio{index}", relative=True, size=radio_size, name=radio_group, x=x,
Expand All @@ -120,7 +120,7 @@ def create_radio(index, text, x, y, height):
solution.drawOn(self.canv, x + 1.25 * radio_size, y)

height_sum = sum(self.height_answer) + space_bottom
for index, (height, choice) in enumerate(zip(self.height_answer, self.mchoice)):
for index, (height, choice) in enumerate(zip(self.height_answer, self.new_mchoice)):
height_sum -= height
create_radio(index, choice, self.x, height_sum, height)

Expand Down Expand Up @@ -205,7 +205,7 @@ def draw(self):
max_points.drawOn(self.canv, self.width, y=y_name_row)


def create_document(questions: List[Question], filename, title, icon: Image = None,
def create_document(questions: List[RegeltestQuestion], filename, title, icon: Image = None,
solution_suffix='_LOESUNG', shuffle_mchoice=True, font_name='Helvetica', font_size=9):
def page_setup(canvas, doc):
canvas.saveState()
Expand All @@ -222,15 +222,17 @@ def page_setup(canvas, doc):
story_solution = [TitleFlowable(title, icon, username="Muster Lösung", max_points=len(questions) * 2)]
story_question = [TitleFlowable(title, icon, max_points=len(questions) * 2)]

for i, question in enumerate(questions):
for i, regeltest_question in enumerate(questions):
random_state = random.getstate()
question_flow = QuestionFlowable(i + 1, question, question.multiple_choice, font_name, font_size,
question_flow = QuestionFlowable(i + 1, regeltest_question.question, regeltest_question.is_multiple_choice,
font_name, font_size,
solution=False,
shuffle_mchoice=shuffle_mchoice, width=doc_question.width)
story_question.append(question_flow)
story_question.append(Spacer(1, 0.1 * inch))
random.setstate(random_state)
question_flow = QuestionFlowable(i + 1, question, question.multiple_choice, font_name, font_size, solution=True,
question_flow = QuestionFlowable(i + 1, regeltest_question.question, regeltest_question.is_multiple_choice,
font_name, font_size, solution=True,
shuffle_mchoice=shuffle_mchoice, width=doc_solution.width)
story_solution.append(question_flow)
story_solution.append(Spacer(1, 0.1 * inch))
Expand Down
Loading

0 comments on commit 8435ca4

Please sign in to comment.