Go back to Richel Bilderbeek's homepage.

Go back to Richel Bilderbeek's C++ page.

 

 

 

 

 

(C++) QtMultipleChoiceQuestionDialog

 

QtQt CreatorLubuntu

 

QtMultipleChoiceQuestionDialog is a Qt dialog for MultipleChoiceQuestion.

Technical facts

 

 

 

 

 

 

./CppQtMultipleChoiceQuestionDialog/CppQtMultipleChoiceQuestionDialog.pri

 

INCLUDEPATH += \
    ../../Classes/CppQtMultipleChoiceQuestionDialog

SOURCES += \
    ../../Classes/CppQtMultipleChoiceQuestionDialog/qtmultiplechoicequestiondialog.cpp

HEADERS  += \
    ../../Classes/CppQtMultipleChoiceQuestionDialog/qtmultiplechoicequestiondialog.h

FORMS += \
    ../../Classes/CppQtMultipleChoiceQuestionDialog/qtmultiplechoicequestiondialog.ui

OTHER_FILES += \
    ../../Classes/CppQtMultipleChoiceQuestionDialog/Licence.txt

 

 

 

 

 

./CppQtMultipleChoiceQuestionDialog/qtmultiplechoicequestiondialog.h

 

//---------------------------------------------------------------------------
/*
QtMultipleChoiceQuestionDialog, Qt dialog for MultipleChoiceQuestion
Copyright (C) 2011-2015 Richel Bilderbeek

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program.If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
//From http://www.richelbilderbeek.nl/QtMultipleChoiceQuestionDialog.htm
//---------------------------------------------------------------------------
#ifndef QTMULTIPLECHOICEQUESTIONDIALOG_H
#define QTMULTIPLECHOICEQUESTIONDIALOG_H

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#include <boost/scoped_ptr.hpp>
#include <boost/shared_ptr.hpp>

#include "qthideandshowdialog.h"

#include "questiondialog.h"
#include "qtquestiondialog.h"
#pragma GCC diagnostic pop


namespace Ui {
  class QtMultipleChoiceQuestionDialog;
}

namespace ribi {

struct Question;
struct MultipleChoiceQuestion;
struct MultipleChoiceQuestionDialog;

class QtMultipleChoiceQuestionDialog : public QtQuestionDialog
{
  Q_OBJECT

public:
  explicit QtMultipleChoiceQuestionDialog(
    QWidget *parent = 0);

  QtMultipleChoiceQuestionDialog(
    const boost::shared_ptr<MultipleChoiceQuestionDialog>& dialog,
    QWidget *parent = 0);
  QtMultipleChoiceQuestionDialog(const QtMultipleChoiceQuestionDialog&) = delete;
  QtMultipleChoiceQuestionDialog& operator=(const QtMultipleChoiceQuestionDialog&) = delete;

  ~QtMultipleChoiceQuestionDialog() noexcept;

  boost::shared_ptr<const QuestionDialog> GetDialog() const;

  ///Obtain the version of this class
  static std::string GetVersion() noexcept;

  ///Obtain the version history of this class
  static std::vector<std::string> GetVersionHistory() noexcept;

  void SetDialog(const boost::shared_ptr<QuestionDialog>& dialog);

private slots:
  void on_button_submit_clicked() noexcept;

private:
  Ui::QtMultipleChoiceQuestionDialog *ui;
  boost::shared_ptr<MultipleChoiceQuestionDialog> m_dialog;

  ///Set the Question
  //void SetQuestion(const boost::shared_ptr<const MultipleChoiceQuestion>& question) noexcept;

  void OnMultipleChoiceQuestionDialogChanged(MultipleChoiceQuestionDialog * const mc_question_dialog) noexcept;
  void OnMultipleChoiceQuestionChanged(const boost::shared_ptr<MultipleChoiceQuestionDialog>& mc_question) noexcept;

};

} //~namespace ribi

#endif // QTMULTIPLECHOICEQUESTIONDIALOG_H

 

 

 

 

 

./CppQtMultipleChoiceQuestionDialog/qtmultiplechoicequestiondialog.cpp

 

//---------------------------------------------------------------------------
/*
QtMultipleChoiceQuestionDialog, Qt dialog for MultipleChoiceQuestion
Copyright (C) 2011-2015 Richel Bilderbeek

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program.If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
//From http://www.richelbilderbeek.nl/QtMultipleChoiceQuestionDialog.htm
//---------------------------------------------------------------------------
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#include "qtmultiplechoicequestiondialog.h"

#include <array>
#include <boost/bind.hpp>
#include <boost/lambda/bind.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/numeric/conversion/cast.hpp>

#include <QFile>

#include "fileio.h"
#include "multiplechoicequestion.h"
#include "multiplechoicequestiondialog.h"
#include "qtquestiondialog.h"
#include "questiondialog.h"
#include "trace.h"
#include "ui_qtmultiplechoicequestiondialog.h"

#pragma GCC diagnostic pop

/*
ribi::QtMultipleChoiceQuestionDialog::QtMultipleChoiceQuestionDialog(QWidget *parent)
  : QtQuestionDialog(parent),
    ui(new Ui::QtMultipleChoiceQuestionDialog),
    m_dialog(
      new MultipleChoiceQuestionDialog(
        boost::shared_ptr<MultipleChoiceQuestion>(
          new MultipleChoiceQuestion(
            "*","1+1=","2",{"1","3","4"}))))
{
  assert(m_dialog);
  assert(GetDialog());

  ui->setupUi(this);
}
*/

