Exemplo n.º 1
0
    def paint(self, painter, option, index):
        rect = QRect(option.rect)

        is_selected = index.data(VariableSelectionModel.IsSelected)
        full_selection = index.model().sourceModel().is_full()
        if option.state & QStyle.State_MouseOver:
            if not full_selection or (full_selection and is_selected):
                txt = [" 添加 ", " 删除 "][is_selected]
                txtw = painter.fontMetrics().horizontalAdvance(txt)
                painter.save()
                painter.setPen(Qt.NoPen)
                painter.setBrush(option.palette.brush(QPalette.Button))
                brect = QRect(
                    rect.x() + rect.width() - 8 - txtw, rect.y(), txtw, rect.height()
                )
                painter.drawRoundedRect(brect, 4, 4)
                painter.setPen(option.palette.color(QPalette.ButtonText))
                painter.drawText(brect, Qt.AlignCenter, txt)
                painter.restore()

        painter.save()
        double_pen = painter.pen()
        double_pen.setWidth(2 * double_pen.width())
        if is_selected:
            next = index.sibling(index.row() + 1, index.column())
            if not next.isValid():
                painter.setPen(double_pen)
                painter.drawLine(rect.bottomLeft(), rect.bottomRight())
            elif not next.data(VariableSelectionModel.IsSelected):
                painter.drawLine(rect.bottomLeft(), rect.bottomRight())
        elif not index.row():
            down = QPoint(0, painter.pen().width())
            painter.setPen(double_pen)
            painter.drawLine(rect.topLeft() + down, rect.topRight() + down)
        else:
            prev = index.sibling(index.row() - 1, index.column())
            if prev.data(VariableSelectionModel.IsSelected):
                painter.drawLine(rect.topLeft(), rect.topRight())
        painter.restore()

        super().paint(painter, option, index)
Exemplo n.º 2
0
    def paint(self, painter, option, index):
        rect = QRect(option.rect)

        is_selected = index.data(VariableSelectionModel.IsSelected)
        if option.state & QStyle.State_MouseOver:
            txt = [" Add ", " Remove "][is_selected]
            txtw = painter.fontMetrics().width(txt)
            painter.save()
            painter.setPen(Qt.NoPen)
            painter.setBrush(QColor("#ccc"))
            brect = QRect(rect.x() + rect.width() - 8 - txtw, rect.y(), txtw,
                          rect.height())
            painter.drawRoundedRect(brect, 4, 4)
            painter.restore()
            painter.drawText(brect, Qt.AlignCenter, txt)

        painter.save()
        double_pen = painter.pen()
        double_pen.setWidth(2 * double_pen.width())
        if is_selected:
            next = index.sibling(index.row() + 1, index.column())
            if not next.isValid():
                painter.setPen(double_pen)
                painter.drawLine(rect.bottomLeft(), rect.bottomRight())
            elif not next.data(VariableSelectionModel.IsSelected):
                painter.drawLine(rect.bottomLeft(), rect.bottomRight())
        elif not index.row():
            down = QPoint(0, painter.pen().width())
            painter.setPen(double_pen)
            painter.drawLine(rect.topLeft() + down, rect.topRight() + down)
        else:
            prev = index.sibling(index.row() - 1, index.column())
            if prev.data(VariableSelectionModel.IsSelected):
                painter.drawLine(rect.topLeft(), rect.topRight())
        painter.restore()

        super().paint(painter, option, index)
Exemplo n.º 3
0
    def paint(self, painter, option, index):
        rect = QRect(option.rect)

        is_selected = index.data(VariableSelectionModel.IsSelected)
        if option.state & QStyle.State_MouseOver:
            txt = [" Add ", " Remove "][is_selected]
            txtw = painter.fontMetrics().width(txt)
            painter.save()
            painter.setPen(Qt.NoPen)
            painter.setBrush(QColor("#ccc"))
            brect = QRect(rect.x() + rect.width() - 8 - txtw, rect.y(),
                          txtw, rect.height())
            painter.drawRoundedRect(brect, 4, 4)
            painter.restore()
            painter.drawText(brect, Qt.AlignCenter, txt)

        painter.save()
        double_pen = painter.pen()
        double_pen.setWidth(2 * double_pen.width())
        if is_selected:
            next = index.sibling(index.row() + 1, index.column())
            if not next.isValid():
                painter.setPen(double_pen)
                painter.drawLine(rect.bottomLeft(), rect.bottomRight())
            elif not next.data(VariableSelectionModel.IsSelected):
                painter.drawLine(rect.bottomLeft(), rect.bottomRight())
        elif not index.row():
            down = QPoint(0, painter.pen().width())
            painter.setPen(double_pen)
            painter.drawLine(rect.topLeft() + down, rect.topRight() + down)
        else:
            prev = index.sibling(index.row() - 1, index.column())
            if prev.data(VariableSelectionModel.IsSelected):
                painter.drawLine(rect.topLeft(), rect.topRight())
        painter.restore()

        super().paint(painter, option, index)
