Bugfixes:
- SVG export text elements use generic font-family as backup, corrected item transformation issues - Fixed RuntimeError caused when clearing item hierarchies from ViewBox - Fixed example execution bug Packaging maintenance: - Added missing files to MANIFEST.in, fixed setup.py package detection - Added debian control files for building source packages - Fixed version numbering in doc, __init__.py
This commit is contained in:
commit
906468996a
8
MANIFEST.in
Normal file
8
MANIFEST.in
Normal file
@ -0,0 +1,8 @@
|
||||
recursive-include pyqtgraph *.py *.ui *.m README *.txt
|
||||
recursive-include tests *.py *.ui
|
||||
recursive-include examples *.py *.ui
|
||||
recursive-include doc *.rst *.py *.svg *.png *.jpg
|
||||
recursive-include doc/build/html *
|
||||
recursive-include tools *
|
||||
include doc/Makefile doc/make.bat README.txt LICENSE.txt
|
||||
|
@ -17,8 +17,7 @@ import sys, os
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
path = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.insert(0, os.path.join(path, '..', '..', '..'))
|
||||
print sys.path
|
||||
sys.path.insert(0, os.path.join(path, '..', '..'))
|
||||
|
||||
# -- General configuration -----------------------------------------------------
|
||||
|
||||
@ -50,9 +49,9 @@ copyright = '2011, Luke Campagnola'
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '1.8'
|
||||
version = ''
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '1.8'
|
||||
release = ''
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
@ -3,8 +3,8 @@
|
||||
You can adapt this file completely to your liking, but it should at least
|
||||
contain the root `toctree` directive.
|
||||
|
||||
Welcome to the documentation for pyqtgraph 1.8
|
||||
==============================================
|
||||
Welcome to the documentation for pyqtgraph
|
||||
==========================================
|
||||
|
||||
Contents:
|
||||
|
||||
|
@ -2,10 +2,10 @@
|
||||
import sys, os
|
||||
path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
|
||||
path.rstrip(os.path.sep)
|
||||
if path.endswith('pyqtgraph'):
|
||||
sys.path.insert(0, os.path.join(path, '..')) ## examples installed inside pyqtgraph package
|
||||
elif 'pyqtgraph' in os.listdir(path):
|
||||
if 'pyqtgraph' in os.listdir(path):
|
||||
sys.path.insert(0, path) ## examples adjacent to pyqtgraph (as in source)
|
||||
elif path.endswith('pyqtgraph'):
|
||||
sys.path.insert(0, os.path.abspath(os.path.join(path, '..'))) ## examples installed inside pyqtgraph package
|
||||
|
||||
## should force example to use PySide instead of PyQt
|
||||
if 'pyside' in sys.argv:
|
||||
|
@ -1,5 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
REVISION = None
|
||||
"""
|
||||
PyQtGraph - Scientific Graphics and GUI Library for Python
|
||||
www.pyqtgraph.org
|
||||
"""
|
||||
|
||||
__version__ = None
|
||||
|
||||
### import all the goodies and add some helper functions for easy CLI use
|
||||
|
||||
@ -63,19 +68,21 @@ def systemInfo():
|
||||
from .Qt import VERSION_INFO
|
||||
print("qt bindings: %s" % VERSION_INFO)
|
||||
|
||||
global REVISION
|
||||
if REVISION is None: ## this code was probably checked out from bzr; look up the last-revision file
|
||||
lastRevFile = os.path.join(os.path.dirname(__file__), '.bzr', 'branch', 'last-revision')
|
||||
global __version__
|
||||
rev = None
|
||||
if __version__ is None: ## this code was probably checked out from bzr; look up the last-revision file
|
||||
lastRevFile = os.path.join(os.path.dirname(__file__), '..', '.bzr', 'branch', 'last-revision')
|
||||
if os.path.exists(lastRevFile):
|
||||
REVISION = open(lastRevFile, 'r').read().strip()
|
||||
rev = open(lastRevFile, 'r').read().strip()
|
||||
|
||||
print("pyqtgraph: %s" % REVISION)
|
||||
print("pyqtgraph: %s; %s" % (__version__, rev))
|
||||
print("config:")
|
||||
import pprint
|
||||
pprint.pprint(CONFIG_OPTIONS)
|
||||
|
||||
## Rename orphaned .pyc files. This is *probably* safe :)
|
||||
|
||||
## We only do this if __version__ is None, indicating the code was probably pulled
|
||||
## from the repository.
|
||||
def renamePyc(startDir):
|
||||
### Used to rename orphaned .pyc files
|
||||
### When a python file changes its location in the repository, usually the .pyc file
|
||||
@ -108,9 +115,8 @@ def renamePyc(startDir):
|
||||
print(" " + name2)
|
||||
os.rename(fileName, name2)
|
||||
|
||||
import os
|
||||
path = os.path.split(__file__)[0]
|
||||
if not hasattr(sys, 'frozen'): ## If we are frozen, there's a good chance we don't have the original .py files anymore.
|
||||
if __version__ is None and not hasattr(sys, 'frozen') and sys.version_info[0] == 2: ## If we are frozen, there's a good chance we don't have the original .py files anymore.
|
||||
renamePyc(path)
|
||||
|
||||
|
||||
|
@ -17,6 +17,9 @@ class SVGExporter(Exporter):
|
||||
self.params = Parameter(name='params', type='group', children=[
|
||||
#{'name': 'width', 'type': 'float', 'value': tr.width(), 'limits': (0, None)},
|
||||
#{'name': 'height', 'type': 'float', 'value': tr.height(), 'limits': (0, None)},
|
||||
#{'name': 'viewbox clipping', 'type': 'bool', 'value': True},
|
||||
#{'name': 'normalize coordinates', 'type': 'bool', 'value': True},
|
||||
#{'name': 'normalize line width', 'type': 'bool', 'value': True},
|
||||
])
|
||||
#self.params.param('width').sigValueChanged.connect(self.widthChanged)
|
||||
#self.params.param('height').sigValueChanged.connect(self.heightChanged)
|
||||
@ -83,7 +86,7 @@ class SVGExporter(Exporter):
|
||||
return bytes(xml)
|
||||
else:
|
||||
with open(fileName, 'w') as fh:
|
||||
fh.write(xml)
|
||||
fh.write(xml.encode('UTF-8'))
|
||||
|
||||
xmlHeader = """\
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
@ -171,8 +174,16 @@ def _generateItemSvg(item, nodes=None, root=None):
|
||||
doc = xml.parseString(xmlStr)
|
||||
else:
|
||||
childs = item.childItems()
|
||||
tr = itemTransform(item, root)
|
||||
tr = itemTransform(item, item.scene())
|
||||
|
||||
## offset to corner of root item
|
||||
if isinstance(root, QtGui.QGraphicsScene):
|
||||
rootPos = QtCore.QPoint(0,0)
|
||||
else:
|
||||
rootPos = root.scenePos()
|
||||
tr2 = QtGui.QTransform()
|
||||
tr2.translate(-rootPos.x(), -rootPos.y())
|
||||
tr = tr * tr2
|
||||
#print item, pg.SRTTransform(tr)
|
||||
|
||||
#tr.translate(item.pos().x(), item.pos().y())
|
||||
@ -239,17 +250,23 @@ def _generateItemSvg(item, nodes=None, root=None):
|
||||
nodes[name] = g1
|
||||
g1.setAttribute('id', name)
|
||||
|
||||
## If this item clips its children, we need to take car of that.
|
||||
## If this item clips its children, we need to take care of that.
|
||||
childGroup = g1 ## add children directly to this node unless we are clipping
|
||||
if not isinstance(item, QtGui.QGraphicsScene):
|
||||
## See if this item clips its children
|
||||
if int(item.flags() & item.ItemClipsChildrenToShape) > 0:
|
||||
## Generate svg for just the path
|
||||
if isinstance(root, QtGui.QGraphicsScene):
|
||||
path = QtGui.QGraphicsPathItem(item.mapToScene(item.shape()))
|
||||
else:
|
||||
path = QtGui.QGraphicsPathItem(root.mapToParent(item.mapToItem(root, item.shape())))
|
||||
pathNode = _generateItemSvg(path, root=root).getElementsByTagName('path')[0]
|
||||
#if isinstance(root, QtGui.QGraphicsScene):
|
||||
#path = QtGui.QGraphicsPathItem(item.mapToScene(item.shape()))
|
||||
#else:
|
||||
#path = QtGui.QGraphicsPathItem(root.mapToParent(item.mapToItem(root, item.shape())))
|
||||
path = QtGui.QGraphicsPathItem(item.mapToScene(item.shape()))
|
||||
item.scene().addItem(path)
|
||||
try:
|
||||
pathNode = _generateItemSvg(path, root=root).getElementsByTagName('path')[0]
|
||||
finally:
|
||||
item.scene().removeItem(path)
|
||||
|
||||
## and for the clipPath element
|
||||
clip = name + '_clip'
|
||||
clipNode = g1.ownerDocument.createElement('clipPath')
|
||||
@ -294,7 +311,10 @@ def correctCoordinates(node, item):
|
||||
elif ch.tagName == 'path':
|
||||
removeTransform = True
|
||||
newCoords = ''
|
||||
for c in ch.getAttribute('d').strip().split(' '):
|
||||
oldCoords = ch.getAttribute('d').strip()
|
||||
if oldCoords == '':
|
||||
continue
|
||||
for c in oldCoords.split(' '):
|
||||
x,y = c.split(',')
|
||||
if x[0].isalpha():
|
||||
t = x[0]
|
||||
@ -317,8 +337,18 @@ def correctCoordinates(node, item):
|
||||
#fs = c[1]-c[2]
|
||||
#fs = (fs**2).sum()**0.5
|
||||
#ch.setAttribute('font-size', str(fs))
|
||||
else:
|
||||
print('warning: export not implemented for SVG tag %s (from item %s)' % (ch.tagName, item))
|
||||
|
||||
## Correct some font information
|
||||
families = ch.getAttribute('font-family').split(',')
|
||||
if len(families) == 1:
|
||||
font = QtGui.QFont(families[0].strip('" '))
|
||||
if font.style() == font.SansSerif:
|
||||
families.append('sans-serif')
|
||||
elif font.style() == font.Serif:
|
||||
families.append('serif')
|
||||
elif font.style() == font.Courier:
|
||||
families.append('monospace')
|
||||
ch.setAttribute('font-family', ', '.join([f if ' ' not in f else '"%s"'%f for f in families]))
|
||||
|
||||
## correct line widths if needed
|
||||
if removeTransform and ch.getAttribute('vector-effect') != 'non-scaling-stroke':
|
||||
|
@ -54,3 +54,8 @@ class ArrowItem(QtGui.QGraphicsPathItem):
|
||||
def paint(self, p, *args):
|
||||
p.setRenderHint(QtGui.QPainter.Antialiasing)
|
||||
QtGui.QGraphicsPathItem.paint(self, p, *args)
|
||||
|
||||
def shape(self):
|
||||
#if not self.opts['pxMode']:
|
||||
#return QtGui.QGraphicsPathItem.shape(self)
|
||||
return self.path
|
@ -63,7 +63,10 @@ class GraphicsItem(object):
|
||||
if self._viewBox is None:
|
||||
p = self
|
||||
while True:
|
||||
p = p.parentItem()
|
||||
try:
|
||||
p = p.parentItem()
|
||||
except RuntimeError: ## sometimes happens as items are being removed from a scene and collected.
|
||||
return None
|
||||
if p is None:
|
||||
vb = self.getViewWidget()
|
||||
if vb is None:
|
||||
@ -496,4 +499,4 @@ class GraphicsItem(object):
|
||||
#self._exportOpts['antialias'] = True
|
||||
else:
|
||||
self._exportOpts = False
|
||||
|
||||
|
||||
|
@ -115,9 +115,10 @@ class TextItem(UIGraphicsItem):
|
||||
self.viewRangeChanged()
|
||||
self.lastTransform = tr
|
||||
|
||||
p.setPen(self.border)
|
||||
p.setBrush(self.fill)
|
||||
p.setRenderHint(p.Antialiasing, True)
|
||||
p.drawPolygon(self.textItem.mapToParent(self.textItem.boundingRect()))
|
||||
if self.border.style() != QtCore.Qt.NoPen or self.fill.style() != QtCore.Qt.NoBrush:
|
||||
p.setPen(self.border)
|
||||
p.setBrush(self.fill)
|
||||
p.setRenderHint(p.Antialiasing, True)
|
||||
p.drawPolygon(self.textItem.mapToParent(self.textItem.boundingRect()))
|
||||
|
||||
|
17
setup.py
17
setup.py
@ -1,11 +1,19 @@
|
||||
from distutils.core import setup
|
||||
import distutils.dir_util
|
||||
import os
|
||||
|
||||
## generate list of all sub-packages
|
||||
subdirs = [i[0].split(os.path.sep)[1:] for i in os.walk('./pyqtgraph') if '__init__.py' in i[2]]
|
||||
subdirs = filter(lambda p: len(p) == 1 or p[1] != 'build', subdirs)
|
||||
path = os.path.abspath(os.path.dirname(__file__))
|
||||
n = len(path.split(os.path.sep))
|
||||
subdirs = [i[0].split(os.path.sep)[n:] for i in os.walk(os.path.join(path, 'pyqtgraph')) if '__init__.py' in i[2]]
|
||||
all_packages = ['.'.join(p) for p in subdirs] + ['pyqtgraph.examples']
|
||||
|
||||
|
||||
## Make sure build directory is clean before installing
|
||||
buildPath = os.path.join(path, 'build')
|
||||
if os.path.isdir(buildPath):
|
||||
distutils.dir_util.remove_tree(buildPath)
|
||||
|
||||
setup(name='pyqtgraph',
|
||||
version='',
|
||||
description='Scientific Graphics and GUI Library for Python',
|
||||
@ -23,6 +31,9 @@ It is intended for use in mathematics / scientific / engineering applications. D
|
||||
#package_data={'pyqtgraph': ['graphicsItems/PlotItem/*.png']},
|
||||
classifiers = [
|
||||
"Programming Language :: Python",
|
||||
"Programming Language :: Python :: 2",
|
||||
"Programming Language :: Python :: 2.6",
|
||||
"Programming Language :: Python :: 2.7",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Development Status :: 4 - Beta",
|
||||
"Environment :: Other Environment",
|
||||
@ -33,7 +44,7 @@ It is intended for use in mathematics / scientific / engineering applications. D
|
||||
"Topic :: Scientific/Engineering :: Visualization",
|
||||
"Topic :: Software Development :: User Interfaces",
|
||||
],
|
||||
requires = [
|
||||
install_requires = [
|
||||
'numpy',
|
||||
'scipy',
|
||||
],
|
||||
|
5
tools/debian/changelog
Normal file
5
tools/debian/changelog
Normal file
@ -0,0 +1,5 @@
|
||||
python-pyqtgraph (0.9.1-1) UNRELEASED; urgency=low
|
||||
|
||||
* Initial release.
|
||||
|
||||
-- Luke <luke.campagnola@gmail.com> Sat, 29 Dec 2012 01:07:23 -0500
|
1
tools/debian/compat
Normal file
1
tools/debian/compat
Normal file
@ -0,0 +1 @@
|
||||
8
|
18
tools/debian/control
Normal file
18
tools/debian/control
Normal file
@ -0,0 +1,18 @@
|
||||
Source: python-pyqtgraph
|
||||
Maintainer: Luke Campagnola <luke.campagnola@gmail.com>
|
||||
Section: python
|
||||
Priority: optional
|
||||
Standards-Version: 3.9.3
|
||||
Build-Depends: debhelper (>= 8)
|
||||
|
||||
Package: python-pyqtgraph
|
||||
Architecture: all
|
||||
Homepage: http://luke.campagnola.me/code/pyqtgraph
|
||||
Depends: python (>= 2.6), python-support (>= 0.90), python-qt4 | python-pyside, python-scipy, python-numpy, ${misc:Depends}
|
||||
Suggests: python-opengl, python-qt4-gl
|
||||
Description: Scientific Graphics and GUI Library for Python
|
||||
PyQtGraph is a pure-python graphics and GUI library built on PyQt4 and numpy.
|
||||
It is intended for use in mathematics / scientific / engineering applications.
|
||||
Despite being written entirely in python, the library is very fast due to its
|
||||
heavy leverage of numpy for number crunching and Qt's GraphicsView framework
|
||||
for fast display.
|
10
tools/debian/copyright
Normal file
10
tools/debian/copyright
Normal file
@ -0,0 +1,10 @@
|
||||
Copyright (c) 2012 University of North Carolina at Chapel Hill
|
||||
Luke Campagnola ('luke.campagnola@%s.com' % 'gmail')
|
||||
|
||||
The MIT License
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
1
tools/debian/files
Normal file
1
tools/debian/files
Normal file
@ -0,0 +1 @@
|
||||
python-pyqtgraph_0.9.1-1_all.deb python optional
|
3
tools/debian/postrm
Executable file
3
tools/debian/postrm
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh -e
|
||||
#DEBHELPER#
|
||||
rm -rf /usr/lib/python2.7/dist-packages/pyqtgraph
|
4
tools/debian/rules
Executable file
4
tools/debian/rules
Executable file
@ -0,0 +1,4 @@
|
||||
#!/usr/bin/make -f
|
||||
|
||||
%:
|
||||
dh $@
|
1
tools/debian/source/format
Normal file
1
tools/debian/source/format
Normal file
@ -0,0 +1 @@
|
||||
3.0 (quilt)
|
Loading…
Reference in New Issue
Block a user