ribi::QtMultipleChoiceQuestionDialog::QtMultipleChoiceQuestionDialog(
  const boost::shared_ptr<MultipleChoiceQuestionDialog>& dialog,
  QWidget *parent)
  : QtQuestionDialog(parent),
    ui(new Ui::QtMultipleChoiceQuestionDialog),
    m_dialog(dialog)
{
  assert(m_dialog);
  assert(GetDialog());

  ui->setupUi(this);
  //this->SetQuestion(m_dialog->GetMultipleChoiceQuestion());

  const boost::shared_ptr<const MultipleChoiceQuestion> question {
    m_dialog->GetMultipleChoiceQuestion()
  };
  assert(question);

  if (fileio::FileIo().IsRegularFile(question->GetFilename().c_str()))
  {
    ui->image->setPixmap(QPixmap(question->GetFilename().c_str()));
  }

  ui->stackedWidget->setCurrentWidget(ui->page_question);
  ui->label_question->setText(question->GetQuestion().c_str());
  ui->label_question_again->setText(question->GetQuestion().c_str());
  ui->label_answer->setText(question->GetAnswer().c_str());

  const int sz = 7;
  const std::array<QRadioButton*,sz> buttons {
    { ui->radio_1, ui->radio_2, ui->radio_3, ui->radio_4, ui->radio_5, ui->radio_6, ui->radio_7 }
  };
  const std::vector<std::string> options = question->GetOptions();
  static_assert(sz == static_cast<int>(buttons.size()),"std::array<T,sz> will have size sz");
  assert(sz >= boost::numeric_cast<int>(options.size()));
  for (int i = 0; i!=sz; ++i)
  {
    if (i < boost::numeric_cast<int>(options.size()))
    {
      buttons[i]->setText(options[i].c_str());
    }
    else
    {
      buttons[i]->setVisible(false);
    }
  }

}

ribi::QtMultipleChoiceQuestionDialog::~QtMultipleChoiceQuestionDialog() noexcept
{
  delete ui;
}

boost::shared_ptr<const ribi::QuestionDialog> ribi::QtMultipleChoiceQuestionDialog::GetDialog() const
{
  return m_dialog;
}

std::string ribi::QtMultipleChoiceQuestionDialog::GetVersion() noexcept
{
  return "1.0";
}

std::vector<std::string> ribi::QtMultipleChoiceQuestionDialog::GetVersionHistory() noexcept
{
  return {
    "2011-06-28: version 1.0: initial version"
  };
}

