From 478a3b1aa4dc3123bcb1133ff78b7a177acdfe04 Mon Sep 17 00:00:00 2001 From: compass Date: Sat, 17 Jan 2015 00:21:33 +0800 Subject: [PATCH] Fix some bugs in PyQt5 --- examples/FillBetweenItem.py | 2 ++ examples/GradientWidget.py | 2 +- examples/template.py | 2 ++ pyqtgraph/GraphicsScene/exportDialog.py | 4 ++- pyqtgraph/Qt.py | 4 ++- pyqtgraph/WidgetGroup.py | 6 ++-- pyqtgraph/console/Console.py | 4 ++- pyqtgraph/flowchart/Flowchart.py | 10 ++++-- pyqtgraph/graphicsItems/FillBetweenItem.py | 21 ++++++------ pyqtgraph/graphicsItems/GradientEditorItem.py | 32 ++++++++++++------- pyqtgraph/graphicsItems/ROI.py | 2 +- pyqtgraph/graphicsItems/ScatterPlotItem.py | 4 +-- pyqtgraph/opengl/GLViewWidget.py | 15 ++++++--- 13 files changed, 71 insertions(+), 37 deletions(-) diff --git a/examples/FillBetweenItem.py b/examples/FillBetweenItem.py index 74dd89bc..fc91ee32 100644 --- a/examples/FillBetweenItem.py +++ b/examples/FillBetweenItem.py @@ -8,6 +8,8 @@ import pyqtgraph as pg from pyqtgraph.Qt import QtGui, QtCore import numpy as np +#FIXME: When running on Qt5, not as perfect as on Qt4 + win = pg.plot() win.setWindowTitle('pyqtgraph example: FillBetweenItem') win.setXRange(-10, 10) diff --git a/examples/GradientWidget.py b/examples/GradientWidget.py index ef7d0fa6..fa5253ba 100644 --- a/examples/GradientWidget.py +++ b/examples/GradientWidget.py @@ -16,7 +16,7 @@ app = QtGui.QApplication([]) w = QtGui.QMainWindow() w.show() w.setWindowTitle('pyqtgraph example: GradientWidget') -w.resize(400,400) +w.setGeometry(10, 50, 400, 400) cw = QtGui.QWidget() w.setCentralWidget(cw) diff --git a/examples/template.py b/examples/template.py index 1198e317..6b5e1f75 100644 --- a/examples/template.py +++ b/examples/template.py @@ -11,6 +11,8 @@ import pyqtgraph as pg from pyqtgraph.Qt import QtCore, QtGui import numpy as np +app = QtGui.QApplication([]) + # win.setWindowTitle('pyqtgraph example: ____') ## Start Qt event loop unless running in interactive mode or using pyside. diff --git a/pyqtgraph/GraphicsScene/exportDialog.py b/pyqtgraph/GraphicsScene/exportDialog.py index 5efb7c44..eebf5999 100644 --- a/pyqtgraph/GraphicsScene/exportDialog.py +++ b/pyqtgraph/GraphicsScene/exportDialog.py @@ -1,4 +1,4 @@ -from ..Qt import QtCore, QtGui, USE_PYSIDE +from ..Qt import QtCore, QtGui, USE_PYSIDE, USE_PYQT5 from .. import exporters as exporters from .. import functions as fn from ..graphicsItems.ViewBox import ViewBox @@ -6,6 +6,8 @@ from ..graphicsItems.PlotItem import PlotItem if USE_PYSIDE: from . import exportDialogTemplate_pyside as exportDialogTemplate +elif USE_PYQT5: + from . import exportDialogTemplate_pyqt5 as exportDialogTemplate else: from . import exportDialogTemplate_pyqt as exportDialogTemplate diff --git a/pyqtgraph/Qt.py b/pyqtgraph/Qt.py index edae4d99..ddf486fe 100644 --- a/pyqtgraph/Qt.py +++ b/pyqtgraph/Qt.py @@ -20,7 +20,7 @@ QT_LIB = None ## Automatically determine whether to use PyQt or PySide. ## This is done by first checking to see whether one of the libraries ## is already imported. If not, then attempt to import PyQt4, then PySide. -libOrder = [PYQT4, PYSIDE, PYQT5] +libOrder = [PYQT5, PYQT4, PYSIDE] for lib in libOrder: if lib in sys.modules: @@ -172,6 +172,8 @@ if QT_LIB.startswith('PyQt'): ## Make sure we have Qt >= 4.7 versionReq = [4, 7] USE_PYSIDE = QT_LIB == PYSIDE # for backward compatibility +USE_PYQT5 = QT_LIB == PYQT5 # for backward compatibility +USE_PYQT4 = QT_LIB == PYQT4 # for backward compatibility QtVersion = PySide.QtCore.__version__ if QT_LIB == PYSIDE else QtCore.QT_VERSION_STR m = re.match(r'(\d+)\.(\d+).*', QtVersion) if m is not None and list(map(int, m.groups())) < versionReq: diff --git a/pyqtgraph/WidgetGroup.py b/pyqtgraph/WidgetGroup.py index 29541454..17e2b2bd 100644 --- a/pyqtgraph/WidgetGroup.py +++ b/pyqtgraph/WidgetGroup.py @@ -8,7 +8,7 @@ This class addresses the problem of having to save and restore the state of a large group of widgets. """ -from .Qt import QtCore, QtGui +from .Qt import QtCore, QtGui, USE_PYQT5 import weakref, inspect from .python2_3 import asUnicode @@ -219,7 +219,9 @@ class WidgetGroup(QtCore.QObject): v2 = self.readWidget(w) if v1 != v2: #print "widget", n, " = ", v2 - self.emit(QtCore.SIGNAL('changed'), self.widgetList[w], v2) + if not USE_PYQT5: + #I don't think this line have any different from the next line + self.emit(QtCore.SIGNAL('changed'), self.widgetList[w], v2) self.sigChanged.emit(self.widgetList[w], v2) def state(self): diff --git a/pyqtgraph/console/Console.py b/pyqtgraph/console/Console.py index 6d77c4cf..421ff1d6 100644 --- a/pyqtgraph/console/Console.py +++ b/pyqtgraph/console/Console.py @@ -1,8 +1,10 @@ -from ..Qt import QtCore, QtGui, USE_PYSIDE +from ..Qt import QtCore, QtGui, USE_PYSIDE, USE_PYQT5 import sys, re, os, time, traceback, subprocess if USE_PYSIDE: from . import template_pyside as template +elif USE_PYQT5: + from . import template_pyqt5 as template else: from . import template_pyqt as template diff --git a/pyqtgraph/flowchart/Flowchart.py b/pyqtgraph/flowchart/Flowchart.py index 48357b30..680a6dde 100644 --- a/pyqtgraph/flowchart/Flowchart.py +++ b/pyqtgraph/flowchart/Flowchart.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from ..Qt import QtCore, QtGui, USE_PYSIDE +from ..Qt import QtCore, QtGui, USE_PYSIDE, USE_PYQT5 from .Node import * from ..pgcollections import OrderedDict from ..widgets.TreeWidget import * @@ -9,6 +9,9 @@ from .. import FileDialog, DataTreeWidget if USE_PYSIDE: from . import FlowchartTemplate_pyside as FlowchartTemplate from . import FlowchartCtrlTemplate_pyside as FlowchartCtrlTemplate +elif USE_PYQT5: + from . import FlowchartTemplate_pyqt5 as FlowchartTemplate + from . import FlowchartCtrlTemplate_pyqt5 as FlowchartCtrlTemplate else: from . import FlowchartTemplate_pyqt as FlowchartTemplate from . import FlowchartCtrlTemplate_pyqt as FlowchartCtrlTemplate @@ -648,7 +651,10 @@ class FlowchartCtrlWidget(QtGui.QWidget): self.cwWin.resize(1000,800) h = self.ui.ctrlList.header() - h.setResizeMode(0, h.Stretch) + if not USE_PYQT5: + h.setResizeMode(0, h.Stretch) + else: + h.setSectionResizeMode(0, h.Stretch) self.ui.ctrlList.itemChanged.connect(self.itemChanged) self.ui.loadBtn.clicked.connect(self.loadClicked) diff --git a/pyqtgraph/graphicsItems/FillBetweenItem.py b/pyqtgraph/graphicsItems/FillBetweenItem.py index d2ee393c..6f21df56 100644 --- a/pyqtgraph/graphicsItems/FillBetweenItem.py +++ b/pyqtgraph/graphicsItems/FillBetweenItem.py @@ -1,4 +1,4 @@ -from ..Qt import QtGui +from ..Qt import QtGui, USE_PYQT5, USE_PYQT4, USE_PYSIDE from .. import functions as fn from .PlotDataItem import PlotDataItem from .PlotCurveItem import PlotCurveItem @@ -14,23 +14,23 @@ class FillBetweenItem(QtGui.QGraphicsPathItem): self.setCurves(curve1, curve2) elif curve1 is not None or curve2 is not None: raise Exception("Must specify two curves to fill between.") - + if brush is not None: self.setBrush(fn.mkBrush(brush)) self.updatePath() def setCurves(self, curve1, curve2): """Set the curves to fill between. - + Arguments must be instances of PlotDataItem or PlotCurveItem.""" - + if self.curves is not None: for c in self.curves: try: c.sigPlotChanged.disconnect(self.curveChanged) except (TypeError, RuntimeError): pass - + curves = [curve1, curve2] for c in curves: if not isinstance(c, PlotDataItem) and not isinstance(c, PlotCurveItem): @@ -40,7 +40,7 @@ class FillBetweenItem(QtGui.QGraphicsPathItem): curve2.sigPlotChanged.connect(self.curveChanged) self.setZValue(min(curve1.zValue(), curve2.zValue())-1) self.curveChanged() - + def setBrush(self, *args, **kwds): """Change the fill brush. Acceps the same arguments as pg.mkBrush()""" QtGui.QGraphicsPathItem.setBrush(self, fn.mkBrush(*args, **kwds)) @@ -58,13 +58,14 @@ class FillBetweenItem(QtGui.QGraphicsPathItem): paths.append(c.curve.getPath()) elif isinstance(c, PlotCurveItem): paths.append(c.getPath()) - + path = QtGui.QPainterPath() - p1 = paths[0].toSubpathPolygons() - p2 = paths[1].toReversed().toSubpathPolygons() + transform = QtGui.QTransform() + p1 = paths[0].toSubpathPolygons(transform) + p2 = paths[1].toReversed().toSubpathPolygons(transform) if len(p1) == 0 or len(p2) == 0: self.setPath(QtGui.QPainterPath()) return - + path.addPolygon(p1[0] + p2[0]) self.setPath(path) diff --git a/pyqtgraph/graphicsItems/GradientEditorItem.py b/pyqtgraph/graphicsItems/GradientEditorItem.py index e16370f5..ef6eff6e 100644 --- a/pyqtgraph/graphicsItems/GradientEditorItem.py +++ b/pyqtgraph/graphicsItems/GradientEditorItem.py @@ -116,16 +116,20 @@ class TickSliderItem(GraphicsWidget): self.resetTransform() ort = orientation if ort == 'top': - self.scale(1, -1) - self.translate(0, -self.height()) + transform = QtGui.QTransform.fromScale(1, -1) + transform.translate(0, -self.height()) + self.setTransform(transform) elif ort == 'left': - self.rotate(270) - self.scale(1, -1) - self.translate(-self.height(), -self.maxDim) + transform = QtGui.QTransform() + transform.rotate(270) + transform.scale(1, -1) + transform.translate(-self.height(), -self.maxDim) + self.setTransform(transform) elif ort == 'right': - self.rotate(270) - self.translate(-self.height(), 0) - #self.setPos(0, -self.height()) + transform = QtGui.QTransform() + transform.rotate(270) + transform.translate(-self.height(), 0) + self.setTransform(transform) elif ort != 'bottom': raise Exception("%s is not a valid orientation. Options are 'left', 'right', 'top', and 'bottom'" %str(ort)) @@ -237,7 +241,7 @@ class TickSliderItem(GraphicsWidget): self.addTick(pos.x()/self.length) elif ev.button() == QtCore.Qt.RightButton: self.showMenu(ev) - + #if ev.button() == QtCore.Qt.RightButton: #if self.moving: #ev.accept() @@ -781,11 +785,15 @@ class GradientEditorItem(TickSliderItem): self.updateGradient() self.sigGradientChangeFinished.emit(self) - -class Tick(QtGui.QGraphicsObject): ## NOTE: Making this a subclass of GraphicsObject instead results in + +class Tick(QtGui.QGraphicsWidget): ## NOTE: Making this a subclass of GraphicsObject instead results in ## activating this bug: https://bugreports.qt-project.org/browse/PYSIDE-86 ## private class - + + # When making Tick a subclass of QtGui.QGraphicsObject as origin, + # ..GraphicsScene.items(self, *args) will get Tick object as a + # class of QtGui.QMultimediaWidgets.QGraphicsVideoItem in python2.7-PyQt5(5.4.0) + sigMoving = QtCore.Signal(object) sigMoved = QtCore.Signal(object) diff --git a/pyqtgraph/graphicsItems/ROI.py b/pyqtgraph/graphicsItems/ROI.py index 179dafdc..f028ca68 100644 --- a/pyqtgraph/graphicsItems/ROI.py +++ b/pyqtgraph/graphicsItems/ROI.py @@ -1008,7 +1008,7 @@ class ROI(GraphicsObject): #print " dataBounds:", dataBounds ## Intersect transformed ROI bounds with data bounds - intBounds = dataBounds.intersect(QtCore.QRectF(0, 0, dShape[0], dShape[1])) + intBounds = dataBounds.intersected(QtCore.QRectF(0, 0, dShape[0], dShape[1])) #print " intBounds:", intBounds ## Determine index values to use when referencing the array. diff --git a/pyqtgraph/graphicsItems/ScatterPlotItem.py b/pyqtgraph/graphicsItems/ScatterPlotItem.py index 1c11fcf9..b54fd446 100644 --- a/pyqtgraph/graphicsItems/ScatterPlotItem.py +++ b/pyqtgraph/graphicsItems/ScatterPlotItem.py @@ -1,4 +1,4 @@ -from ..Qt import QtGui, QtCore, USE_PYSIDE +from ..Qt import QtGui, QtCore, USE_PYSIDE, USE_PYQT5 from ..Point import Point from .. import functions as fn from .GraphicsItem import GraphicsItem @@ -752,7 +752,7 @@ class ScatterPlotItem(GraphicsObject): self.data['targetRect'][updateMask] = list(imap(QtCore.QRectF, updatePts[0,:], updatePts[1,:], width, width)) data = self.data[viewMask] - if USE_PYSIDE: + if USE_PYSIDE or USE_PYQT5: list(imap(p.drawPixmap, data['targetRect'], repeat(atlas), data['sourceRect'])) else: p.drawPixmapFragments(data['targetRect'].tolist(), data['sourceRect'].tolist(), atlas) diff --git a/pyqtgraph/opengl/GLViewWidget.py b/pyqtgraph/opengl/GLViewWidget.py index c71bb3c9..2e7b4263 100644 --- a/pyqtgraph/opengl/GLViewWidget.py +++ b/pyqtgraph/opengl/GLViewWidget.py @@ -1,4 +1,4 @@ -from ..Qt import QtCore, QtGui, QtOpenGL +from ..Qt import QtCore, QtGui, QtOpenGL, USE_PYQT5 from OpenGL.GL import * import OpenGL.GL.framebufferobjects as glfbo import numpy as np @@ -323,10 +323,17 @@ class GLViewWidget(QtOpenGL.QGLWidget): def wheelEvent(self, ev): - if (ev.modifiers() & QtCore.Qt.ControlModifier): - self.opts['fov'] *= 0.999**ev.delta() + delta = 0 + if not USE_PYQT5: + delta = ev.delta() else: - self.opts['distance'] *= 0.999**ev.delta() + delta = ev.angleDelta().x() + if delta == 0: + delta = ev.angleDelta().y() + if (ev.modifiers() & QtCore.Qt.ControlModifier): + self.opts['fov'] *= 0.999**delta + else: + self.opts['distance'] *= 0.999**delta self.update() def keyPressEvent(self, ev):