Cupidvogel
2nd May 2015, 18:21
I am trying to design a custom rich dropdown, like the one you can find here: https://jsfiddle.net/53vLfjfu/.
I figured I will design the dropdown widget first, as the remaining task of showing and hiding on click will be trivial. So here is what I came up with:
class DropdownOption: public QPushButton
{
public:
DropdownOption(std::string aText, QWidget *aParent);
};
DropdownOption::DropdownOption(std::string aText, QWidget *aParent):
QPushButton(QString::fromStdString(aText),aParent)
{
this->setFixedHeight(30);
this->setCursor(Qt::PointingHandCursor);
this->setCheckable(false);
this->setStyleSheet("background: rgb(74,89,98); color: black; border-radius: 0px; text-align: left; padding-left: 5px; border-bottom: 1px solid black;");
}
//parent is the widget with all the options which will roll down when the dropdown widget showing the current value is clicked
QFrame *parent = new QFrame(this);
int width = 120;
parent->setParent(fParent);
//this width will be flexible, here I am setting to 160 for checking purpose
parent->setGeometry(40,40,width,160);
parent->setStyleSheet("border-radius: 5px; background:red;");
QFrame *actualDropDown = new QFrame(parent);
actualDropDown->setFixedWidth(width-30);
actualDropDown->setStyleSheet("background: blue;");
QVBoxLayout *layout = new QVBoxLayout();
actualDropDown->setLayout(layout);
for (int i = 0; i < fValues.size(); i++)
{
DropdownOption *button = new DropdownOption(fValues[i],actualDropDown);
layout->addWidget(button);
}
QScrollArea *scroll = new QScrollArea(this);
scroll->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
scroll->setWidget(actualDropDown);
//20 px less than parent, to ensure that the options don't clip parent's border radius when scrolling up or down past the ends
scroll->setMaximumHeight(140);
scroll->move(0,10);
scroll->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOf f);
Couple of call outs, unlike in the HTML dropdown, I cannot 'snuggle' the options at the top and bottom of the parent widget, because I don't want them to have border-radius (which will show when they are highlighted after being clicked or hovered upon), and if the children don't have border-radius, the border radius of the parent (in this case, the widget which holds the options) gets clipped off when the children scroll through the ends. That's why I have set the widget at a height of 10 px from top and bottom.
Secondly, I have set the width of actualDropDown to be 30 px less than parent, because if I set to the same width, the scrollbar moves out of viewport.
Here's how it looks like currently:
11155
As you can see, I am unable to move the scrollbar inside the blue colored widget (in the example link, the options cover the parent widget breath wise, and the scroll bar appears over them, not outside them). Not to mention, QFrame does not let me access its scroll bar (which say QTextEdit does through the verticalScrollBar()->setStylesheet() method), thus I am not able to style it like the one in the example (which is actually how scroll bar appears in Mac by default).
How do I make it work, making it look just like the example dropdown? (I have set the backgrounds to blue, red, grey for understanding purpose, I will later reset them to match the ones in the link.)
I figured I will design the dropdown widget first, as the remaining task of showing and hiding on click will be trivial. So here is what I came up with:
class DropdownOption: public QPushButton
{
public:
DropdownOption(std::string aText, QWidget *aParent);
};
DropdownOption::DropdownOption(std::string aText, QWidget *aParent):
QPushButton(QString::fromStdString(aText),aParent)
{
this->setFixedHeight(30);
this->setCursor(Qt::PointingHandCursor);
this->setCheckable(false);
this->setStyleSheet("background: rgb(74,89,98); color: black; border-radius: 0px; text-align: left; padding-left: 5px; border-bottom: 1px solid black;");
}
//parent is the widget with all the options which will roll down when the dropdown widget showing the current value is clicked
QFrame *parent = new QFrame(this);
int width = 120;
parent->setParent(fParent);
//this width will be flexible, here I am setting to 160 for checking purpose
parent->setGeometry(40,40,width,160);
parent->setStyleSheet("border-radius: 5px; background:red;");
QFrame *actualDropDown = new QFrame(parent);
actualDropDown->setFixedWidth(width-30);
actualDropDown->setStyleSheet("background: blue;");
QVBoxLayout *layout = new QVBoxLayout();
actualDropDown->setLayout(layout);
for (int i = 0; i < fValues.size(); i++)
{
DropdownOption *button = new DropdownOption(fValues[i],actualDropDown);
layout->addWidget(button);
}
QScrollArea *scroll = new QScrollArea(this);
scroll->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
scroll->setWidget(actualDropDown);
//20 px less than parent, to ensure that the options don't clip parent's border radius when scrolling up or down past the ends
scroll->setMaximumHeight(140);
scroll->move(0,10);
scroll->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOf f);
Couple of call outs, unlike in the HTML dropdown, I cannot 'snuggle' the options at the top and bottom of the parent widget, because I don't want them to have border-radius (which will show when they are highlighted after being clicked or hovered upon), and if the children don't have border-radius, the border radius of the parent (in this case, the widget which holds the options) gets clipped off when the children scroll through the ends. That's why I have set the widget at a height of 10 px from top and bottom.
Secondly, I have set the width of actualDropDown to be 30 px less than parent, because if I set to the same width, the scrollbar moves out of viewport.
Here's how it looks like currently:
11155
As you can see, I am unable to move the scrollbar inside the blue colored widget (in the example link, the options cover the parent widget breath wise, and the scroll bar appears over them, not outside them). Not to mention, QFrame does not let me access its scroll bar (which say QTextEdit does through the verticalScrollBar()->setStylesheet() method), thus I am not able to style it like the one in the example (which is actually how scroll bar appears in Mac by default).
How do I make it work, making it look just like the example dropdown? (I have set the backgrounds to blue, red, grey for understanding purpose, I will later reset them to match the ones in the link.)