different question type practice setup & parts of group train widget

This commit is contained in:
jorenchik
2024-09-29 17:01:44 +03:00
parent d19f082da6
commit 67ea97809b
3 changed files with 244 additions and 81 deletions

View File

@@ -1,8 +1,10 @@
#pragma once #pragma once
#include <QMainWindow> #include <QMainWindow>
#include "parser.h"
extern QMainWindow *trainWindow; extern QMainWindow *trainWindow;
void initTrainWindow(); void initTrainWindow();
void setQuestions(std::vector<Question*> questions);

View File

@@ -346,6 +346,7 @@ void loadMdem() {
questions = parseRes.value; questions = parseRes.value;
makePages(); makePages();
SwitchPage(0); SwitchPage(0);
setQuestions(questions);
} else { } else {
std::cout << "Compilation error." << std::endl; std::cout << "Compilation error." << std::endl;
for (auto mdem: mdems) { for (auto mdem: mdems) {
@@ -381,13 +382,13 @@ int main(int argc, char *argv[]) {
mdemList->setModel(model); mdemList->setModel(model);
QObject::connect( QObject::connect(
mdemList, mdemList,
&QTreeView::doubleClicked, &QTreeView::doubleClicked,
[model](const QModelIndex &index) { [model](const QModelIndex &index) {
auto fileInfo = model->fileInfo(index); auto fileInfo = model->fileInfo(index);
currentPath = fileInfo.filePath().toStdString(); currentPath = fileInfo.filePath().toStdString();
loadMdem(); loadMdem();
} }
); );
QModelIndex rootIndex = model->index( QModelIndex rootIndex = model->index(

View File

@@ -1,20 +1,26 @@
#include <QMainWindow> #include <QMainWindow>
#include <QWidget> #include <QWidget>
#include <QToolButton> #include <QToolButton>
#include <algorithm>
#include <cstdint>
#include <format>
#include <qboxlayout.h> #include <qboxlayout.h>
#include <qlabel.h> #include <qlabel.h>
#include <qlayoutitem.h> #include <qlayoutitem.h>
#include <qlistview.h> #include <qlistview.h>
#include <qnamespace.h> #include <qnamespace.h>
#include <qscrollarea.h>
#include <qstandarditemmodel.h> #include <qstandarditemmodel.h>
#include <qstringlistmodel.h> #include <qstringlistmodel.h>
#include <qtoolbutton.h> #include <qtoolbutton.h>
#include <Qt> #include <Qt>
#include <random>
#include <qwidget.h> #include <qwidget.h>
#include <QStandardItemModel> #include <QStandardItemModel>
#include <QDropEvent> #include <QDropEvent>
#include "trainWindow.h" #include "trainWindow.h"
#include "parser.h"
QWidget *wMaster; QWidget *wMaster;
QVBoxLayout *hMaster; QVBoxLayout *hMaster;
@@ -28,13 +34,25 @@ QVBoxLayout *vButtonBox;
QWidget *actionButtons; QWidget *actionButtons;
QHBoxLayout *hButtons; QHBoxLayout *hButtons;
QToolButton *btnPrev; QToolButton *btnPrev;
QToolButton *btnShowAnswer; QSpacerItem *leftSpacer;
QToolButton *btnTriggerAnswer;
QSpacerItem *rightSpacer;
QToolButton *btnNext; QToolButton *btnNext;
QMainWindow *trainWindow; QMainWindow *trainWindow;
QWidget *trainWidget; QWidget *trainWidget;
QVBoxLayout *vTrainWidget; QVBoxLayout *vTrainWidget;
std::default_random_engine rng;
QStandardItemModel *multiChoiceModel;
QListView *listView;
QStandardItemModel *itemModel;
QListView *itemListView;
QStandardItemModel *orderModel;
class CustomListView : public QListView class CustomListView : public QListView
{ {
Q_OBJECT Q_OBJECT
@@ -62,26 +80,26 @@ protected:
} }
} }
}; };
#include "trainWindow.moc" #include "trainWindow.moc"
CustomListView *orderList;
QStandardItem *makeItem(std::string content, bool isCheckable) {
auto *item = new QStandardItem();
item->setText(QString::fromStdString(content));
item->setCheckable(isCheckable);
return item;
};
void initTrainWindow() { void initTrainWindow() {
// # Types of question unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
// rng = std::default_random_engine(seed);
// - AnswerQuestion:
// One answer (could be on multiple lines).
// - ChoiceQuestion:
// One or many correct answers that are showed to user.
// - OrderQuestion:
// Many items that should be ordered in a list.
// - MatchQuestion:
// Match some items to other items.
trainWindow = new QMainWindow(); trainWindow = new QMainWindow();
trainWidget = new QWidget(); trainWidget = new QWidget();
vTrainWidget = new QVBoxLayout(); vTrainWidget = new QVBoxLayout();
/*wMaster = new QWidget();*/
/*hMaster = new QVBoxLayout();*/
trainWidget->setLayout(vTrainWidget); trainWidget->setLayout(vTrainWidget);
trainWindow->setCentralWidget(trainWidget); trainWindow->setCentralWidget(trainWidget);
trainWidget->setLayout(vTrainWidget); trainWidget->setLayout(vTrainWidget);
@@ -107,23 +125,9 @@ void initTrainWindow() {
)); ));
lQuestionText->setTextInteractionFlags(Qt::TextSelectableByMouse); lQuestionText->setTextInteractionFlags(Qt::TextSelectableByMouse);
vQuestionBox->addWidget(lQuestionText); vQuestionBox->addWidget(lQuestionText);
lQuestionText->hide();
} }
{ // Make answer text.
answerText = new QLabel();
answerText->setText("- Riga\n- Second line");
answerText->setWordWrap(true);
answerText->hide();
answerText->setStyleSheet(QString(
"QLabel {"
"font-size: 15px;"
"}"
));
answerText->setTextInteractionFlags(Qt::TextSelectableByMouse);
vQuestionBox->addWidget(answerText);
}
auto listStyle = auto listStyle =
"QListView {" "QListView {"
" background-color: white;" " background-color: white;"
@@ -133,7 +137,7 @@ void initTrainWindow() {
" padding: 5px 0 0 0;" " padding: 5px 0 0 0;"
"}" "}"
"QListView::item {" "QListView::item {"
" color: blue;" " color: black;"
" padding: 5px;" " padding: 5px;"
" border: 1px solid gray;" " border: 1px solid gray;"
" background-color: white;" " background-color: white;"
@@ -145,98 +149,254 @@ void initTrainWindow() {
"}"; "}";
{ // Make multi-choice list. { // Make multi-choice list.
auto *multiChoiceModel = new QStandardItemModel(); multiChoiceModel = new QStandardItemModel();
QListView *listView = new QListView(); listView = new QListView();
listView->setModel(multiChoiceModel); listView->setModel(multiChoiceModel);
auto *firstItem = new QStandardItem();
firstItem->setText("Item 1");
firstItem->setCheckable(true);
auto *secondItem = new QStandardItem();
secondItem->setText("Item 2");
secondItem->setCheckable(true);
multiChoiceModel->setItem(0, firstItem);
multiChoiceModel->setItem(1, secondItem);
listView->setStyleSheet(listStyle); listView->setStyleSheet(listStyle);
questionBox->layout()->addWidget(listView);
listView->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); listView->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
listView->setEditTriggers(QAbstractItemView::NoEditTriggers); listView->setEditTriggers(QAbstractItemView::NoEditTriggers);
listView->setFocusPolicy(Qt::NoFocus);
questionBox->layout()->addWidget(listView);
listView->hide();
}
{ // Make answer text.
answerText = new QLabel();
answerText->setText("- Riga\n- Second line");
answerText->setWordWrap(true);
answerText->setStyleSheet(QString(
"QLabel {"
"font-size: 15px;"
"}"
));
answerText->setTextInteractionFlags(Qt::TextSelectableByMouse);
vQuestionBox->addWidget(answerText);
answerText->hide();
} }
{ // Make order list. { // Make order list.
auto *orderModel = new QStandardItemModel(); orderModel = new QStandardItemModel();
QListView *orderList = new CustomListView(); orderList = new CustomListView();
orderList->setModel(orderModel); orderList->setModel(orderModel);
auto *firstItem = new QStandardItem();
firstItem->setText("Item 1");
auto *secondItem = new QStandardItem();
secondItem->setText("Item 2");
auto *thirdItem = new QStandardItem();
thirdItem->setText("Item 3");
orderModel->setItem(0, firstItem);
orderModel->setItem(1, secondItem);
orderModel->setItem(2, thirdItem);
questionBox->layout()->addWidget(orderList);
orderList->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); orderList->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
orderList->setEditTriggers(QAbstractItemView::NoEditTriggers); orderList->setEditTriggers(QAbstractItemView::NoEditTriggers);
orderList->setDragDropMode(QAbstractItemView::InternalMove); orderList->setDragDropMode(QAbstractItemView::InternalMove);
orderList->setFocusPolicy(Qt::NoFocus); orderList->setFocusPolicy(Qt::NoFocus);
orderList->setStyleSheet(listStyle); orderList->setStyleSheet(listStyle);
// Connect to handle the drop event properly // Connect to handle the drop event properly
QObject::connect( QObject::connect(
orderModel, orderModel,
&QStandardItemModel::rowsMoved, &QStandardItemModel::rowsMoved,
[orderModel](const QModelIndex &, int sourceRow, int, const QModelIndex &, int destinationRow) { [](const QModelIndex &, int sourceRow, int, const QModelIndex &, int destinationRow) {
if (sourceRow != destinationRow - 1) { if (sourceRow != destinationRow - 1) {
auto *movedItem = orderModel->takeItem(sourceRow); auto *movedItem = orderModel->takeItem(sourceRow);
orderModel->insertRow(destinationRow > sourceRow ? destinationRow - 1 : destinationRow, movedItem); orderModel->insertRow(destinationRow > sourceRow ? destinationRow - 1 : destinationRow, movedItem);
} }
} }
); );
questionBox->layout()->addWidget(orderList);
orderList->hide();
} }
{ // Make buttons menu. There are left middle and right buttons. { // Make buttons menu. There are left middle and right buttons.
vButtonBox = new QVBoxLayout(); vButtonBox = new QVBoxLayout();
actionButtons = new QWidget(); actionButtons = new QWidget();
hButtons = new QHBoxLayout(); hButtons = new QHBoxLayout();
btnPrev = new QToolButton(); btnPrev = new QToolButton();
auto *leftSpacer = new QSpacerItem(50, 50, QSizePolicy::Expanding, QSizePolicy::Minimum); leftSpacer = new QSpacerItem(50, 50, QSizePolicy::Expanding, QSizePolicy::Minimum);
btnShowAnswer = new QToolButton(); btnTriggerAnswer = new QToolButton();
auto *rightSpacer = new QSpacerItem(50, 50, QSizePolicy::Expanding, QSizePolicy::Minimum); rightSpacer = new QSpacerItem(50, 50, QSizePolicy::Expanding, QSizePolicy::Minimum);
btnNext = new QToolButton(); btnNext = new QToolButton();
hButtons->addWidget(btnPrev); hButtons->addWidget(btnPrev);
hButtons->addItem(leftSpacer); hButtons->addItem(leftSpacer);
hButtons->addWidget(btnShowAnswer); hButtons->addWidget(btnTriggerAnswer);
hButtons->addItem(rightSpacer); hButtons->addItem(rightSpacer);
hButtons->addWidget(btnNext); hButtons->addWidget(btnNext);
vButtonBox->addWidget(actionButtons); vButtonBox->addWidget(actionButtons);
actionButtons->setLayout(hButtons); actionButtons->setLayout(hButtons);
btnPrev->setText("Previous"); btnPrev->setText("Previous");
btnShowAnswer->setText("Show answer"); btnTriggerAnswer->setText("Show answer");
btnNext->setText("Next"); btnNext->setText("Next");
QObject::connect(btnShowAnswer, &QToolButton::clicked, [](bool checked) {
answerText->show(); questionBox->setObjectName("question-box");
btnShowAnswer->hide();
});
actionButtons->setStyleSheet(QString( actionButtons->setStyleSheet(QString(
"QToolButton {" "QToolButton {"
"padding: 4px 5px;" "padding: 4px 5px;"
"font-size: 15px;" "font-size: 15px;"
"}" "}"
)); ));
questionBox->setObjectName("question-box");
} }
{ // Make group question view.
auto wGroupQuestion = new QWidget();
auto hGroupQuestion = new QHBoxLayout();
wGroupQuestion->setLayout(hGroupQuestion);
auto itemScroll = new QScrollArea();
auto vItems = new QVBoxLayout();
itemScroll->setLayout(vItems);
itemModel = new QStandardItemModel();
itemListView = new QListView();
itemListView->setModel(itemModel);
itemListView->setStyleSheet(listStyle);
for (int i = 0; i < 50; ++i) {
itemModel->appendRow(makeItem("Item I", false));
}
vItems->addWidget(itemListView);
hGroupQuestion->addWidget(itemScroll);
auto wGroupBox = new QWidget();
auto vGroupBox = new QVBoxLayout();
auto groupScroll = new QScrollArea();
auto vGroups = new QVBoxLayout();
wGroupBox->setLayout(vGroupBox);
vGroupBox->addWidget(groupScroll);
groupScroll->setLayout(vGroups);
hGroupQuestion->addWidget(wGroupBox);
itemListView->setEditTriggers(QAbstractItemView::NoEditTriggers);
questionBox->layout()->addWidget(wGroupQuestion);
}
vTrainWidget->addWidget(questionBox); vTrainWidget->addWidget(questionBox);
vTrainWidget->addWidget(actionButtons); vTrainWidget->addWidget(actionButtons);
vTrainWidget->addWidget(wMaster); vTrainWidget->addWidget(wMaster);
} }
std::vector<Question*> trainQuestions = std::vector<Question*>();
int32_t currentQuestionIndex = -1;
void hideQuestionElements() {
lQuestionText->hide();
answerText->hide();
orderList->hide();
listView->hide();
}
void setupAnswerQuestion(MultiElementQuestion *question) {
hideQuestionElements();
lQuestionText->setText(
QString::fromStdString(question->QuestionText)
);
lQuestionText->show();
auto ss = std::stringstream();
for (auto answerEl: question->Choices) {
ss << std::format("- {}", answerEl.Answer) << std::endl;
}
answerText->setText(
QString::fromStdString(ss.str())
);
if (answerText->isVisible()) {
answerText->hide();
}
auto showAnswer = [](bool checked) {
answerText->show();
btnTriggerAnswer->hide();
QObject::disconnect(btnTriggerAnswer, 0, 0, 0);
};
QObject::connect(
btnTriggerAnswer,
&QToolButton::clicked,
showAnswer
);
btnTriggerAnswer->show();
}
void setupOrderQuestion(MultiElementQuestion *question) {
hideQuestionElements();
lQuestionText->setText(
QString::fromStdString(question->QuestionText)
);
lQuestionText->show();
orderModel->clear();
auto shuffledAnswers = question->Choices;
std::shuffle(shuffledAnswers.begin(), shuffledAnswers.end(), rng);
for (auto answerEl: shuffledAnswers) {
orderModel->appendRow(makeItem(answerEl.Answer, false));
}
orderList->show();
auto showAnswer = [](bool checked) {
QObject::disconnect(btnTriggerAnswer, 0, 0, 0);
};
QObject::connect(
btnTriggerAnswer,
&QToolButton::clicked,
showAnswer
);
btnTriggerAnswer->show();
}
void setupMultiChoiceQuestion(MultiElementQuestion *question) {
hideQuestionElements();
lQuestionText->setText(
QString::fromStdString(question->QuestionText)
);
lQuestionText->show();
multiChoiceModel->clear();
for (auto answerEl: question->Choices) {
multiChoiceModel->appendRow(makeItem(answerEl.Answer, true));
}
listView->show();
auto showAnswer = [](bool checked) {
QObject::disconnect(btnTriggerAnswer, 0, 0, 0);
};
QObject::connect(
btnTriggerAnswer,
&QToolButton::clicked,
showAnswer
);
btnTriggerAnswer->show();
}
void setupGroupQuestion(GroupQuestion *question) {
hideQuestionElements();
// TODO
auto showAnswer = [](bool checked) {
QObject::disconnect(btnTriggerAnswer, 0, 0, 0);
};
QObject::connect(
btnTriggerAnswer,
&QToolButton::clicked,
showAnswer
);
btnTriggerAnswer->show();
}
void setQuestions(std::vector<Question*> questions) {
trainQuestions = questions;
if (questions.size() <= 0) {
return;
}
// setupFirstQuestion
currentQuestionIndex = 0;
if (auto *question = dynamic_cast<MultiElementQuestion*>(trainQuestions[currentQuestionIndex])) {
switch (question->type) {
case MultiElementType::Order:
setupOrderQuestion(question);
break;
case MultiElementType::MultiChoice:
setupMultiChoiceQuestion(question);
break;
case MultiElementType::Regular:
setupAnswerQuestion(question);
break;
}
} else if (auto *question = dynamic_cast<GroupQuestion*>(trainQuestions[currentQuestionIndex])) {
setupGroupQuestion(question);
}
}