void ribi::QtMultipleChoiceQuestionDialog::OnMultipleChoiceQuestionDialogChanged(
  MultipleChoiceQuestionDialog * const mc_question_dialog
) noexcept
{
  assert(mc_question_dialog);

  ui->radio_1->setChecked(mc_question_dialog->GetAnswerInProgress() == 0);
  ui->radio_2->setChecked(mc_question_dialog->GetAnswerInProgress() == 1);
  ui->radio_3->setChecked(mc_question_dialog->GetAnswerInProgress() == 2);
  ui->radio_4->setChecked(mc_question_dialog->GetAnswerInProgress() == 3);
  ui->radio_5->setChecked(mc_question_dialog->GetAnswerInProgress() == 4);
  ui->radio_6->setChecked(mc_question_dialog->GetAnswerInProgress() == 5);
  ui->radio_7->setChecked(mc_question_dialog->GetAnswerInProgress() == 6);
  OnMultipleChoiceQuestionDialogChanged(mc_question_dialog);
}

void ribi::QtMultipleChoiceQuestionDialog::OnMultipleChoiceQuestionChanged(
  const boost::shared_ptr<MultipleChoiceQuestionDialog>& mc_question
) noexcept
{
  assert(mc_question);
  assert(mc_question->GetQuestion());
  if (fileio::FileIo().IsRegularFile(mc_question->GetQuestion()->GetFilename()))
  {
    ui->image->setPixmap(QPixmap(mc_question->GetQuestion()->GetFilename().c_str()));
  }

  ui->stackedWidget->setCurrentWidget(ui->page_question);
  ui->label_question->setText(mc_question->GetQuestion()->GetQuestion().c_str());
  ui->label_question_again->setText(mc_question->GetQuestion()->GetQuestion().c_str());
  ui->label_answer->setText(mc_question->GetQuestion()->GetCorrectAnswers()[0].c_str());

}

void ribi::QtMultipleChoiceQuestionDialog::SetDialog(const boost::shared_ptr<QuestionDialog>& dialog)
{
  const bool verbose = false;

  const boost::shared_ptr<MultipleChoiceQuestionDialog> mcquestiondialog
    = boost::dynamic_pointer_cast<MultipleChoiceQuestionDialog>(dialog);
  if (!mcquestiondialog)
  {
    std::stringstream s;
    s << "QtMultipleChoiceQuestionDialog::SetDialog: not an MultipleChoiceQuestionDialog '" << dialog->ToStr() << "'\n";
    //this->ui->stackedWidget->setVisible(false);
    //this->ui->image->setVisible(false);
    return;
  }

  //this->ui->stackedWidget->setVisible(true);
  //this->ui->image->setVisible(true);

  assert(mcquestiondialog);
  if (m_dialog == mcquestiondialog)
  {
    return;
  }
  if (verbose)
  {
    std::stringstream s;
    s << "Setting mcquestiondialog '" << mcquestiondialog->ToStr() << "'\n";
  }
  const auto mc_question_after = mcquestiondialog->GetMultipleChoiceQuestion();

  bool mc_question_changed  = true;

  if (m_dialog)
  {
    const auto mc_question_before = m_dialog->GetMultipleChoiceQuestion();

    mc_question_changed = mc_question_before != mc_question_after;

    if (verbose)
    {
      if (mc_question_changed)
      {
        std::stringstream s;
        s
          << "open_question will change from "
          << mc_question_before->ToStr()
          << " to "
          << mc_question_after->ToStr()
          << '\n'
        ;
        TRACE(s.str());
      }
    }
    //Disconnect
    m_dialog->m_signal_mc_question_changed.disconnect(
      boost::bind(&ribi::QtMultipleChoiceQuestionDialog::OnMultipleChoiceQuestionDialogChanged,this,boost::lambda::_1)
    );

    /*
    m_dialog->m_signal_request_quit.disconnect(
      boost::bind(&ribi::QtMultipleChoiceQuestionDialog::OnQuit,this,boost::lambda::_1)
    );
    m_dialog->m_signal_submitted.disconnect(
      boost::bind(&ribi::QtMultipleChoiceQuestionDialog::OnSubmit,this,boost::lambda::_1)
    );
    */
  }

  //Replace m_example by the new one
  m_dialog = mcquestiondialog;

  assert(m_dialog->GetMultipleChoiceQuestion() == mc_question_after);

  m_dialog->m_signal_mc_question_changed.connect(
    boost::bind(&ribi::QtMultipleChoiceQuestionDialog::OnMultipleChoiceQuestionDialogChanged,this,boost::lambda::_1)
  );
  /*
  m_dialog->m_signal_request_quit.connect(
    boost::bind(&ribi::QtMultipleChoiceQuestionDialog::OnQuit,this)
  );
  m_dialog->m_signal_submitted.connect(
    boost::bind(&ribi::QtMultipleChoiceQuestionDialog::OnSubmit,this,boost::lambda::_1)
  );
  */

  //Emit everything that has changed
  if (mc_question_changed)
  {
    m_dialog->m_signal_mc_question_changed(m_dialog.get());
  }

  assert(mcquestiondialog == m_dialog);
}

