I would like to make a combo box that selects some contents associated with colors. I want the background of the contents to show the color. I have achieved this:
QList<QString> names;
QList<QColor> bgColors;
QList<QColor> fgColors;
QComboBox* colorComboBox = new QComboBox();
for(int i = 0; i < names.size(); ++i)
{
colorComboBox->addItem(names.at(i), bgColors.at(i));
const QModelIndex idx = colorComboBox->model()->index(i, 0);
colorComboBox->model()->setData(idx, bgColors.at(i), Qt::BackgroundColorRole);
colorComboBox->model()->setData(idx, fgColors.at(i), Qt::ForegroundRole);
}
The combo box shows the text I want, with the background color I want (not as delicate as the ColorEditorFactory example, which only shows a small rectangle next to the text, but this is how I wanted it).
What I need:
Once a row/color is selected, I would like the combo box to show the color. As is now, the combo box when closed shows the text but not the color.
How can I change the color of the combo box header ? (I mam calling it header but it may have a different name, not sure - the part that shows above the table used for selection and when the combo box is closed)
Edit: I tried to set a stylesheet in a slot on currentIndexChanged
:
setStyleSheet("QComboBox { color: " + fgColor +
"; background-color: " + bgColor + "; }");
Result: it changed the entire combo box in that color, forgetting the initial colors.
setStyleSheet("QComboBox:!on { color: " + fgColor +
"; background-color: " + bgColor + "; }");
Result: it changed the color nicely when not selected - but the highlight and the header are gray and hard to read, I wish I could change it also. And when I hover, the entire combo color changes to the last one I set.
The answer may be in stylesheets - if I can figure out what property applies to the header.
If I understand well, you want to change the color of the QComboBox header as soon as you click on an item. I have this code which is working for me :
In the .cpp file :
myClass::init() // called in the constructor of myClass
{
names.clear();
names.append("One");
names.append("Two");
names.append("Three");
bgColors.clear();
bgColors.append(QColor("blue"));
bgColors.append(QColor("red"));
bgColors.append(QColor("green"));
fgColors.clear();
fgColors.append(QColor("yellow"));
fgColors.append(QColor("magenta"));
fgColors.append(QColor("cyan"));
colorComboBox = new QComboBox();
colorComboBox->setItemDelegate(new SelectionKillerDelegate);
// don't know why but this line seems important; uncomment it,
// and the text in the QComboBox (not the items) will be highlighted
colorComboBox->setStyleSheet("QComboBox { border-radius: 1px; }");
for(int i = 0; i < names.size(); ++i)
{
colorComboBox->addItem(names.at(i), bgColors.at(i));
const QModelIndex idx = colorComboBox->model()->index(i, 0);
colorComboBox->model()->setData(idx, bgColors.at(i), Qt::BackgroundColorRole);
colorComboBox->model()->setData(idx, fgColors.at(i), Qt::ForegroundRole);
}
connect(colorComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(comboBoxChanged(int)));
}
void myClass::comboBoxChanged(int index)
{
QColor forecolor = (QColor) (colorComboBox->itemData(index, Qt::ForegroundRole).value<QColor>());
QString fgColor = forecolor.name(QColor::HexRgb);
QColor backcolor = (QColor) (colorComboBox->itemData(index, Qt::BackgroundRole).value<QColor>());
QString bgColor = backcolor.name(QColor::HexRgb);
setStyleSheet("QComboBox { color: " + fgColor + "; background-color: " + bgColor + "; }");
}
In the .h file (thanks to this answer for the subclass of QItemDelegate
which allows you to have items of QComboBox selected but not highlighted) :
class SelectionKillerDelegate : public QItemDelegate
{
virtual void paint(QPainter *painter,
const QStyleOptionViewItem &option,
const QModelIndex &index) const override
{
QStyleOptionViewItem myOption = option;
myOption.state &= (~QStyle::State_Selected);
QItemDelegate::paint (painter, myOption, index);
}
};
private :
QComboBox* colorComboBox;
QList<QString> names;
QList<QColor> bgColors;
QList<QColor> fgColors;
public slots :
void comboBoxChanged(int);
I hope it will work for you too.