mirror of
https://github.com/jorenchik/mdemory.git
synced 2026-03-22 00:26:21 +00:00
different question type practice setup & parts of group train widget
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <QMainWindow>
|
||||
|
||||
#include "parser.h"
|
||||
|
||||
extern QMainWindow *trainWindow;
|
||||
|
||||
void initTrainWindow();
|
||||
void setQuestions(std::vector<Question*> questions);
|
||||
|
||||
@@ -346,6 +346,7 @@ void loadMdem() {
|
||||
questions = parseRes.value;
|
||||
makePages();
|
||||
SwitchPage(0);
|
||||
setQuestions(questions);
|
||||
} else {
|
||||
std::cout << "Compilation error." << std::endl;
|
||||
for (auto mdem: mdems) {
|
||||
|
||||
@@ -1,20 +1,26 @@
|
||||
#include <QMainWindow>
|
||||
#include <QWidget>
|
||||
#include <QToolButton>
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <format>
|
||||
#include <qboxlayout.h>
|
||||
#include <qlabel.h>
|
||||
#include <qlayoutitem.h>
|
||||
#include <qlistview.h>
|
||||
#include <qnamespace.h>
|
||||
#include <qscrollarea.h>
|
||||
#include <qstandarditemmodel.h>
|
||||
#include <qstringlistmodel.h>
|
||||
#include <qtoolbutton.h>
|
||||
#include <Qt>
|
||||
#include <random>
|
||||
#include <qwidget.h>
|
||||
#include <QStandardItemModel>
|
||||
#include <QDropEvent>
|
||||
|
||||
#include "trainWindow.h"
|
||||
#include "parser.h"
|
||||
|
||||
QWidget *wMaster;
|
||||
QVBoxLayout *hMaster;
|
||||
@@ -28,13 +34,25 @@ QVBoxLayout *vButtonBox;
|
||||
QWidget *actionButtons;
|
||||
QHBoxLayout *hButtons;
|
||||
QToolButton *btnPrev;
|
||||
QToolButton *btnShowAnswer;
|
||||
QSpacerItem *leftSpacer;
|
||||
QToolButton *btnTriggerAnswer;
|
||||
QSpacerItem *rightSpacer;
|
||||
QToolButton *btnNext;
|
||||
|
||||
QMainWindow *trainWindow;
|
||||
QWidget *trainWidget;
|
||||
QVBoxLayout *vTrainWidget;
|
||||
|
||||
std::default_random_engine rng;
|
||||
|
||||
QStandardItemModel *multiChoiceModel;
|
||||
QListView *listView;
|
||||
|
||||
QStandardItemModel *itemModel;
|
||||
QListView *itemListView;
|
||||
|
||||
QStandardItemModel *orderModel;
|
||||
|
||||
class CustomListView : public QListView
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -62,26 +80,26 @@ protected:
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#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() {
|
||||
// # Types of question
|
||||
//
|
||||
// - 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.
|
||||
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
|
||||
rng = std::default_random_engine(seed);
|
||||
|
||||
trainWindow = new QMainWindow();
|
||||
trainWidget = new QWidget();
|
||||
vTrainWidget = new QVBoxLayout();
|
||||
|
||||
/*wMaster = new QWidget();*/
|
||||
/*hMaster = new QVBoxLayout();*/
|
||||
trainWidget->setLayout(vTrainWidget);
|
||||
trainWindow->setCentralWidget(trainWidget);
|
||||
trainWidget->setLayout(vTrainWidget);
|
||||
@@ -107,23 +125,9 @@ void initTrainWindow() {
|
||||
));
|
||||
lQuestionText->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
||||
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 =
|
||||
"QListView {"
|
||||
" background-color: white;"
|
||||
@@ -133,7 +137,7 @@ void initTrainWindow() {
|
||||
" padding: 5px 0 0 0;"
|
||||
"}"
|
||||
"QListView::item {"
|
||||
" color: blue;"
|
||||
" color: black;"
|
||||
" padding: 5px;"
|
||||
" border: 1px solid gray;"
|
||||
" background-color: white;"
|
||||
@@ -145,61 +149,58 @@ void initTrainWindow() {
|
||||
"}";
|
||||
|
||||
{ // Make multi-choice list.
|
||||
auto *multiChoiceModel = new QStandardItemModel();
|
||||
QListView *listView = new QListView();
|
||||
multiChoiceModel = new QStandardItemModel();
|
||||
listView = new QListView();
|
||||
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);
|
||||
|
||||
questionBox->layout()->addWidget(listView);
|
||||
listView->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
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.
|
||||
auto *orderModel = new QStandardItemModel();
|
||||
QListView *orderList = new CustomListView();
|
||||
orderModel = new QStandardItemModel();
|
||||
orderList = new CustomListView();
|
||||
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->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||
orderList->setDragDropMode(QAbstractItemView::InternalMove);
|
||||
orderList->setFocusPolicy(Qt::NoFocus);
|
||||
|
||||
orderList->setStyleSheet(listStyle);
|
||||
|
||||
// Connect to handle the drop event properly
|
||||
QObject::connect(
|
||||
orderModel,
|
||||
&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) {
|
||||
auto *movedItem = orderModel->takeItem(sourceRow);
|
||||
orderModel->insertRow(destinationRow > sourceRow ? destinationRow - 1 : destinationRow, movedItem);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
questionBox->layout()->addWidget(orderList);
|
||||
orderList->hide();
|
||||
}
|
||||
|
||||
{ // Make buttons menu. There are left middle and right buttons.
|
||||
@@ -207,36 +208,195 @@ void initTrainWindow() {
|
||||
actionButtons = new QWidget();
|
||||
hButtons = new QHBoxLayout();
|
||||
btnPrev = new QToolButton();
|
||||
auto *leftSpacer = new QSpacerItem(50, 50, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||
btnShowAnswer = new QToolButton();
|
||||
auto *rightSpacer = new QSpacerItem(50, 50, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||
leftSpacer = new QSpacerItem(50, 50, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||
btnTriggerAnswer = new QToolButton();
|
||||
rightSpacer = new QSpacerItem(50, 50, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||
btnNext = new QToolButton();
|
||||
|
||||
hButtons->addWidget(btnPrev);
|
||||
hButtons->addItem(leftSpacer);
|
||||
hButtons->addWidget(btnShowAnswer);
|
||||
hButtons->addWidget(btnTriggerAnswer);
|
||||
hButtons->addItem(rightSpacer);
|
||||
hButtons->addWidget(btnNext);
|
||||
vButtonBox->addWidget(actionButtons);
|
||||
actionButtons->setLayout(hButtons);
|
||||
btnPrev->setText("Previous");
|
||||
btnShowAnswer->setText("Show answer");
|
||||
btnTriggerAnswer->setText("Show answer");
|
||||
btnNext->setText("Next");
|
||||
QObject::connect(btnShowAnswer, &QToolButton::clicked, [](bool checked) {
|
||||
answerText->show();
|
||||
btnShowAnswer->hide();
|
||||
});
|
||||
|
||||
questionBox->setObjectName("question-box");
|
||||
actionButtons->setStyleSheet(QString(
|
||||
"QToolButton {"
|
||||
"padding: 4px 5px;"
|
||||
"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(actionButtons);
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user