/*
void ribi::QtMultipleChoiceQuestionDialog::SetQuestion(
  const boost::shared_ptr<const MultipleChoiceQuestion>& question) noexcept
{
  m_dialog->SetQuestion(question);

  if (QFile::exists(question->GetFilename().c_str()))
  {
    ui->image->setPixmap(QPixmap(question->GetFilename().c_str()));
  }

  const MultipleChoiceQuestion * const q
    = dynamic_cast<const MultipleChoiceQuestion *>(question.get());
  assert(q);

  ui->stackedWidget->setCurrentWidget(ui->page_question);
  ui->label_question->setText(question->GetQuestion().c_str());
  ui->label_question_again->setText(q->GetQuestion().c_str());
  ui->label_answer->setText(q->GetAnswer().c_str());


  const int sz = 7;
  const std::array<QRadioButton*,sz> buttons
    = { ui->radio_1, ui->radio_2, ui->radio_3, ui->radio_4, ui->radio_5, ui->radio_6, ui->radio_7 };
  const std::vector<std::string> options = q->GetOptions();
  static_assert(sz == buttons.size(),"std::array<T,sz> will have size sz");
  assert(sz >= boost::numeric_cast<int>(options.size()));
  for (int i = 0; i!=sz; ++i)
  {
    if (i < boost::numeric_cast<int>(options.size()))
    {
      buttons[i]->setText(options[i].c_str());
    }
    else
    {
      buttons[i]->setVisible(false);
    }
  }


}
*/

void ribi::QtMultipleChoiceQuestionDialog::on_button_submit_clicked() noexcept
{
  assert(!m_dialog->HasSubmitted());
  const std::vector<const QRadioButton* > buttons
    = { ui->radio_1, ui->radio_2, ui->radio_3, ui->radio_4, ui->radio_5, ui->radio_6 };

  if (std::find_if(
    buttons.begin(), buttons.end(),
    boost::bind(&QRadioButton::isChecked,boost::lambda::_1)
      == true) == buttons.end()) return;

  const std::string index {
    boost::lexical_cast<std::string>(
      std::distance(
        buttons.begin(),
        std::find_if(
          buttons.begin(), buttons.end(),
          boost::bind(&QRadioButton::isChecked,boost::lambda::_1) == true
        )
      )
    )
  };


  this->m_dialog->Submit(index);

  const bool is_correct = m_dialog->IsAnswerCorrect();

  this->ui->stackedWidget->setCurrentWidget(is_correct
    ? ui->page_correct
    : ui->page_incorrect);
}

 

 

 

 

 

Go back to Richel Bilderbeek's C++ page.

Go back to Richel Bilderbeek's homepage.

 

Valid XHTML 1.0 Strict

This page has been created by the tool CodeToHtml