Exemplo n.º 4
0
    def showPopup(self):
        # type: () -> None
        """
        Reimplemented from QComboBox.showPopup

        Popup up a customized view and filter edit line.

        Note
        ----
        The .popup(), .lineEdit(), .completer() of the base class are not used.
        """
        if self.__popup is not None:
            # We have user entered state that cannot be disturbed
            # (entered filter text, scroll offset, ...)
            return  # pragma: no cover

        if self.count() == 0:
            return

        opt = QStyleOptionComboBox()
        self.initStyleOption(opt)
        popup = QListView(
            uniformItemSizes=True,
            horizontalScrollBarPolicy=Qt.ScrollBarAlwaysOff,
            verticalScrollBarPolicy=Qt.ScrollBarAsNeeded,
            iconSize=self.iconSize(),
        )
        popup.setFocusProxy(self.__searchline)
        popup.setParent(self, Qt.Popup | Qt.FramelessWindowHint)
        popup.setItemDelegate(_ComboBoxListDelegate(popup))
        proxy = QSortFilterProxyModel(
            popup, filterCaseSensitivity=Qt.CaseInsensitive
        )
        proxy.setFilterKeyColumn(self.modelColumn())
        proxy.setSourceModel(self.model())
        popup.setModel(proxy)
        root = proxy.mapFromSource(self.rootModelIndex())
        popup.setRootIndex(root)

        self.__popup = popup
        self.__proxy = proxy
        self.__searchline.setText("")
        self.__searchline.setPlaceholderText("Filter...")
        self.__searchline.setVisible(True)
        self.__searchline.textEdited.connect(proxy.setFilterFixedString)

        style = self.style()  # type: QStyle

        popuprect_origin = style.subControlRect(
            QStyle.CC_ComboBox, opt, QStyle.SC_ComboBoxListBoxPopup, self
        )  # type: QRect
        popuprect_origin = QRect(
            self.mapToGlobal(popuprect_origin.topLeft()),
            popuprect_origin.size()
        )
        editrect = style.subControlRect(
            QStyle.CC_ComboBox, opt, QStyle.SC_ComboBoxEditField, self
        )  # type: QRect
        self.__searchline.setGeometry(editrect)
        desktop = QApplication.desktop()
        screenrect = desktop.availableGeometry(self)  # type: QRect

        # get the height for the view
        listrect = QRect()
        for i in range(min(proxy.rowCount(root), self.maxVisibleItems())):
            index = proxy.index(i, self.modelColumn(), root)
            if index.isValid():
                listrect = listrect.united(popup.visualRect(index))
            if listrect.height() >= screenrect.height():
                break
        window = popup.window()  # type: QWidget
        window.ensurePolished()
        if window.layout() is not None:
            window.layout().activate()
        else:
            QApplication.sendEvent(window, QEvent(QEvent.LayoutRequest))

        margins = qwidget_margin_within(popup.viewport(), window)
        height = (listrect.height() + 2 * popup.spacing() +
                  margins.top() + margins.bottom())

        popup_size = (QSize(popuprect_origin.width(), height)
                      .expandedTo(window.minimumSize())
                      .boundedTo(window.maximumSize())
                      .boundedTo(screenrect.size()))
        popuprect = QRect(popuprect_origin.bottomLeft(), popup_size)

        popuprect = dropdown_popup_geometry(
            popuprect, popuprect_origin, screenrect)
        popup.setGeometry(popuprect)

        current = proxy.mapFromSource(
            self.model().index(self.currentIndex(), self.modelColumn(),
                               self.rootModelIndex()))
        popup.setCurrentIndex(current)
        popup.scrollTo(current, QAbstractItemView.EnsureVisible)
        popup.show()
        popup.setFocus(Qt.PopupFocusReason)
        popup.installEventFilter(self)
        popup.viewport().installEventFilter(self)
        popup.viewport().setMouseTracking(True)
        self.update()
        self.__popupTimer.restart()
