4
I’m looking to build a question form in Qt. As there are several questions to be answered, it is necessary to allow the scrolling of the form, and so I used a QScrollArea
. Questions are all answered on a scale Likert, then I adjusted the alignment of the layout that contains them to the left and spaced the options manually. That is, everything is aligned to the left. I also implemented an alternate color style, just to make it more enjoyable for the user to differentiate the questions when scrolling the form.
Here is an image of the MCVE that I prepared (and is below). The main problem is that I can’t get this "zebrado" to extend to the end of the form (on the right, indicated in the blue box in the image). There is also the space that looks like a margin on the left (indicated in the red box).
To solve the main problem, I have already tried to change the size restrictions of the kids layouts (using setSizeConstraint
) and even add a reamer (stretch) after the last option (as can be seen in the code line marked with comment), but none of these options works. And for the secondary problem, well, I’ve tried changing the margins via stylesheet (as in code) and even using the method setMargin
of one’s own class QWidget
, but nothing works.
What works for the main problem is to set a minimum or fixed size for the options container (the object in pRow
), but I cannot use this option because the window can have the size adjusted by the user (or depending on the screen dimensions available to it). Also because it doesn’t solve the secondary problem, and I wouldn’t want to capture window resize event to adjust the size manually - since then I lose the advantage of using layouts.
Any suggestions?
MCVE code
#include <QApplication>
#include <QWidget>
#include <QRadioButton>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QFrame>
#include <QLabel>
#include <QRadioButton>
#include <QScrollArea>
#define STYLE_SHEET " \
QWidget#plainArea \
{ \
background-color: #ffffff; \
padding: 0px 0px 0px 0px; \
margin: 0px 0px 0px 0px; \
border-width: 0px; \
} \
\
QLabel#headerTitle \
{ \
font-size: 25px; } \
} \
\
QLabel#questionTitle \
{ \
font-size: 20px; \
} \
\
QRadioButton#optionTitle \
{ \
font-size: 16px; \
} \
\
QWidget#highlightedrow \
{ \
background-color: #efd3d2; \
} \
"
QWidget* createQuestionnaire(QWidget *pParent)
{
QWidget *pQuestionnaire = new QWidget(pParent);
pQuestionnaire->setObjectName("plainArea");
pQuestionnaire->setLayout(new QVBoxLayout());
pQuestionnaire->layout()->setAlignment(Qt::AlignTop);
// Cabeçalho
QLabel *pTitle = new QLabel("Por favor, responda às perguntas a seguir.", pQuestionnaire);
pTitle->setObjectName("headerTitle");
pQuestionnaire->layout()->addWidget(pTitle);
QFrame *pLine = new QFrame(pQuestionnaire);
pLine->setFrameStyle(QFrame::HLine);
pLine->setLineWidth(4);
pQuestionnaire->layout()->addWidget(pLine);
static_cast<QBoxLayout*>(pQuestionnaire->layout())->addSpacing(10);
// Scroll Area
QScrollArea *pScroll = new QScrollArea(pQuestionnaire);
pScroll->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
pScroll->setObjectName("plainArea");
pScroll->setLayout(new QVBoxLayout());
pQuestionnaire->layout()->addWidget(pScroll);
QWidget *pArea = new QWidget(pQuestionnaire);
pArea->setObjectName("plainArea");
pArea->setLayout(new QVBoxLayout());
pArea->layout()->setSizeConstraint(QLayout::SetMinAndMaxSize);
pScroll->setWidget(pArea);
// Questões
QStringList lFruits = {
"Abacate", "Amora", "Ameixa", "Acerola", "Abacaxi", "Açaí",
"Banana", "Bacuri", "Buriti", "Butiá", "Bacaba", "Carambola",
"Cajá", "Caju", "Cereja", "Cacau", "Caqui", "Cupuaçu", "Damasco",
"Figo", "Framboesa", "Fruta Pão", "Graviola", "Goiaba", "Goiaba Branca",
"Groselha", "Guaraná", "Grumixama", "Guariroba", "Ingá", "Ibapó",
"Itu", "Ingá Dedo", "Ingá Branco", "Jaca", "Jabuticaba", "Jambo",
"Jenipapo", "Jatobá", "Kiwi", "Laranja", "Limão", "Lima Doce",
"Lixia", "Melancia", "Mamão", "Melão", "Maracujá", "Manga",
"Macadâmia", "Maçã", "Mangaba", "Mexerica", "Nectarina", "Noz",
"Nêspera", "Olho-De-Boi", "Pera", "Pêssego", "Pitaya", "Pitanga",
"Pinha", "Pinhão", "Pitomba", "Pocã", "Quina", "Rabutan", "Romã",
"Sapoti", "Sapucaia", "Salok", "Saputá", "Tangerina", "Tomate",
"Tamarindo", "Toranja", "Taiúva", "Uva", "Uxi", "Uvaia", "Umbu",
"Veludo", "Wampi", "Xixá"
};
QStringList lOptions = { "detesto", "gosto pouco", "gosto", "gosto muito", "adoro" };
for(int i = 0; i < lFruits.size(); i++)
{
QWidget *pRow = new QWidget(pQuestionnaire);
pArea->layout()->addWidget(pRow);
if(i % 2)
pRow->setObjectName("highlightedrow");
pRow->setLayout(new QVBoxLayout());
QLabel *pQuestion = new QLabel(QString("%1 - Você gosta de %2?").arg(i+1).arg(lFruits.at(i)), pRow);
pQuestion->setObjectName("questionTitle");
pRow->layout()->addWidget(pQuestion);
QWidget *pOptions = new QWidget(pRow);
pRow->layout()->addWidget(pOptions);
pOptions->setLayout(new QHBoxLayout());
pOptions->layout()->setAlignment(Qt::AlignLeft);
static_cast<QBoxLayout*>(pOptions->layout())->addSpacing(60);
foreach(QString sOption, lOptions)
{
QRadioButton *pButton = new QRadioButton(sOption, pOptions);
pButton->setCursor(Qt::PointingHandCursor);
pButton->setObjectName("optionTitle");
pOptions->layout()->addWidget(pButton);
static_cast<QBoxLayout*>(pOptions->layout())->addSpacing(20);
}
static_cast<QBoxLayout*>(pOptions->layout())->addStretch(); // <--- Stretch não funciona!
}
return pQuestionnaire;
}
int main(int argc, char** argv)
{
QApplication oApp(argc, argv);
QWidget *pWindow = new QWidget();
pWindow->setObjectName("plainArea");
pWindow->setStyleSheet(STYLE_SHEET);
pWindow->setWindowTitle("MCVE para o SOPT");
pWindow->setLayout(new QVBoxLayout());
pWindow->layout()->addWidget(createQuestionnaire(pWindow));
pWindow->show();
pWindow->resize(800, 600);
return oApp.exec();
}
P.S.: Oh, how I hate the QScrollArea
of Qt, you see. rs
I’ll have them frame it, take a picture and ask all the questions that don’t go forward :)
– Maniero
Let go of the exaggerating hand, go. :)
– Luiz Vieira
All right, I don’t give orders to frame :P
– Maniero