Commit 6bf7da3b authored by Benjamin Jakimow's avatar Benjamin Jakimow
Browse files
parent f4d90e73
......@@ -49,13 +49,12 @@ if Qgis.QGIS_VERSION < MIN_QGIS_VERSION:
KEY_MAPLAYERCONFIGWIDGETFACTORIES = 'QPS_MAPLAYER_CONFIGWIDGET_FACTORIES'
def registerMapLayerConfigWidgetFactory(factory: QgsMapLayerConfigWidgetFactory):
def registerMapLayerConfigWidgetFactory(factory: QgsMapLayerConfigWidgetFactory) -> QgsMapLayerConfigWidgetFactory:
"""
Register a new tab in the map layer properties dialog.
:param factory: QgsMapLayerConfigWidgetFactory
:type factory:
:return:
:rtype:
:return: QgsMapLayerConfigWidgetFactory or None, if a factory with similar name was registered before by this method
"""
global MAPLAYER_CONFIGWIDGET_FACTORIES
assert isinstance(factory, QgsMapLayerConfigWidgetFactory)
......@@ -70,6 +69,9 @@ def registerMapLayerConfigWidgetFactory(factory: QgsMapLayerConfigWidgetFactory)
os.environ[KEY_MAPLAYERCONFIGWIDGETFACTORIES] = '::'.join(registered)
iface.registerMapLayerConfigWidgetFactory(factory)
QgsApplication.instance().messageLog().logMessage(f'Registered {name}', level=Qgis.Info)
return factory
else:
return None
def unregisterMapLayerConfigWidgetFactory(factory: QgsMapLayerConfigWidgetFactory):
......
......@@ -843,7 +843,7 @@ class ClassificationScheme(QAbstractTableModel):
self.insertClasses(classes)
def addClasses(self, classes, index=None):
warnings.warn('use insertClasses()', DeprecationWarning)
warnings.warn('use insertClasses()', DeprecationWarning, stacklevel=2)
self.insertClasses(classes, index=index)
def insertClasses(self, classes, index=None):
......@@ -918,7 +918,7 @@ class ClassificationScheme(QAbstractTableModel):
return None
def addClass(self, c, index=None):
warnings.warn('Use insert class', DeprecationWarning)
warnings.warn('Use insert class', DeprecationWarning, stacklevel=2)
def insertClass(self, c, index=None):
"""
......
......@@ -115,7 +115,7 @@ class CrosshairStyle(object):
self.mShowDot = b
def setShow(self, b):
warnings.warn('MapCanvas.setShow was replaced by .setVisibility(b:bool)', DeprecationWarning)
warnings.warn('MapCanvas.setShow was replaced by .setVisibility(b:bool)', DeprecationWarning, stacklevel=2)
assert isinstance(b, bool)
self.mShow = b
......
# -*- coding: utf-8 -*-
import time
import weakref
import warnings
from ..Qt import QtCore, QtGui
from ..Qt import QtCore, QtGui, QT_LIB, isQObjectAlive
from ..Point import Point
from .. import functions as fn
from .. import ptime as ptime
from .mouseEvents import *
from .. import debug as debug
from .. import getConfigOption
getMillis = lambda: int(round(time.time() * 1000))
if hasattr(QtCore, 'PYQT_VERSION'):
try:
import sip
HAVE_SIP = True
except ImportError:
HAVE_SIP = False
if QT_LIB.startswith('PyQt'):
from ..Qt import sip
HAVE_SIP = True
else:
HAVE_SIP = False
......@@ -39,7 +40,7 @@ class GraphicsScene(QtGui.QGraphicsScene):
* Eats mouseMove events that occur too soon after a mouse press.
* Reimplements items() and itemAt() to circumvent PyQt bug
====================== ==================================================================
====================== ====================================================================
**Signals**
sigMouseClicked(event) Emitted when the mouse is clicked over the scene. Use ev.pos() to
get the click position relative to the item that was clicked on,
......@@ -49,7 +50,9 @@ class GraphicsScene(QtGui.QGraphicsScene):
is given in scene coordinates.
sigMouseHover(items) Emitted when the mouse is moved over the scene. Items is a list
of items under the cursor.
====================== ==================================================================
sigItemAdded(item) Emitted when an item is added via addItem(). The item is given.
sigItemRemoved(item) Emitted when an item is removed via removeItem(). The item is given.
====================== ====================================================================
Mouse interaction is as follows:
......@@ -83,7 +86,10 @@ class GraphicsScene(QtGui.QGraphicsScene):
sigMouseClicked = QtCore.Signal(object) ## emitted when mouse is clicked. Check for event.isAccepted() to see whether the event has already been acted on.
sigPrepareForPaint = QtCore.Signal() ## emitted immediately before the scene is about to be rendered
sigItemAdded = QtCore.Signal(object) ## emits the item object just added
sigItemRemoved = QtCore.Signal(object) ## emits the item object just removed
_addressCache = weakref.WeakValueDictionary()
ExportDirectory = None
......@@ -110,10 +116,11 @@ class GraphicsScene(QtGui.QGraphicsScene):
self.lastHoverEvent = None
self.minDragTime = 0.5 # drags shorter than 0.5 sec are interpreted as clicks
self.contextMenu = [QtGui.QAction("Export...", self)]
self.contextMenu = [QtGui.QAction(QtCore.QCoreApplication.translate("GraphicsScene", "Export..."), self)]
self.contextMenu[0].triggered.connect(self.showExportDialog)
self.exportDialog = None
self._lastMoveEventTime = 0
def render(self, *args):
self.prepareForPaint()
......@@ -145,7 +152,7 @@ class GraphicsScene(QtGui.QGraphicsScene):
self._moveDistance = d
def mousePressEvent(self, ev):
QtGui.QGraphicsScene.mousePressEvent(self, ev)
super().mousePressEvent(ev)
if self.mouseGrabberItem() is None: ## nobody claimed press; we are free to generate drag/click events
if self.lastHoverEvent is not None:
# If the mouse has moved since the last hover event, send a new one.
......@@ -158,42 +165,63 @@ class GraphicsScene(QtGui.QGraphicsScene):
## set focus on the topmost focusable item under this click
items = self.items(ev.scenePos())
for i in items:
if i.isEnabled() and i.isVisible() and int(i.flags() & i.ItemIsFocusable) > 0:
if i.isEnabled() and i.isVisible() and (i.flags() & i.ItemIsFocusable):
i.setFocus(QtCore.Qt.MouseFocusReason)
break
def _moveEventIsAllowed(self):
# For ignoring events that are too close together
def mouseMoveEvent(self, ev):
self.sigMouseMoved.emit(ev.scenePos())
## First allow QGraphicsScene to deliver hoverEnter/Move/ExitEvents
QtGui.QGraphicsScene.mouseMoveEvent(self, ev)
# Max number of events per second
rateLimit = getConfigOption('mouseRateLimit')
if rateLimit <= 0:
return True
## Next deliver our own HoverEvents
self.sendHoverEvents(ev)
# Delay between events (in milliseconds)
delay = 1000.0 / rateLimit
if getMillis() - self._lastMoveEventTime >= delay:
return True
return False
if int(ev.buttons()) != 0: ## button is pressed; send mouseMoveEvents and mouseDragEvents
QtGui.QGraphicsScene.mouseMoveEvent(self, ev)
if self.mouseGrabberItem() is None:
now = ptime.time()
init = False
## keep track of which buttons are involved in dragging
for btn in [QtCore.Qt.LeftButton, QtCore.Qt.MidButton, QtCore.Qt.RightButton]:
if int(ev.buttons() & btn) == 0:
continue
if int(btn) not in self.dragButtons: ## see if we've dragged far enough yet
cev = [e for e in self.clickEvents if int(e.button()) == int(btn)]
if cev:
cev = cev[0]
dist = Point(ev.scenePos() - cev.scenePos()).length()
if dist == 0 or (dist < self._moveDistance and now - cev.time() < self.minDragTime):
continue
init = init or (len(self.dragButtons) == 0) ## If this is the first button to be dragged, then init=True
self.dragButtons.append(int(btn))
## If we have dragged buttons, deliver a drag event
if len(self.dragButtons) > 0:
if self.sendDragEvent(ev, init=init):
ev.accept()
def mouseMoveEvent(self, ev):
# ignore high frequency events
if self._moveEventIsAllowed():
self._lastMoveEventTime = getMillis()
self.sigMouseMoved.emit(ev.scenePos())
# First allow QGraphicsScene to eliver hoverEvent/Move/Exit Events
super().mouseMoveEvent(ev)
# Next Deliver our own Hover Events
self.sendHoverEvents(ev)
if ev.buttons():
# button is pressed' send mouseMoveEvents and mouseDragEvents
super().mouseMoveEvent(ev)
if self.mouseGrabberItem() is None:
now = ptime.time()
init = False
## keep track of which buttons are involved in dragging
for btn in [QtCore.Qt.LeftButton, QtCore.Qt.MiddleButton, QtCore.Qt.RightButton]:
if not (ev.buttons() & btn):
continue
if btn not in self.dragButtons: ## see if we've dragged far enough yet
cev = [e for e in self.clickEvents if e.button() == btn]
if cev:
cev = cev[0]
dist = Point(ev.scenePos() - cev.scenePos()).length()
if dist == 0 or (dist < self._moveDistance and now - cev.time() < self.minDragTime):
continue
init = init or (len(self.dragButtons) == 0) ## If this is the first button to be dragged, then init=True
self.dragButtons.append(btn)
## if we have dragged buttons, deliver a drag event
if len(self.dragButtons) > 0:
if self.sendDragEvent(ev, init=init):
ev.accept()
else:
super().mouseMoveEvent(ev)
# if you do not accept event (which is ignored) then cursor will disappear
ev.accept()
def leaveEvent(self, ev): ## inform items that mouse is gone
if len(self.dragButtons) == 0:
......@@ -207,24 +235,24 @@ class GraphicsScene(QtGui.QGraphicsScene):
ev.accept()
self.dragButtons.remove(ev.button())
else:
cev = [e for e in self.clickEvents if int(e.button()) == int(ev.button())]
cev = [e for e in self.clickEvents if e.button() == ev.button()]
if cev:
if self.sendClickEvent(cev[0]):
#print "sent click event"
ev.accept()
self.clickEvents.remove(cev[0])
if int(ev.buttons()) == 0:
if not ev.buttons():
self.dragItem = None
self.dragButtons = []
self.clickEvents = []
self.lastDrag = None
QtGui.QGraphicsScene.mouseReleaseEvent(self, ev)
super().mouseReleaseEvent(ev)
self.sendHoverEvents(ev) ## let items prepare for next click/drag
def mouseDoubleClickEvent(self, ev):
QtGui.QGraphicsScene.mouseDoubleClickEvent(self, ev)
super().mouseDoubleClickEvent(ev)
if self.mouseGrabberItem() is None: ## nobody claimed press; we are free to generate drag/click events
self.clickEvents.append(MouseClickEvent(ev, double=True))
......@@ -236,7 +264,7 @@ class GraphicsScene(QtGui.QGraphicsScene):
items = []
event = HoverEvent(None, acceptable)
else:
acceptable = int(ev.buttons()) == 0 ## if we are in mid-drag, do not allow items to accept the hover event.
acceptable = not ev.buttons() ## if we are in mid-drag, do not allow items to accept the hover event.
event = HoverEvent(ev, acceptable)
items = self.itemsNearEvent(event, hoverable=True)
self.sigMouseHover.emit(items)
......@@ -264,7 +292,9 @@ class GraphicsScene(QtGui.QGraphicsScene):
for item in prevItems:
event.currentItem = item
try:
if item.scene() is self:
# NOTE: isQObjectAlive(item) was added for PySide6 where
# verlet_chain_demo.py triggers a RuntimeError.
if isQObjectAlive(item) and item.scene() is self:
item.hoverEvent(event)
except:
debug.printExc("Error sending hover exit event:")
......@@ -276,7 +306,7 @@ class GraphicsScene(QtGui.QGraphicsScene):
# item to continue receiving events until the drag is over
# - event is not a mouse event (QEvent.Leave sometimes appears here)
if (ev.type() == ev.GraphicsSceneMousePress or
(ev.type() == ev.GraphicsSceneMouseMove and int(ev.buttons()) == 0)):
(ev.type() == ev.GraphicsSceneMouseMove and not ev.buttons())):
self.lastHoverEvent = event ## save this so we can ask about accepted events later.
def sendDragEvent(self, ev, init=False, final=False):
......@@ -314,7 +344,7 @@ class GraphicsScene(QtGui.QGraphicsScene):
if event.isAccepted():
#print " --> accepted"
self.dragItem = item
if int(item.flags() & item.ItemIsFocusable) > 0:
if item.flags() & item.ItemIsFocusable:
item.setFocus(QtCore.Qt.MouseFocusReason)
break
elif self.dragItem is not None:
......@@ -359,11 +389,23 @@ class GraphicsScene(QtGui.QGraphicsScene):
debug.printExc("Error sending click event:")
if ev.isAccepted():
if int(item.flags() & item.ItemIsFocusable) > 0:
if item.flags() & item.ItemIsFocusable:
item.setFocus(QtCore.Qt.MouseFocusReason)
break
self.sigMouseClicked.emit(ev)
return ev.isAccepted()
def addItem(self, item):
# extend QGraphicsScene.addItem to emit a sigItemAdded signal
ret = QtGui.QGraphicsScene.addItem(self, item)
self.sigItemAdded.emit(item)
return ret
def removeItem(self, item):
# extend QGraphicsScene.removeItem to emit a sigItemRemoved signal
ret = QtGui.QGraphicsScene.removeItem(self, item)
self.sigItemRemoved.emit(item)
return ret
def items(self, *args):
items = QtGui.QGraphicsScene.items(self, *args)
......@@ -501,7 +543,7 @@ class GraphicsScene(QtGui.QGraphicsScene):
for m in menusToAdd:
if isinstance(m, QtGui.QMenu):
menu.addMenu(m)
menu.addAction(m.menuAction())
elif isinstance(m, QtGui.QAction):
menu.addAction(m)
else:
......
from ..Qt import QtCore, QtGui, QT_LIB
from ..Qt import QtCore, QtGui, QtWidgets, QT_LIB
from .. import exporters as exporters
from .. import functions as fn
from ..graphicsItems.ViewBox import ViewBox
from ..graphicsItems.PlotItem import PlotItem
if QT_LIB == 'PySide':
from . import exportDialogTemplate_pyside as exportDialogTemplate
elif QT_LIB == 'PySide2':
from . import exportDialogTemplate_pyside2 as exportDialogTemplate
elif QT_LIB == 'PyQt5':
from . import exportDialogTemplate_pyqt5 as exportDialogTemplate
else:
from . import exportDialogTemplate_pyqt as exportDialogTemplate
import importlib
ui_template = importlib.import_module(
f'.exportDialogTemplate_{QT_LIB.lower()}', package=__package__)
class FormatExportListWidgetItem(QtWidgets.QListWidgetItem):
def __init__(self, expClass, *args, **kwargs):
QtWidgets.QListWidgetItem.__init__(self, *args, **kwargs)
self.expClass = expClass
class ExportDialog(QtGui.QWidget):
......@@ -28,7 +29,7 @@ class ExportDialog(QtGui.QWidget):
self.selectBox.hide()
self.scene.addItem(self.selectBox)
self.ui = exportDialogTemplate.Ui_Form()
self.ui = ui_template.Ui_Form()
self.ui.setupUi(self)
self.ui.closeBtn.clicked.connect(self.close)
......@@ -99,16 +100,14 @@ class ExportDialog(QtGui.QWidget):
def updateFormatList(self):
current = self.ui.formatList.currentItem()
if current is not None:
current = str(current.text())
self.ui.formatList.clear()
self.exporterClasses = {}
gotCurrent = False
for exp in exporters.listExporters():
self.ui.formatList.addItem(exp.Name)
self.exporterClasses[exp.Name] = exp
if exp.Name == current:
self.ui.formatList.setCurrentRow(self.ui.formatList.count()-1)
item = FormatExportListWidgetItem(exp, QtCore.QCoreApplication.translate('Exporter', exp.Name))
self.ui.formatList.addItem(item)
if item == current:
self.ui.formatList.setCurrentRow(self.ui.formatList.count() - 1)
gotCurrent = True
if not gotCurrent:
......@@ -119,7 +118,7 @@ class ExportDialog(QtGui.QWidget):
self.currentExporter = None
self.ui.paramTree.clear()
return
expClass = self.exporterClasses[str(item.text())]
expClass = item.expClass
exp = expClass(item=self.ui.itemTree.currentItem().gitem)
params = exp.parameters()
......@@ -145,4 +144,4 @@ class ExportDialog(QtGui.QWidget):
def closeEvent(self, event):
self.close()
QtGui.QWidget.closeEvent(self, event)
super().closeEvent(event)
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file './pyqtgraph/GraphicsScene/exportDialogTemplate.ui'
#
# Created: Mon Dec 23 10:10:52 2013
# by: PyQt4 UI code generator 4.10
#
# WARNING! All changes made in this file will be lost!
from PyQt4 import QtCore, QtGui
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
def _fromUtf8(s):
return s
try:
_encoding = QtGui.QApplication.UnicodeUTF8
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig)
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName(_fromUtf8("Form"))
Form.resize(241, 367)
self.gridLayout = QtGui.QGridLayout(Form)
self.gridLayout.setSpacing(0)
self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
self.label = QtGui.QLabel(Form)
self.label.setObjectName(_fromUtf8("label"))
self.gridLayout.addWidget(self.label, 0, 0, 1, 3)
self.itemTree = QtGui.QTreeWidget(Form)
self.itemTree.setObjectName(_fromUtf8("itemTree"))
self.itemTree.headerItem().setText(0, _fromUtf8("1"))
self.itemTree.header().setVisible(False)
self.gridLayout.addWidget(self.itemTree, 1, 0, 1, 3)
self.label_2 = QtGui.QLabel(Form)
self.label_2.setObjectName(_fromUtf8("label_2"))
self.gridLayout.addWidget(self.label_2, 2, 0, 1, 3)
self.formatList = QtGui.QListWidget(Form)
self.formatList.setObjectName(_fromUtf8("formatList"))
self.gridLayout.addWidget(self.formatList, 3, 0, 1, 3)
self.exportBtn = QtGui.QPushButton(Form)
self.exportBtn.setObjectName(_fromUtf8("exportBtn"))
self.gridLayout.addWidget(self.exportBtn, 6, 1, 1, 1)
self.closeBtn = QtGui.QPushButton(Form)
self.closeBtn.setObjectName(_fromUtf8("closeBtn"))
self.gridLayout.addWidget(self.closeBtn, 6, 2, 1, 1)
self.paramTree = ParameterTree(Form)
self.paramTree.setObjectName(_fromUtf8("paramTree"))
self.paramTree.headerItem().setText(0, _fromUtf8("1"))
self.paramTree.header().setVisible(False)
self.gridLayout.addWidget(self.paramTree, 5, 0, 1, 3)
self.label_3 = QtGui.QLabel(Form)
self.label_3.setObjectName(_fromUtf8("label_3"))
self.gridLayout.addWidget(self.label_3, 4, 0, 1, 3)
self.copyBtn = QtGui.QPushButton(Form)
self.copyBtn.setObjectName(_fromUtf8("copyBtn"))
self.gridLayout.addWidget(self.copyBtn, 6, 0, 1, 1)
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
Form.setWindowTitle(_translate("Form", "Export", None))
self.label.setText(_translate("Form", "Item to export:", None))
self.label_2.setText(_translate("Form", "Export format", None))
self.exportBtn.setText(_translate("Form", "Export", None))
self.closeBtn.setText(_translate("Form", "Close", None))
self.label_3.setText(_translate("Form", "Export options", None))
self.copyBtn.setText(_translate("Form", "Copy", None))
from ..parametertree import ParameterTree
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file './pyqtgraph/GraphicsScene/exportDialogTemplate.ui'
# Form implementation generated from reading ui file 'pyqtgraph\GraphicsScene\exportDialogTemplate.ui'
#
# Created: Mon Dec 23 10:10:53 2013
# by: pyside-uic 0.2.14 running on PySide 1.1.2
# Created by: PyQt6 UI code generator 6.0.0
#
# WARNING! All changes made in this file will be lost!
# WARNING: Any manual changes made to this file will be lost when pyuic6 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt6 import QtCore, QtGui, QtWidgets
from PySide import QtCore, QtGui
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(241, 367)
self.gridLayout = QtGui.QGridLayout(Form)
self.gridLayout = QtWidgets.QGridLayout(Form)
self.gridLayout.setSpacing(0)
self.gridLayout.setObjectName("gridLayout")
self.label = QtGui.QLabel(Form)
self.label = QtWidgets.QLabel(Form)
self.label.setObjectName("label")
self.gridLayout.addWidget(self.label, 0, 0, 1, 3)
self.itemTree = QtGui.QTreeWidget(Form)
self.itemTree = QtWidgets.QTreeWidget(Form)
self.itemTree.setObjectName("itemTree")
self.itemTree.headerItem().setText(0, "1")
self.itemTree.header().setVisible(False)
self.gridLayout.addWidget(self.itemTree, 1, 0, 1, 3)
self.label_2 = QtGui.QLabel(Form)
self.label_2 = QtWidgets.QLabel(Form)
self.label_2.setObjectName("label_2")
self.gridLayout.addWidget(self.label_2, 2, 0, 1, 3)
self.formatList = QtGui.QListWidget(Form)
self.formatList = QtWidgets.QListWidget(Form)
self.formatList.setObjectName("formatList")
self.gridLayout.addWidget(self.formatList, 3, 0, 1, 3)
self.exportBtn = QtGui.QPushButton(Form)
self.exportBtn = QtWidgets.QPushButton(Form)
self.exportBtn.setObjectName("exportBtn")
self.gridLayout.addWidget(self.exportBtn, 6, 1, 1, 1)
self.closeBtn = QtGui.QPushButton(Form)
self.closeBtn = QtWidgets.QPushButton(Form)
self.closeBtn.setObjectName("closeBtn")
self.gridLayout.addWidget(self.closeBtn, 6, 2, 1, 1)
self.paramTree = ParameterTree(Form)
......@@ -41,10 +41,10 @@ class Ui_Form(object):
self.paramTree.headerItem().setText(0, "1")
self.paramTree.header().setVisible(False)
self.gridLayout.addWidget(self.paramTree, 5, 0, 1, 3)
self.label_3 = QtGui.QLabel(Form)
self.label_3 = QtWidgets.QLabel(Form)
self.label_3.setObjectName("label_3")
self.gridLayout.addWidget(self.label_3, 4, 0, 1, 3)
self.copyBtn = QtGui.QPushButton(Form)
self.copyBtn = QtWidgets.QPushButton(Form)
self.copyBtn.setObjectName("copyBtn")
self.gridLayout.addWidget(self.copyBtn, 6, 0, 1, 1)
......@@ -52,12 +52,12 @@ class Ui_Form(object):
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
Form.setWindowTitle(QtGui.QApplication.translate("Form", "Export", None, QtGui.QApplication.UnicodeUTF8))
self.label.setText(QtGui.QApplication.translate("Form", "Item to export:", None, QtGui.QApplication.UnicodeUTF8))
self.label_2.setText(QtGui.QApplication.translate("Form", "Export format",