Как добавить кнопку или другой виджет для выбора в QComboBox?

Я хочу сделать что-то на подобии такого:

введите сюда описание изображения

Как это можно организовать?

Там в списке выпадающем есть нормальные кнопки с текстом и
мне как раз нужно организовать что-то на подобии такого.


Ответы (1 шт):

Автор решения: S. Nick

.. мне надо к примеру вместо текста добавить кнопку – nurd 14

Я не совсем понимаю, что будет дальше, но надо так надо.
Как вариант, это может выглядеть примерно так:

import os
from PyQt5.Qt import *


class ComboBoxWidget(QWidget):
    """Один элемент в listWidget."""
    itemOpSignal = pyqtSignal(QListWidgetItem, str)

    def __init__(self, text, listwidgetItem):
        super().__init__()
        self.text = text
        self.listwidgetItem = listwidgetItem
        self.initUi()

    def initUi(self):
        self.label = QLabel(self.text, self)
        
        self.toolButton = QToolButton(self)
        self.toolButton.setIcon(QIcon("Ok.png"))
        self.toolButton.setIconSize(QSize(50, 50))
        self.toolButton.setAutoRaise(True)
        self.toolButton.setToolTip(f'Button \n{self.text}')
        self.toolButton.clicked.connect(
            lambda: self.itemOpSignal.emit(self.listwidgetItem, self.text))

        self.horizontalLayout = QHBoxLayout(self)
        self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout.addWidget(self.toolButton)
        self.horizontalLayout.addWidget(self.label)
        spacerItem = QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem)


class ListQCombobox(QComboBox):
    def __init__(self, *args):
        super(ListQCombobox, self).__init__(*args)
        
        self.listw = QListWidget(self)
        self.setModel(self.listw.model())
        self.setView(self.listw)
        self.activated.connect(self.setTopText)

        self.w_cb = 0
        self.h_cb = 0
        self.label = QLabel('Сделайте выбор', self)
        self.label.setGeometry(0, 0, self.w_cb, self.h_cb) 
        self.label.setScaledContents(True)
        self.label.setAlignment(Qt.AlignCenter)

        qss = '''QComboBox QAbstractItemView::item {
                    height: 25px;
                }
                QListView::item:hover {
                    background: #BDD7FD;
                }'''
        self.setStyleSheet(qss)

    def refreshInputs(self, list_inputs):
        self.clear()
        # цикл для добавления элемента
        for num, path in enumerate(list_inputs):
            listwitem = QListWidgetItem(self.listw)
            listwitem.setToolTip(path)
            itemWidget = ComboBoxWidget(os.path.basename(path), listwitem)
            itemWidget.itemOpSignal.connect(self.buttonClicked)
            # background color
            if num % 2 == 0:
                listwitem.setBackground(QColor(255, 255, 255))         
            else:
                listwitem.setBackground(QColor(237, 243, 254))
            listwitem.setSizeHint(itemWidget.sizeHint())
            self.listw.addItem(listwitem)
            self.listw.setItemWidget(listwitem, itemWidget)

    def setTopText(self, index):
        list_text = self.fetchListsText()
        topText = list_text[index] 
        
        self.label.setText(topText)
        self.label.setStyleSheet('background-color: #4daf4a; color: #ffff33;')

    def refreshBackColors(self):
        for row in range(self.view().count()):
            if row % 2 == 0:
                self.view().item(row).setBackground(QColor(255, 255, 255))
            else:
                self.view().item(row).setBackground(QColor(237, 243, 254))
# !!!
    def buttonClicked(self, listwidgetItem, text):
        print(f'Вы нажали на кнопку: {text}. Делайте что нибудь.') #
        
    def fetchListsText(self):
        return [self.view().item(row).toolTip() for row in range(self.view().count())]

    def fetchCurrentText(self):
        if self.view().count():
            return self.view().item(0).toolTip()
        else:
            return ""

    def count(self):
        return self.view().count()


class Dialog(QDialog):
    def __init__(self, parent=None):
        super(Dialog, self).__init__(parent)

        list_new_inputs = [r"item 1",  r"item 2", r"item 3", r"item 4"]

        self.gridLayout = QGridLayout(self)
        self.label = QLabel("Combobox: ", self)
        self.gridLayout.addWidget(self.label, 0, 0, 1, 1)        

        self.comboBox = ListQCombobox(self)
        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.comboBox.sizePolicy().hasHeightForWidth())
        self.comboBox.setSizePolicy(sizePolicy)
        self.comboBox.setAcceptDrops(True)
        self.comboBox.setSizeAdjustPolicy(QComboBox.AdjustToMinimumContentsLength)
        self.gridLayout.addWidget(self.comboBox, 0, 1, 1, 1)
        
        self.comboBox.refreshInputs(list_new_inputs)
        
    def resizeEvent(self, event):
        self.comboBox.w_cb = self.comboBox.size().width() - 20
        self.comboBox.h_cb = self.comboBox.size().height()        
        self.comboBox.label.setGeometry(0, 0, self.comboBox.w_cb, self.comboBox.h_cb)
        
        if self.comboBox.label.text() == 'Сделайте выбор':
            self.comboBox.label.setStyleSheet('background-color: #66c2a5; color: #fff;')
        else:
            self.comboBox.label.setStyleSheet('background-color: #4daf4a; color: #ffff33;')


if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)
    dialog = Dialog()
    dialog.show()
    sys.exit(app.exec_())

введите сюда описание изображения

введите сюда описание изображения

→ Ссылка