Exemplo n.º 5
0
    def showPopup(self):
        # type: () -> None
        """
        Reimplemented from QComboBox.showPopup

        Popup up a customized view and filter edit line.

        Note
        ----
        The .popup(), .lineEdit(), .completer() of the base class are not used.
        """
        if self.__popup is not None:
            # We have user entered state that cannot be disturbed
            # (entered filter text, scroll offset, ...)
            return  # pragma: no cover

        if self.count() == 0:
            return

        opt = QStyleOptionComboBox()
        self.initStyleOption(opt)
        popup = QListView(
            uniformItemSizes=True,
            horizontalScrollBarPolicy=Qt.ScrollBarAlwaysOff,
            verticalScrollBarPolicy=Qt.ScrollBarAsNeeded,
            iconSize=self.iconSize(),
        )
        popup.setFocusProxy(self.__searchline)
        popup.setParent(self, Qt.Popup | Qt.FramelessWindowHint)
        popup.setItemDelegate(_ComboBoxListDelegate(popup))
        proxy = QSortFilterProxyModel(
            popup, filterCaseSensitivity=Qt.CaseInsensitive
        )
        proxy.setFilterKeyColumn(self.modelColumn())
        proxy.setSourceModel(self.model())
        popup.setModel(proxy)
        root = proxy.mapFromSource(self.rootModelIndex())
        popup.setRootIndex(root)

        self.__popup = popup
        self.__proxy = proxy
        self.__searchline.setText("")
        self.__searchline.setPlaceholderText("Filter...")
        self.__searchline.setVisible(True)
        self.__searchline.textEdited.connect(proxy.setFilterFixedString)

        style = self.style()  # type: QStyle

        popuprect_origin = style.subControlRect(
            QStyle.CC_ComboBox, opt, QStyle.SC_ComboBoxListBoxPopup, self
        )  # type: QRect
        popuprect_origin = QRect(
            self.mapToGlobal(popuprect_origin.topLeft()),
            popuprect_origin.size()
        )
        editrect = style.subControlRect(
            QStyle.CC_ComboBox, opt, QStyle.SC_ComboBoxEditField, self
        )  # type: QRect
        self.__searchline.setGeometry(editrect)
        desktop = QApplication.desktop()
        screenrect = desktop.availableGeometry(self)  # type: QRect

        # get the height for the view
        listrect = QRect()
        for i in range(min(proxy.rowCount(root), self.maxVisibleItems())):
            index = proxy.index(i, self.modelColumn(), root)
            if index.isValid():
                listrect = listrect.united(popup.visualRect(index))
            if listrect.height() >= screenrect.height():
                break
        window = popup.window()  # type: QWidget
        window.ensurePolished()
        if window.layout() is not None:
            window.layout().activate()
        else:
            QApplication.sendEvent(window, QEvent(QEvent.LayoutRequest))

        margins = qwidget_margin_within(popup.viewport(), window)
        height = (listrect.height() + 2 * popup.spacing() +
                  margins.top() + margins.bottom())

        popup_size = (QSize(popuprect_origin.width(), height)
                      .expandedTo(window.minimumSize())
                      .boundedTo(window.maximumSize())
                      .boundedTo(screenrect.size()))
        popuprect = QRect(popuprect_origin.bottomLeft(), popup_size)

        popuprect = dropdown_popup_geometry(
            popuprect, popuprect_origin, screenrect)
        popup.setGeometry(popuprect)

        current = proxy.mapFromSource(
            self.model().index(self.currentIndex(), self.modelColumn(),
                               self.rootModelIndex()))
        popup.setCurrentIndex(current)
        popup.scrollTo(current, QAbstractItemView.EnsureVisible)
        popup.show()
        popup.setFocus(Qt.PopupFocusReason)
        popup.installEventFilter(self)
        popup.viewport().installEventFilter(self)
        popup.viewport().setMouseTracking(True)
        self.update()
        self.__popupTimer.restart()