Russian Qt Forum
Апрель 20, 2024, 19:15 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: QComboBox с множественным выбором  (Прочитано 5441 раз)
sergs
Гость
« : Март 14, 2017, 12:42 »

Потребовался выпадающий список с возможностью выбора нескольких элементов. Создал модель, которая автоматически устанавливает всем элементам флажок Qt.ItemIsUserCheckable. Создал класс-наследник QComboBox, использующий эту модель. Вот код
Код:
class CheckableItemsModel(QStandardItemModel):

    checkStateChanged = pyqtSignal()

    def __init__(self, parent=None):
        super(CheckableItemsModel, self).__init__(parent)

    def flags(self, index):
        return super(CheckableItemsModel, self).flags(index) | Qt.ItemIsUserCheckable

    def data(self, index, role=Qt.DisplayRole):
        value = super(CheckableItemsModel, self).data(index, role)
        if index.isValid() and role == Qt.CheckStateRole and value is None:
            value = Qt.Unchecked
        return value

    def setData(self, index, value, role=Qt.EditRole):
        ok = super(CheckableItemsModel, self).setData(index, value, role)
        if ok and role == Qt.CheckStateRole:
            self.checkStateChanged.emit()

        return ok


class CheckComboBox(QComboBox):

    checkedItemsChanged = pyqtSignal(list)

    def __init__(self, parent=None):
        super(CheckComboBox, self).__init__(parent)

        # workaround for Mac and GTK to show checkboxes
        self.setStyleSheet('QComboBox { combobox-popup: 1px }')

        self.defaultText = ''
        self.separator = ','
        self.containerPressed = False

        self.checkableModel = CheckableItemsModel(self)
        self.setModel(self.checkableModel)

        self.model().checkStateChanged.connect(self.updateCheckedItems)
        self.model().rowsInserted.connect(self.updateCheckedItems)
        self.model().rowsRemoved.connect(self.updateCheckedItems)

        self.activated.connect(self.toggleCheckState)

    def itemCheckState(self, index):
        return self.itemData(index, Qt.CheckStateRole)

    def setItemCheckState(self, index, state):
        self.setItemData(index, state, Qt.CheckStateRole)

    def checkedItems(self):
        items = list()
        if self.model():
            index = self.model().index(0, self.modelColumn(), self.rootModelIndex())
            indexes = self.model().match(index, Qt.CheckStateRole, Qt.Checked, -1, Qt.MatchExactly)
            for i in indexes:
                items.append(index.data())

        return items

    def setCheckedItems(self, items):
        for i in items:
            index = self.findText(i)
            self.setItemCheckState(index, Qt.Checked if index != -1 else Qt.Unchecked)

    def updateCheckedItems(self):
        items = self.checkedItems()
        if len(items) == 0:
            self.setEditText(self.defaultText)
        else:
            self.setEditText(self.separator.join(items))

        self.checkedItemsChanged.emit(items)

    def toggleCheckState(self, index):
        value = self.itemData(index, Qt.CheckStateRole)
        if value is not None:
            self.setItemData(index, Qt.Checked if value == Qt.Unchecked else Qt.Unchecked, Qt.CheckStateRole)

Элементы выпадающего списка имеют чекбоксы, но с множественным выбором затык. Сейчас при клике на любой элемент его флажок устанавливается и выпадающий список сразу же закрывается. В какую сторону смотреть, может, что-то не так с моим кодом?

И вторая проблема. В Mac и в окружении GTK почему-то не видны чекбоксы, можно ли как-то это исправить, например, при помощи стиля CSS?

P.S. Про QListWidget/QListView знаю, нужен именно выпадающий список.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.045 секунд. Запросов: 20.