QGIS/python/plugins/processing/modeler/ModelerGraphicItem.py

487 lines
22 KiB
Python
Raw Normal View History

2012-10-04 19:33:47 +02:00
# -*- coding: utf-8 -*-
"""
***************************************************************************
ModelerGraphicItem.py
---------------------
Date : August 2012
Copyright : (C) 2012 by Victor Olaya
Email : volayaf at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************
"""
2012-10-04 19:33:47 +02:00
__author__ = 'Victor Olaya'
__date__ = 'August 2012'
__copyright__ = '(C) 2012, Victor Olaya'
2012-10-04 19:33:47 +02:00
# This will get replaced with a git SHA1 when you do a git archive
2012-10-04 19:33:47 +02:00
__revision__ = '$Format:%H$'
2012-09-15 18:25:25 +03:00
import os
import math
2016-04-22 10:38:48 +02:00
from qgis.PyQt.QtCore import Qt, QPointF, QRectF
2017-03-04 19:41:23 +01:00
from qgis.PyQt.QtGui import QFont, QFontMetricsF, QPen, QBrush, QColor, QPolygonF, QPicture, QPainter
2016-04-22 10:38:48 +02:00
from qgis.PyQt.QtWidgets import QGraphicsItem, QMessageBox, QMenu
from qgis.PyQt.QtSvg import QSvgRenderer
2017-06-13 16:05:59 +10:00
from qgis.core import (QgsProcessingParameterDefinition,
QgsProcessingModelParameter,
QgsProcessingModelOutput,
QgsProcessingModelChildAlgorithm,
2017-06-13 16:05:59 +10:00
QgsProcessingModelAlgorithm)
from processing.modeler.ModelerParameterDefinitionDialog import ModelerParameterDefinitionDialog
from processing.modeler.ModelerParametersDialog import ModelerParametersDialog
pluginPath = os.path.split(os.path.dirname(__file__))[0]
2012-09-15 18:25:25 +03:00
class ModelerGraphicItem(QGraphicsItem):
2012-09-15 18:25:25 +03:00
2013-04-17 13:16:34 +02:00
BOX_HEIGHT = 30
2012-09-15 18:25:25 +03:00
BOX_WIDTH = 200
2017-06-15 07:24:15 +10:00
def __init__(self, element, model, controls, scene=None):
super(ModelerGraphicItem, self).__init__(None)
self.controls = controls
2012-09-15 18:25:25 +03:00
self.model = model
2017-06-15 07:24:15 +10:00
self.scene = scene
2012-09-15 18:25:25 +03:00
self.element = element
if isinstance(element, QgsProcessingModelParameter):
svg = QSvgRenderer(os.path.join(pluginPath, 'images', 'input.svg'))
self.picture = QPicture()
painter = QPainter(self.picture)
svg.render(painter)
self.pixmap = None
2017-06-13 16:05:59 +10:00
self.text = self.model.parameterDefinition(element.parameterName()).description()
elif isinstance(element, QgsProcessingModelOutput):
# Output name
svg = QSvgRenderer(os.path.join(pluginPath, 'images', 'output.svg'))
self.picture = QPicture()
painter = QPainter(self.picture)
svg.render(painter)
self.pixmap = None
self.text = element.name()
2012-09-15 18:25:25 +03:00
else:
2017-06-13 16:05:59 +10:00
self.text = element.description()
self.pixmap = element.algorithm().icon().pixmap(15, 15)
2012-09-15 18:25:25 +03:00
self.arrows = []
self.setFlag(QGraphicsItem.ItemIsMovable, True)
self.setFlag(QGraphicsItem.ItemIsSelectable, True)
self.setFlag(QGraphicsItem.ItemSendsGeometryChanges, True)
2012-09-15 18:25:25 +03:00
self.setZValue(1000)
2013-05-15 20:42:04 +02:00
if not isinstance(element, QgsProcessingModelOutput) and controls:
svg = QSvgRenderer(os.path.join(pluginPath, 'images', 'edit.svg'))
picture = QPicture()
painter = QPainter(picture)
svg.render(painter)
2017-03-04 19:41:23 +01:00
pt = QPointF(ModelerGraphicItem.BOX_WIDTH / 2 -
FlatButtonGraphicItem.WIDTH / 2,
ModelerGraphicItem.BOX_HEIGHT / 2 -
FlatButtonGraphicItem.HEIGHT / 2)
self.editButton = FlatButtonGraphicItem(picture, pt, self.editElement)
self.editButton.setParentItem(self)
svg = QSvgRenderer(os.path.join(pluginPath, 'images', 'delete.svg'))
picture = QPicture()
painter = QPainter(picture)
svg.render(painter)
2017-03-04 19:41:23 +01:00
pt = QPointF(ModelerGraphicItem.BOX_WIDTH / 2 -
FlatButtonGraphicItem.WIDTH / 2,
FlatButtonGraphicItem.HEIGHT / 2 -
ModelerGraphicItem.BOX_HEIGHT / 2)
self.deleteButton = FlatButtonGraphicItem(picture, pt,
self.removeElement)
self.deleteButton.setParentItem(self)
2013-05-15 20:42:04 +02:00
if isinstance(element, QgsProcessingModelChildAlgorithm):
2017-06-13 16:05:59 +10:00
alg = element.algorithm()
2017-06-13 15:51:40 +10:00
if [a for a in alg.parameterDefinitions() if not a.isDestination()]:
2014-07-02 07:46:03 +02:00
pt = self.getLinkPointForParameter(-1)
pt = QPointF(0, pt.y())
if controls:
2017-06-13 16:05:59 +10:00
self.inButton = FoldButtonGraphicItem(pt, self.foldInput, self.element.parametersCollapsed())
self.inButton.setParentItem(self)
2017-06-13 15:51:40 +10:00
if alg.outputDefinitions():
2013-04-17 13:16:34 +02:00
pt = self.getLinkPointForOutput(-1)
pt = QPointF(0, pt.y())
if controls:
2017-06-13 16:05:59 +10:00
self.outButton = FoldButtonGraphicItem(pt, self.foldOutput, self.element.outputsCollapsed())
self.outButton.setParentItem(self)
2013-05-15 20:42:04 +02:00
2013-04-17 13:16:34 +02:00
def foldInput(self, folded):
2017-06-13 16:05:59 +10:00
self.element.setParametersCollapsed(folded)
#also need to update the model's stored component
self.model.childAlgorithm(self.element.childId()).setParametersCollapsed(folded)
2013-05-15 20:42:04 +02:00
self.prepareGeometryChange()
2017-06-13 16:05:59 +10:00
if self.element.algorithm().outputDefinitions():
2013-04-17 13:16:34 +02:00
pt = self.getLinkPointForOutput(-1)
pt = QPointF(0, pt.y())
2013-04-17 13:16:34 +02:00
self.outButton.position = pt
for arrow in self.arrows:
arrow.updatePath()
2013-04-17 13:16:34 +02:00
self.update()
2013-05-15 20:42:04 +02:00
2013-04-17 13:16:34 +02:00
def foldOutput(self, folded):
2017-06-13 16:05:59 +10:00
self.element.setOutputsCollapsed(folded)
# also need to update the model's stored component
self.model.childAlgorithm(self.element.childId()).setOutputsCollapsed(folded)
2013-05-15 20:42:04 +02:00
self.prepareGeometryChange()
for arrow in self.arrows:
arrow.updatePath()
2013-05-15 20:42:04 +02:00
self.update()
2012-09-15 18:25:25 +03:00
def addArrow(self, arrow):
self.arrows.append(arrow)
def boundingRect(self):
font = QFont('Verdana', 8)
font.setPixelSize(12)
fm = QFontMetricsF(font)
unfolded = isinstance(self.element, QgsProcessingModelChildAlgorithm) and not self.element.parametersCollapsed()
2017-06-13 16:05:59 +10:00
numParams = len([a for a in self.element.algorithm().parameterDefinitions() if not a.isDestination()]) if unfolded else 0
unfolded = isinstance(self.element, QgsProcessingModelChildAlgorithm) and not self.element.outputsCollapsed()
2017-06-13 16:05:59 +10:00
numOutputs = len(self.element.algorithm().outputDefinitions()) if unfolded else 0
2014-07-02 07:46:03 +02:00
hUp = fm.height() * 1.2 * (numParams + 2)
hDown = fm.height() * 1.2 * (numOutputs + 2)
rect = QRectF(-(ModelerGraphicItem.BOX_WIDTH + 2) / 2,
-(ModelerGraphicItem.BOX_HEIGHT + 2) / 2 - hUp,
ModelerGraphicItem.BOX_WIDTH + 2,
ModelerGraphicItem.BOX_HEIGHT + hDown + hUp)
2012-09-15 18:25:25 +03:00
return rect
def mouseDoubleClickEvent(self, event):
self.editElement()
2012-09-15 18:25:25 +03:00
def contextMenuEvent(self, event):
if isinstance(self.element, QgsProcessingModelOutput):
return
popupmenu = QMenu()
removeAction = popupmenu.addAction('Remove')
2012-09-15 18:25:25 +03:00
removeAction.triggered.connect(self.removeElement)
editAction = popupmenu.addAction('Edit')
2014-07-02 07:46:03 +02:00
editAction.triggered.connect(self.editElement)
if isinstance(self.element, QgsProcessingModelChildAlgorithm):
2017-06-13 16:05:59 +10:00
if not self.element.isActive():
removeAction = popupmenu.addAction('Activate')
2012-09-15 18:25:25 +03:00
removeAction.triggered.connect(self.activateAlgorithm)
else:
deactivateAction = popupmenu.addAction('Deactivate')
2012-09-15 18:25:25 +03:00
deactivateAction.triggered.connect(self.deactivateAlgorithm)
popupmenu.exec_(event.screenPos())
def deactivateAlgorithm(self):
2017-06-20 15:31:53 +10:00
self.model.deactivateChildAlgorithm(self.element.childId())
2017-06-15 07:24:15 +10:00
self.scene.dialog.repaintModel()
2012-09-15 18:25:25 +03:00
def activateAlgorithm(self):
2017-06-20 15:31:53 +10:00
if self.model.activateChildAlgorithm(self.element.childId()):
2017-06-15 07:24:15 +10:00
self.scene.dialog.repaintModel()
else:
QMessageBox.warning(None, 'Could not activate Algorithm',
'The selected algorithm depends on other currently non-active algorithms.\n'
'Activate them them before trying to activate it.')
2012-09-15 18:25:25 +03:00
def editElement(self):
if isinstance(self.element, QgsProcessingModelParameter):
dlg = ModelerParameterDefinitionDialog(self.model,
2017-06-13 16:05:59 +10:00
param=self.model.parameterDefinition(self.element.parameterName()))
2012-09-15 18:25:25 +03:00
dlg.exec_()
if dlg.param is not None:
2017-06-20 19:23:21 +10:00
self.model.removeModelParameter(self.element.parameterName())
2017-06-13 16:05:59 +10:00
self.element.setParameterName(dlg.param.name())
2017-06-23 15:08:14 +10:00
self.element.setDescription(dlg.param.name())
2017-06-20 19:23:21 +10:00
self.model.addModelParameter(dlg.param, self.element)
2017-06-13 13:22:19 +10:00
self.text = dlg.param.description()
self.scene.dialog.repaintModel()
elif isinstance(self.element, QgsProcessingModelChildAlgorithm):
2017-06-13 15:51:40 +10:00
dlg = None
try:
2017-06-13 16:05:59 +10:00
dlg = self.element.algorithm().getCustomModelerParametersDialog(self.model, self.element.childId())
2017-06-13 15:51:40 +10:00
except:
pass
2012-09-15 18:25:25 +03:00
if not dlg:
2017-06-13 16:05:59 +10:00
dlg = ModelerParametersDialog(self.element.algorithm(), self.model, self.element.childId())
2012-09-15 18:25:25 +03:00
dlg.exec_()
if dlg.alg is not None:
2017-06-13 16:05:59 +10:00
dlg.alg.setChildId(self.element.childId())
2017-06-20 15:31:53 +10:00
self.updateAlgorithm(dlg.alg)
2017-06-15 07:24:15 +10:00
self.scene.dialog.repaintModel()
2012-09-15 18:25:25 +03:00
2017-06-20 15:31:53 +10:00
def updateAlgorithm(self, alg):
existing_child = self.model.childAlgorithm(alg.childId())
alg.setPosition(existing_child.position())
alg.setParametersCollapsed(existing_child.parametersCollapsed())
alg.setOutputsCollapsed(existing_child.outputsCollapsed())
for i, out in enumerate(alg.modelOutputs().keys()):
alg.modelOutput(out).setPosition(alg.modelOutput(out).position() or
alg.position() + QPointF(
ModelerGraphicItem.BOX_WIDTH,
(i + 1.5) * ModelerGraphicItem.BOX_HEIGHT))
self.model.setChildAlgorithm(alg)
2012-09-15 18:25:25 +03:00
def removeElement(self):
if isinstance(self.element, QgsProcessingModelParameter):
2017-06-20 19:23:21 +10:00
if self.model.childAlgorithmsDependOnParameter(self.element.parameterName()):
QMessageBox.warning(None, 'Could not remove input',
'Algorithms depend on the selected input.\n'
'Remove them before trying to remove it.')
elif self.model.otherParametersDependOnParameter(self.element.parameterName()):
QMessageBox.warning(None, 'Could not remove input',
'Other inputs depend on the selected input.\n'
'Remove them before trying to remove it.')
else:
2017-06-20 19:23:21 +10:00
self.model.removeModelParameter(self.element.parameterName())
2017-06-15 07:24:15 +10:00
self.scene.dialog.haschanged = True
self.scene.dialog.repaintModel()
elif isinstance(self.element, QgsProcessingModelChildAlgorithm):
2017-06-15 07:24:15 +10:00
if not self.model.removeChildAlgorithm(self.element.childId()):
QMessageBox.warning(None, 'Could not remove element',
'Other elements depend on the selected one.\n'
'Remove them before trying to remove it.')
else:
2017-06-15 07:24:15 +10:00
self.scene.dialog.haschanged = True
self.scene.dialog.repaintModel()
2012-09-15 18:25:25 +03:00
def getAdjustedText(self, text):
font = QFont('Verdana', 8)
font.setPixelSize(12)
fm = QFontMetricsF(font)
2012-09-15 18:25:25 +03:00
w = fm.width(text)
2013-04-17 13:16:34 +02:00
if w < self.BOX_WIDTH - 25 - FlatButtonGraphicItem.WIDTH:
2012-09-15 18:25:25 +03:00
return text
text = text[0:-3] + ''
2012-09-15 18:25:25 +03:00
w = fm.width(text)
while w > self.BOX_WIDTH - 25 - FlatButtonGraphicItem.WIDTH:
text = text[0:-4] + ''
2012-09-15 18:25:25 +03:00
w = fm.width(text)
return text
def paint(self, painter, option, widget=None):
rect = QRectF(-(ModelerGraphicItem.BOX_WIDTH + 2) / 2.0,
-(ModelerGraphicItem.BOX_HEIGHT + 2) / 2.0,
ModelerGraphicItem.BOX_WIDTH + 2,
ModelerGraphicItem.BOX_HEIGHT + 2)
if isinstance(self.element, QgsProcessingModelParameter):
color = QColor(238, 242, 131)
stroke = QColor(234, 226, 118)
selected = QColor(116, 113, 68)
elif isinstance(self.element, QgsProcessingModelChildAlgorithm):
color = QColor(255, 255, 255)
stroke = Qt.gray
selected = QColor(50, 50, 50)
else:
color = QColor(172, 196, 114)
stroke = QColor(90, 140, 90)
selected = QColor(42, 65, 42)
if self.isSelected():
stroke = selected
color = color.darker(110)
2017-03-04 19:41:23 +01:00
painter.setPen(QPen(stroke, 0)) # 0 width "cosmetic" pen
painter.setBrush(QBrush(color, Qt.SolidPattern))
2012-09-15 18:25:25 +03:00
painter.drawRect(rect)
font = QFont('Verdana', 8)
font.setPixelSize(12)
2012-09-15 18:25:25 +03:00
painter.setFont(font)
painter.setPen(QPen(Qt.black))
text = self.getAdjustedText(self.text)
if isinstance(self.element, QgsProcessingModelChildAlgorithm) and not self.element.isActive():
painter.setPen(QPen(Qt.gray))
text = text + "\n(deactivated)"
fm = QFontMetricsF(font)
2012-09-15 18:25:25 +03:00
text = self.getAdjustedText(self.text)
h = fm.ascent()
pt = QPointF(-ModelerGraphicItem.BOX_WIDTH / 2 + 25, ModelerGraphicItem.BOX_HEIGHT / 2.0 - h + 1)
2012-09-15 18:25:25 +03:00
painter.drawText(pt, text)
painter.setPen(QPen(Qt.black))
if isinstance(self.element, QgsProcessingModelChildAlgorithm):
2013-06-12 00:05:52 +02:00
h = -(fm.height() * 1.2)
h = h - ModelerGraphicItem.BOX_HEIGHT / 2.0 + 5
pt = QPointF(-ModelerGraphicItem.BOX_WIDTH / 2 + 25, h)
painter.drawText(pt, 'In')
2013-04-17 13:16:34 +02:00
i = 1
2017-06-13 16:05:59 +10:00
if not self.element.parametersCollapsed():
for param in [p for p in self.element.algorithm().parameterDefinitions() if not p.isDestination()]:
2017-05-16 16:36:00 +10:00
if not param.flags() & QgsProcessingParameterDefinition.FlagHidden:
text = self.getAdjustedText(param.description())
h = -(fm.height() * 1.2) * (i + 1)
h = h - ModelerGraphicItem.BOX_HEIGHT / 2.0 + 5
2017-03-04 19:41:23 +01:00
pt = QPointF(-ModelerGraphicItem.BOX_WIDTH / 2 + 33, h)
painter.drawText(pt, text)
2014-07-02 07:46:03 +02:00
i += 1
h = fm.height() * 1.1
2013-05-15 20:42:04 +02:00
h = h + ModelerGraphicItem.BOX_HEIGHT / 2.0
pt = QPointF(-ModelerGraphicItem.BOX_WIDTH / 2 + 25, h)
painter.drawText(pt, 'Out')
2017-06-13 16:05:59 +10:00
if not self.element.outputsCollapsed():
for i, out in enumerate(self.element.algorithm().outputDefinitions()):
2017-05-16 16:36:00 +10:00
text = self.getAdjustedText(out.description())
h = fm.height() * 1.2 * (i + 2)
h = h + ModelerGraphicItem.BOX_HEIGHT / 2.0
2017-03-04 19:41:23 +01:00
pt = QPointF(-ModelerGraphicItem.BOX_WIDTH / 2 + 33, h)
painter.drawText(pt, text)
if self.pixmap:
painter.drawPixmap(-(ModelerGraphicItem.BOX_WIDTH / 2.0) + 3, -8,
self.pixmap)
elif self.picture:
painter.drawPicture(-(ModelerGraphicItem.BOX_WIDTH / 2.0) + 3, -8,
self.picture)
2012-09-15 18:25:25 +03:00
2013-04-17 13:16:34 +02:00
def getLinkPointForParameter(self, paramIndex):
offsetX = 25
if isinstance(self.element, QgsProcessingModelChildAlgorithm) and self.element.parametersCollapsed():
2013-04-17 13:16:34 +02:00
paramIndex = -1
offsetX = 17
if isinstance(self.element, QgsProcessingModelParameter):
paramIndex = -1
offsetX = 0
font = QFont('Verdana', 8)
font.setPixelSize(12)
fm = QFontMetricsF(font)
if isinstance(self.element, QgsProcessingModelChildAlgorithm):
2013-06-12 00:05:52 +02:00
h = -(fm.height() * 1.2) * (paramIndex + 2) - fm.height() / 2.0 + 8
h = h - ModelerGraphicItem.BOX_HEIGHT / 2.0
else:
h = 0
return QPointF(-ModelerGraphicItem.BOX_WIDTH / 2 + offsetX, h)
2013-05-15 20:42:04 +02:00
def getLinkPointForOutput(self, outputIndex):
if isinstance(self.element, QgsProcessingModelChildAlgorithm) and self.element.algorithm().outputDefinitions():
2017-06-13 16:05:59 +10:00
outputIndex = (outputIndex if not self.element.outputsCollapsed() else -1)
text = self.getAdjustedText(self.element.algorithm().outputDefinitions()[outputIndex].description())
font = QFont('Verdana', 8)
font.setPixelSize(12)
fm = QFontMetricsF(font)
w = fm.width(text)
h = fm.height() * 1.2 * (outputIndex + 1) + fm.height() / 2.0
2013-06-12 00:05:52 +02:00
y = h + ModelerGraphicItem.BOX_HEIGHT / 2.0 + 5
2017-03-04 19:41:23 +01:00
x = (-ModelerGraphicItem.BOX_WIDTH / 2 + 33 + w + 5
2017-06-13 16:05:59 +10:00
if not self.element.outputsCollapsed()
2017-03-04 19:41:23 +01:00
else 10)
return QPointF(x, y)
2013-04-17 13:16:34 +02:00
else:
return QPointF(0, 0)
2012-09-15 18:25:25 +03:00
def itemChange(self, change, value):
if change == QGraphicsItem.ItemPositionHasChanged:
2012-09-15 18:25:25 +03:00
for arrow in self.arrows:
arrow.updatePath()
2017-06-13 16:05:59 +10:00
self.element.setPosition(self.pos())
# also need to update the model's stored component's position
if isinstance(self.element, QgsProcessingModelChildAlgorithm):
2017-06-13 16:05:59 +10:00
self.model.childAlgorithm(self.element.childId()).setPosition(self.pos())
elif isinstance(self.element, QgsProcessingModelParameter):
2017-06-13 16:05:59 +10:00
self.model.parameterComponent(self.element.parameterName()).setPosition(self.pos())
elif isinstance(self.element, QgsProcessingModelOutput):
self.model.childAlgorithm(self.element.childId()).modelOutput(self.element.name()).setPosition(self.pos())
2012-09-15 18:25:25 +03:00
return value
def polygon(self):
font = QFont('Verdana', 8)
font.setPixelSize(12)
fm = QFontMetricsF(font)
hUp = fm.height() * 1.2 * (len(self.element.parameters) + 2)
hDown = fm.height() * 1.2 * (len(self.element.outputs) + 2)
pol = QPolygonF([
QPointF(-(ModelerGraphicItem.BOX_WIDTH + 2) / 2,
-(ModelerGraphicItem.BOX_HEIGHT + 2) / 2 - hUp),
QPointF(-(ModelerGraphicItem.BOX_WIDTH + 2) / 2,
(ModelerGraphicItem.BOX_HEIGHT + 2) / 2 + hDown),
QPointF((ModelerGraphicItem.BOX_WIDTH + 2) / 2,
(ModelerGraphicItem.BOX_HEIGHT + 2) / 2 + hDown),
QPointF((ModelerGraphicItem.BOX_WIDTH + 2) / 2,
-(ModelerGraphicItem.BOX_HEIGHT + 2) / 2 - hUp),
QPointF(-(ModelerGraphicItem.BOX_WIDTH + 2) / 2,
-(ModelerGraphicItem.BOX_HEIGHT + 2) / 2 - hUp)
])
2012-09-15 18:25:25 +03:00
return pol
class FlatButtonGraphicItem(QGraphicsItem):
2013-05-15 20:42:04 +02:00
2013-04-17 13:16:34 +02:00
WIDTH = 16
2013-05-15 20:42:04 +02:00
HEIGHT = 16
def __init__(self, picture, position, action):
super(FlatButtonGraphicItem, self).__init__(None)
2013-05-15 20:42:04 +02:00
self.setAcceptHoverEvents(True)
self.setFlag(QGraphicsItem.ItemIsMovable, False)
self.picture = picture
2013-04-17 13:16:34 +02:00
self.position = position
2013-05-15 20:42:04 +02:00
self.isIn = False
self.action = action
2013-04-17 13:16:34 +02:00
def mousePressEvent(self, event):
self.action()
2013-05-15 20:42:04 +02:00
2013-04-17 13:16:34 +02:00
def paint(self, painter, option, widget=None):
pt = QPointF(-math.floor(self.WIDTH / 2), -math.floor(self.HEIGHT / 2)) + self.position
rect = QRectF(pt.x(), pt.y(), self.WIDTH, self.HEIGHT)
2013-04-17 13:16:34 +02:00
if self.isIn:
painter.setPen(QPen(Qt.transparent, 1))
painter.setBrush(QBrush(QColor(55, 55, 55, 33),
Qt.SolidPattern))
2013-04-17 13:16:34 +02:00
else:
painter.setPen(QPen(Qt.transparent, 1))
painter.setBrush(QBrush(Qt.transparent,
Qt.SolidPattern))
2013-05-15 20:42:04 +02:00
painter.drawRect(rect)
painter.drawPicture(pt.x(), pt.y(), self.picture)
2013-05-15 20:42:04 +02:00
2013-04-17 13:16:34 +02:00
def boundingRect(self):
rect = QRectF(self.position.x() - math.floor(self.WIDTH / 2),
self.position.y() - math.floor(self.HEIGHT / 2),
self.WIDTH,
self.HEIGHT)
2013-05-15 20:42:04 +02:00
return rect
2013-04-17 13:16:34 +02:00
def hoverEnterEvent(self, event):
2013-05-15 20:42:04 +02:00
self.isIn = True
2013-04-17 13:16:34 +02:00
self.update()
2013-05-15 20:42:04 +02:00
2013-04-17 13:16:34 +02:00
def hoverLeaveEvent(self, event):
2013-05-15 20:42:04 +02:00
self.isIn = False
2013-04-17 13:16:34 +02:00
self.update()
2013-05-15 20:42:04 +02:00
2013-04-17 13:16:34 +02:00
class FoldButtonGraphicItem(FlatButtonGraphicItem):
WIDTH = 11
HEIGHT = 11
2013-05-15 20:42:04 +02:00
def __init__(self, position, action, folded):
plus = QPicture()
minus = QPicture()
svg = QSvgRenderer(os.path.join(pluginPath, 'images', 'plus.svg'))
painter = QPainter(plus)
svg.render(painter)
svg = QSvgRenderer(os.path.join(pluginPath, 'images', 'minus.svg'))
painter = QPainter(minus)
svg.render(painter)
self.pictures = {True: plus,
False: minus}
self.folded = folded
picture = self.pictures[self.folded]
super(FoldButtonGraphicItem, self).__init__(picture, position, action)
2013-04-17 13:16:34 +02:00
def mousePressEvent(self, event):
self.folded = not self.folded
self.picture = self.pictures[self.folded]
2013-04-17 13:16:34 +02:00
self.action(self.folded)