4

For example for string "Elon Musk":

  • "Elon" text color is red;
  • "Musk" text color is green;

Thanks in advance for any help you can provide

Igor
  • 53
  • 3

3 Answers3

1

Yes, it can. In fact you can do whatever you want in there using QItemDelegate. Inside the delegate you can do all the crazy stuff you want, which not only includes coloring, but also buttons and other controls.

The Quantum Physicist
  • 24,987
  • 19
  • 103
  • 189
  • Thank you for response. I'm not sure where exactly to change colors, but I will be searching in direction of sub-classing of QStyledItemDelegate and reimplementing of paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) method. So changing "option" I hope to solve my problem – Igor Nov 23 '18 at 14:41
  • [`QStyledItemDelegate`](http://doc.qt.io/qt-5/qstyleditemdelegate.html#details) is recommended by the doc instead of `QItemDelegate`. – ymoreau Nov 23 '18 at 15:30
1

You can play with Qt::ItemDataRole to provide customisations. For this particular case -

#include <QApplication>
#include <QComboBox>
#include <QColor>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QComboBox box;
    box.addItem("Elon");
    box.addItem("Musk");

    box.setItemData(0, QColor(Qt::red), Qt::ForegroundRole);
    box.setItemData(1, QColor(Qt::green), Qt::ForegroundRole);

    box.show();

    return a.exec();
}

Screenshots for reference -

enter image description here enter image description here

Anmol Gautam
  • 949
  • 1
  • 12
  • 27
  • So detailed answer, thanks a lot. But gave a confusing description of my question, sorry for that. I meant: "Elon Musk" is the one item (not two) – Igor Nov 23 '18 at 14:36
  • But the question was about coloring strings in a single item. I.e. "Elon Musk" is the text in a single item, where "Elon (red) Musk (green)". – vahancho Nov 23 '18 at 14:36
  • 1
    @Igor you can have a look at https://stackoverflow.com/questions/2476581/qt-how-to-use-rich-text-in-a-qcombobox – Anmol Gautam Nov 23 '18 at 14:43
1

As an alternative approach to using delegates I would use a QLabel with rich text (HTML encoded) to color the combo box item text. I also need to implement an event filter to handle clicking (selecting) "custom" items. The following example demonstrates how to do it:

class Filter : public QObject
{
public:
  Filter(QComboBox *combo)
    :
      m_combo(combo)
  {}
protected:
  bool eventFilter(QObject *watched, QEvent * event) override
  {
    auto lbl = qobject_cast<QLabel *>(watched);
    if (lbl && event->type() == QEvent::MouseButtonRelease)
    {
      // Set the current index
      auto model = m_combo->model();
      for (int r = 0; r < model->rowCount(); ++r)
      {
        if (m_combo->view()->indexWidget(model->index(r, 0)) == lbl)
        {
          m_combo->setCurrentIndex(r);
          break;
        }
      }
      m_combo->hidePopup();
    }
    return false;
  }

private:
  QComboBox *m_combo;
};

And here is how to add "colored" items into combo box and handle them:

QComboBox box;
box.setEditable(true);
Filter filter(&box);

// Add two items: regular and colored.
box.addItem("A regular item");
box.addItem("Elon Musk");

// Handle the colored item. Color strings using HTML tags.
QLabel lbl("<font color=\"red\">Elon </font><font color=\"green\">Musk</font>", &box);
lbl.setAutoFillBackground(true);
lbl.installEventFilter(&filter);
box.view()->setIndexWidget(box.model()->index(1, 0), &lbl);

box.show();
vahancho
  • 20,808
  • 3
  • 47
  • 55