1# -*- coding: utf-8 -*- 2 3""" 4*************************************************************************** 5 CheckBoxesPanel.py 6 --------------------- 7 Date : January 2015 8 Copyright : (C) 2015 by Arnaud Morvan 9 Email : arnaud dot morvan at camptocamp dot com 10 Contributors : Arnaud Morvan 11*************************************************************************** 12* * 13* This program is free software; you can redistribute it and/or modify * 14* it under the terms of the GNU General Public License as published by * 15* the Free Software Foundation; either version 2 of the License, or * 16* (at your option) any later version. * 17* * 18*************************************************************************** 19""" 20 21__author__ = 'Arnaud Morvan' 22__date__ = 'January 2015' 23__copyright__ = '(C) 2015, Arnaud Morvan' 24 25from qgis.PyQt.QtCore import Qt 26from qgis.PyQt.QtWidgets import ( 27 QCheckBox, 28 QRadioButton, 29 QGridLayout, 30 QButtonGroup, 31 QSizePolicy, 32 QSpacerItem, 33 QWidget, 34 QMenu, 35 QAction 36) 37from qgis.PyQt.QtGui import QCursor 38 39 40class CheckboxesPanel(QWidget): 41 42 def __init__(self, options, multiple, columns=2, parent=None): 43 super(CheckboxesPanel, self).__init__(parent) 44 45 self._options = [] 46 for i, option in enumerate(options): 47 if isinstance(option, str): 48 self._options.append((i, option)) 49 else: 50 self.options.append(option) 51 self._multiple = multiple 52 self._buttons = [] 53 rows = len(options) / columns 54 55 self._buttonGroup = QButtonGroup() 56 self._buttonGroup.setExclusive(not multiple) 57 layout = QGridLayout() 58 layout.setContentsMargins(0, 0, 0, 0) 59 layout.setMargin(0) 60 for i, (v, t) in enumerate(self._options): 61 if multiple: 62 button = QCheckBox(t) 63 else: 64 button = QRadioButton(t) 65 self._buttons.append((v, button)) 66 self._buttonGroup.addButton(button, i) 67 layout.addWidget(button, i % rows, i / rows) 68 layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum), 69 0, columns) 70 self.setLayout(layout) 71 72 if multiple: 73 self.setContextMenuPolicy(Qt.CustomContextMenu) 74 self.customContextMenuRequested.connect(self.showPopupMenu) 75 76 def showPopupMenu(self): 77 popup_menu = QMenu() 78 select_all_action = QAction(self.tr('Select All'), popup_menu) 79 select_all_action.triggered.connect(self.selectAll) 80 clear_all_action = QAction(self.tr('Clear Selection'), popup_menu) 81 clear_all_action.triggered.connect(self.deselectAll) 82 popup_menu.addAction(select_all_action) 83 popup_menu.addAction(clear_all_action) 84 popup_menu.exec_(QCursor.pos()) 85 86 def selectAll(self): 87 for (v, button) in self._buttons: 88 button.setChecked(True) 89 90 def deselectAll(self): 91 for (v, button) in self._buttons: 92 button.setChecked(False) 93 94 def value(self): 95 if self._multiple: 96 return [ 97 v 98 for (v, checkbox) in self._buttons 99 if checkbox.isChecked() 100 ] 101 else: 102 return self._options[self._buttonGroup.checkedId()][0] 103 104 def setValue(self, value): 105 for (v, button) in self._buttons: 106 if self._multiple: 107 button.setChecked(v in value) 108 else: 109 button.setChecked(v == value) 110