ResCrove
ResCrove

Reputation: 39

How can I change color of each option in combo box?

How can I change color of each option in combo box in pyqt5? I want to yellow color, green, blue, etc.

enter image description here

This is my code.

self.combo_box = QComboBox(self)
self.combo_box.setGeometry(200, 150, 150, 30)
geek_list = ["Red", "Green", "Yellow", "Blue"]
self.combo_box.addItems(geek_list)
self.combo_box.setStyleSheet("QListView"
                             "{"
                             "background-color: red;"
                             "}")

`

Can you also tell me how to send value of this options to first window? For example if I choose red color how can I print number 1 in my first window

enter image description here

from PyQt5 import QtGui
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QPainter, QColor, QBrush
import sys

class AnotherWindow(QWidget):
    def __init__(self):
        super().__init__()
        layout = QVBoxLayout()
        self.label = QLabel()
        self.setWindowTitle("Zmiana tła")
        layout.addWidget(self.label)
        self.setLayout(layout)
        self.setGeometry(700, 700, 500, 500)

        self.combo_box = QComboBox(self)

        self.combo_box.setGeometry(10, 10, 150, 30)

        geek_list = ["Red", "Green", "Yellow", "Blue"]

        self.combo_box.addItems(geek_list)

        self.combo_box.setStyleSheet("QListView"
                                     "{"
                                     "background-color: red;"
                                     "}")

        self.combo_box.activated.connect(self.do_something)

    def do_something(self):
        value = self.combo_box.currentIndex()
        return value


class Window(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        layout = QGridLayout()
        self.setLayout(layout)
        self.setGeometry(100, 100, 360, 350)
        self.setWindowTitle("Dialogi")
        self.w = AnotherWindow()
        # create menu
        menubar = QMenuBar()
        layout.addWidget(menubar, 0, 0)
        actionFile = menubar.addMenu("Dialog")
        action = actionFile.addAction("New")
        action.triggered.connect(self.w.show)
        actionFile.addAction("Open")
        value_from_window_two = self.w.do_something()
        print(value_from_window_two)

Upvotes: 1

Views: 2054

Answers (1)

musicamante
musicamante

Reputation: 48434

QComboBox uses an internal QStandardItemModel (unless another model is explicitly set) which allows setting some properties for each item ("index") of the model.

Qt models provide some predefined roles which are data fields specific to each index, and among those roles there is the BackgroundRole.

You can then use setData for that role specifying the index and the value.

In the following example I'm using the string constructor of QColor which uses the standard SVG colors. Also note that:

  • if you want the current index selected from the user, you cannot get it when the widget is created (as you're trying to do at the end of the __init__ of Window);
  • you should use layouts more properly, for instance, you're not adding the combobox to the layout of AnotherWindow;
  • related to the above point, trying to set fixed geometries is usually discouraged, as you cannot know the screen layout and OS features on the target system; for instance, I have two screens, with the right one as the main one, and having windows that automatically are created on the left one is quite annoying;
  • if you want a menu bar, you should use a QMainWindow and call menuBar() instead; if you really need a basic QWidget, you should add the menubar using the dedicated layout function setMenuBar();
  • for this kind of situations, using a QDialog is preferred instead of a QWidget, as it allows using window modality and also provides the exec_() blocking function that ensures you can get the result as soon as the dialog is closed (accepted or rejected);
class AnotherWindow(QDialog):
    def __init__(self, parent):
        super().__init__(parent)
        layout = QVBoxLayout()
        self.label = QLabel()
        self.setWindowTitle("Zmiana tła")
        layout.addWidget(self.label)
        self.setLayout(layout)

        self.combo_box = QComboBox()
        layout.addWidget(self.combo_box)

        geek_list = ["red", "green", "yellow", "blue"]

        model = self.combo_box.model()
        for row, color in enumerate(geek_list):
            self.combo_box.addItem(color.title())
            model.setData(model.index(row, 0), QtGui.QColor(color), QtCore.Qt.BackgroundRole)

        self.combo_box.activated.connect(self.accept)

    def color(self):
        return self.combo_box.currentData(QtCore.Qt.BackgroundRole)

    def colorName(self):
        return self.combo_box.currentText()


class Window(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        self.setWindowTitle("Dialogi")
        actionFile = self.menuBar().addMenu("Dialog")
        action = actionFile.addAction("New")
        action.triggered.connect(self.selectColor)
        actionFile.addAction("Open")

    def selectColor(self):
        dialog = AnotherWindow(self)
        if dialog.exec_():
            print(dialog.color())
            print(dialog.colorName())

Upvotes: 4

Related Questions