[kde-doc-english] [parley/Applications/16.04] src/practice: Redesign of Multiple-Choice Test
Julian Helfferich
julian.helfferich at googlemail.com
Fri Mar 25 13:26:36 UTC 2016
Git commit 5e27c8c3da7cd95d9bc84649babc9d045c97e109 by Julian Helfferich.
Committed on 25/03/2016 at 12:49.
Pushed by helfferich into branch 'Applications/16.04'.
Redesign of Multiple-Choice Test
In the new design the QRadioButtons have been replaced with
QPushButtons and the design further specified using QStyleSheets. The
new design contains several improvements:
* Labels numbering the entries indicate which entry is selected by
which keyboard shortcut.
* Borders around the QPushButton make it very clear which entry has the
keyboard focus and over which entry the mouse is hovering.
* For correct and wrong answers, the background is changed to green and
red respectively. The black text on colored background is more
legible than colored text.
REVIEW: 127305
GUI: Re-design of multiple choice widget. Pictures of the multiple
choice widget are used in the handbook in Chapters "Practice" and
"Grammar Practice Modes".
M +107 -33 src/practice/multiplechoicemodewidget.cpp
M +5 -3 src/practice/multiplechoicemodewidget.h
http://commits.kde.org/parley/5e27c8c3da7cd95d9bc84649babc9d045c97e109
diff --git a/src/practice/multiplechoicemodewidget.cpp b/src/practice/multiplechoicemodewidget.cpp
index 74b3279..a4eff53 100644
--- a/src/practice/multiplechoicemodewidget.cpp
+++ b/src/practice/multiplechoicemodewidget.cpp
@@ -20,7 +20,7 @@
#include <QDebug>
#include <kcolorscheme.h>
-#include <QtWidgets/QRadioButton>
+#include <QPushButton>
#include <QTimer>
#include <QKeyEvent>
#include <QVBoxLayout>
@@ -53,9 +53,7 @@ void MultiplechoiceModeWidget::setQuestionFont(const QFont& font)
void MultiplechoiceModeWidget::setSolutionFont(const QFont& font)
{
m_solutionFont = font;
- foreach(QRadioButton * radio, m_choiceButtons) {
- radio->setFont(m_solutionFont);
- }
+ resetButtonStyleSheet();
}
void MultiplechoiceModeWidget::setQuestion(const QVariant& question)
@@ -80,14 +78,14 @@ void MultiplechoiceModeWidget::setQuestion(const QVariant& question)
if (m_choiceButtons.size() != data.choices.size()) {
qDeleteAll(m_choiceButtons);
m_choiceButtons.clear();
- setNumberOfRadioButtons(data.choices.size());
+ setNumberOfPushButtons(data.choices.size());
}
int j = 0;
- foreach(QRadioButton * radio, m_choiceButtons) {
- radio->setText(data.choices[j]);
- radio->setToolTip(data.choices[j]);
- radio->setFont(m_solutionFont);
+ foreach(QPushButton * pushButton, m_choiceButtons) {
+ pushButton->setText(data.choices[j]);
+ pushButton->setToolTip(data.choices[j]);
+ pushButton->setFont(m_solutionFont);
j++;
}
}
@@ -100,35 +98,46 @@ void MultiplechoiceModeWidget::showQuestion()
m_ui->solutionSoundButton->setVisible(false);
m_ui->feedbackLabel->clear();
+ resetButtonStyleSheet();
+
if ( ! m_choiceButtons.isEmpty() ) {
- //necessary trick to uncheck'em all
- m_choiceButtons[0]->setChecked(true);
- m_choiceButtons[0]->setAutoExclusive(false);
- m_choiceButtons[0]->setChecked(false);
- m_choiceButtons[0]->setAutoExclusive(true);
- foreach(QRadioButton * radio, m_choiceButtons) {
- radio->setPalette(palette());
- radio->setEnabled(true);
+ foreach(QPushButton * pushButton, m_choiceButtons) {
+ pushButton->setChecked(false);
+ pushButton->setEnabled(true);
}
QTimer::singleShot(0, m_choiceButtons[0], SLOT(setFocus()));
}
}
-void MultiplechoiceModeWidget::setNumberOfRadioButtons(const int numberOfChoices)
+void MultiplechoiceModeWidget::setNumberOfPushButtons(const int numberOfChoices)
{
QVBoxLayout *verticalLayout = new QVBoxLayout();
m_ui->gridLayout->addLayout(verticalLayout, 2, 0);
for (int i = 0; i < numberOfChoices; i++) {
- QRadioButton *radio_button = new QRadioButton(this);
- verticalLayout->addWidget(radio_button);
- m_choiceButtons.append(radio_button);
+ QHBoxLayout *horizontalLayout = new QHBoxLayout();
+ verticalLayout->addLayout(horizontalLayout);
+
+ // Display number of entry
+ QLabel *label = new QLabel(QString::number(i+1) + QString(":"), this);
+ horizontalLayout->addWidget(label);
+
+ // Button displaying choice
+ QPushButton *pushButton = new QPushButton(this);
+ pushButton->setCheckable(true);
+ pushButton->setFlat(true);
+ pushButton->sizePolicy().setHorizontalPolicy(QSizePolicy::Maximum);
+ m_choiceButtons.append(pushButton);
if (i < 5) {
- connect(m_actions.at(i), &QAction::triggered, radio_button, &QAbstractButton::click);
+ connect(m_actions.at(i), &QAction::triggered, pushButton, &QAbstractButton::click);
}
- connect(radio_button, &QRadioButton::clicked, this, &MultiplechoiceModeWidget::continueAction);
- radio_button->installEventFilter(this);
+ connect(pushButton, &QPushButton::clicked, this, &MultiplechoiceModeWidget::continueAction);
+ pushButton->installEventFilter(this);
+ horizontalLayout->addWidget(pushButton);
+
+ // Spacer to align button to the left
+ horizontalLayout->addStretch(1);
}
}
@@ -149,9 +158,9 @@ bool MultiplechoiceModeWidget::eventFilter(QObject *obj, QEvent *event)
if (event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
if (keyEvent->key() == Qt::Key_Enter || keyEvent->key() == Qt::Key_Return) {
- QRadioButton *radioButton = qobject_cast<QRadioButton*>(obj);
- if (radioButton) {
- radioButton->click();
+ QPushButton *pushButton = qobject_cast<QPushButton*>(obj);
+ if (pushButton) {
+ pushButton->click();
return true;
}
}
@@ -181,12 +190,41 @@ void MultiplechoiceModeWidget::showSolution()
if (userInput().isValid()) {
input = userInput().toInt();
}
- m_choiceButtons[m_solution]->setPalette(m_correctPalette);
+
+ const QColor textColor = palette().color(QPalette::WindowText);
+ // Set border to text color with light transparency
+ const QString borderColor = QStringLiteral("#90") +
+ palette().color(QPalette::WindowText).name().remove(0,1);
+ // Set background to correct color, but with transparency
+ const QString correctBackground = QStringLiteral("#7D") +
+ m_correctPalette.color(QPalette::Text).name().remove(0,1);
+
+ m_choiceButtons[m_solution]->setStyleSheet(
+ m_choiceButtons[m_solution]->styleSheet() +
+ " QPushButton:checked { "
+ "color: " + textColor.name() + "; "
+ "border-color: " + borderColor + "; "
+ "background-color: " + correctBackground +
+ " }"
+ );
+ // Always check correct button to highlight correct answer
+ m_choiceButtons[m_solution]->setChecked(true);
+
if (input != -1 && input != m_solution) {
- m_choiceButtons[input]->setPalette(m_wrongPalette);
+ const QString wrongBackground = QStringLiteral("#7D") +
+ m_wrongPalette.color(QPalette::Text).name().remove(0,1);
+
+ m_choiceButtons[input]->setStyleSheet(
+ m_choiceButtons[input]->styleSheet() +
+ " QPushButton:checked { "
+ "color: " + textColor.name() + "; "
+ "border-color: " + borderColor + "; "
+ "background-color: " + wrongBackground +
+ " }"
+ );
}
- foreach(QRadioButton * radio, m_choiceButtons) {
- radio->setEnabled(false);
+ foreach(QPushButton * pushButton, m_choiceButtons) {
+ pushButton->setEnabled(false);
}
m_ui->solutionPronunciationLabel->setVisible(m_ui->solutionPronunciationLabel->isEnabled());
m_ui->solutionSoundButton->setVisible(m_ui->solutionSoundButton->isEnabled());
@@ -196,8 +234,8 @@ QVariant MultiplechoiceModeWidget::userInput()
{
int i = 0;
- foreach(QRadioButton * radio, m_choiceButtons) {
- if (radio->isChecked()) return i;
+ foreach(QPushButton * pushButton, m_choiceButtons) {
+ if (pushButton->isChecked()) return i;
i++;
}
@@ -225,3 +263,39 @@ void MultiplechoiceModeWidget::setQuestionPronunciation(const QString& pronuncia
m_ui->questionPronunciationLabel->setText('[' + pronunciationText + ']');
m_ui->questionPronunciationLabel->setEnabled(!pronunciationText.isNull());
}
+
+void MultiplechoiceModeWidget::resetButtonStyleSheet()
+{
+ // Define default QPushButton StyleSheet
+ const QColor textColor = palette().color(QPalette::WindowText);
+ // Set border to text color with light transparency
+ const QString borderColor = QStringLiteral("#90") +
+ palette().color(QPalette::WindowText).name().remove(0,1);
+ const QString defaultStyleSheet =
+ "QPushButton { text-align: left; "
+ "color: " + textColor.name() + "; "
+ "padding: 5px; "
+ "border-color: #00FFFFFF; " // Make border transparent
+ "border-style: solid; "
+ "border-width: 1px; "
+ "border-radius: 4px; "
+ "font-style: " +
+ m_solutionFont.styleName() + "; " +
+ "font-weight: " +
+ QString::number(m_solutionFont.weight()) + "; " +
+ "font-size: " +
+ QString::number(m_solutionFont.pointSize()) + "pt } "+
+ "QPushButton:hover { "
+ "border-color: " + borderColor + " } "
+ "QPushButton:focus { "
+ "color: " + textColor.name() + " } "
+ "QPushButton:focus:!hover { "
+ "border-style: dashed; "
+ "border-color: " + borderColor + " }";
+
+ if (!m_choiceButtons.isEmpty()) {
+ foreach(QPushButton * pushButton, m_choiceButtons) {
+ pushButton->setStyleSheet(defaultStyleSheet);
+ }
+ }
+}
diff --git a/src/practice/multiplechoicemodewidget.h b/src/practice/multiplechoicemodewidget.h
index 0d0b43c..6af1292 100644
--- a/src/practice/multiplechoicemodewidget.h
+++ b/src/practice/multiplechoicemodewidget.h
@@ -22,7 +22,7 @@ namespace Ui
{
class MultiplechoicePracticeWidget;
}
-class QRadioButton;
+class QPushButton;
namespace Practice
{
@@ -59,15 +59,17 @@ public:
public Q_SLOTS:
virtual void showQuestion();
virtual void showSolution();
- virtual void setNumberOfRadioButtons(const int numberOfChoices);
+ virtual void setNumberOfPushButtons(const int numberOfChoices);
virtual void showSynonym();
protected:
virtual bool eventFilter(QObject *obj, QEvent *event);
+ virtual void resetButtonStyleSheet();
+
private:
Ui::MultiplechoicePracticeWidget* m_ui;
int m_solution;
- QList<QRadioButton*> m_choiceButtons;
+ QList<QPushButton*> m_choiceButtons;
QList<QAction*> m_actions;
LatexRenderer *m_latexRenderer;
QFont m_solutionFont;
More information about the kde-doc-english
mailing list