Thanks to visit codestin.com
Credit goes to github.com

Skip to content

PySide backend support #80

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Jun 16, 2011
Merged

PySide backend support #80

merged 14 commits into from
Jun 16, 2011

Conversation

gstorer
Copy link
Contributor

@gstorer gstorer commented Apr 11, 2011

Hi,
I've modified the Qt backend to switch between PySide and PyQt using the same environment variable as IPython.

There are a couple of outstanding bugs in PySide that are apparent in matplotlib:
489 - temporary work around in qt.py that can be removed when PySide fixes the bug. Fixed in source.
819 - temporary work around in qt.py that can be removed when PySide fixes the bug. Default file filter isn't set.
736 - Only affects the subplot configuration tool. Fixed in PySide 1.0.1.

I also removed the 'hackish' fix for the bug in early version of PyQt 4.6.x - it could be added to qt.py if it was felt necessary.

I've added a Qt slot to the FigureManagerQT class that passes straight through to the status bar - this seemed to fix a segfault that may or may not be a bug in PySide. I haven't been able to separately reproduce it and PySide isn't really suppose to support the old style slots/signals.

I've modified formlayout to use getColor instead of getRgba as PySide does not have the later function. I also had to alias all of the Qt names used by formlayout as you can't double import things.

Regards,
Gerald.

@gstorer
Copy link
Contributor Author

gstorer commented Apr 28, 2011

Updated to remove the fix for PySide bug 489 and added a work around for the PySide removal of support for old style classes.

The only outstanding bug is 819 where the default file filter can't be set.

@gstorer
Copy link
Contributor Author

gstorer commented May 2, 2011

There are now no outstanding bugs with PySide that matplotlib exposes (that I am aware of).

@@ -0,0 +1,53 @@
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The name of this file is problematic. It breaks the Qt3 backend (since 'qt' is the name of the PyQt library version 3 -- the backend tries to import the bindings but instead gets this file.) It's also confusing to read "from qt import ..." in the Qt4 backends and not have that refer to the main qt library.

Perhaps it should be called "qt4_compat.py" or something similar?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I just blindly copied the file from IPython but they don't support Qt3.

@gstorer
Copy link
Contributor Author

gstorer commented May 9, 2011

All of mdboom's comments implemented. I also changed backend_version while I was at it to be more consistent with the other backends. That is, a version string representing the GUI toolkit's version rather than something arbitrary.

@@ -91,7 +91,7 @@ class FigureCanvasQTAgg( FigureCanvasQT, FigureCanvasAgg ):
else:
stringBuffer = self.renderer._renderer.tostring_argb()

qImage = QtGui.QImage(stringBuffer, self.renderer.width,
qImage = QtGui.QImage(stringBuffer, self.renderer.width,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With ubuntu 11.4 (pyside 1.0.1 & qt4 4.7.2), I get a following exception.

TypeError: 'PySide.QtGui.QImage' called with wrong argument types:
PySide.QtGui.QImage(str, int, int, PySide.QtGui.QImage.Format)
Supported signatures:
PySide.QtGui.QImage()
PySide.QtGui.QImage(PySide.QtGui.QImage)
PySide.QtGui.QImage(PySide.QtCore.QSize, PySide.QtGui.QImage.Format)
PySide.QtGui.QImage(QString, str = None)
PySide.QtGui.QImage(int, int, PySide.QtGui.QImage.Format)
PySide.QtGui.QImage(buffer, int, int, PySide.QtGui.QImage.Format)
PySide.QtGui.QImage(buffer, int, int, int, PySide.QtGui.QImage.Format)

Converting stringBuffer to a buffer object explicitly seem to solve the problem (both pyqt and pyside works), but i'm not sure if this behavior will depend on the pyside version.

        qImage = QtGui.QImage(buffer(stringBuffer), int(self.renderer.width), 
                              int(self.renderer.height),

We may need a same change at line 117.
The agg renderer has a "buffer_rgba" method but QImage does not seem to support RGBA format.

-JJ

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a PySide bug fixed in 1.0.2 http://bugs.pyside.org/show_bug.cgi?id=489

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably add a version check against PySide then, since we know 1.0.2 is the minimum workable version.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good to know that this is a pyside bug. However, using explicit buffer call does any harm to matplotib w/ pyside v1.0.2?
I could be wrong but my guess is that if we call buffer explicitly, the code will work for both v1.0.2 and v1.0.1?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Wrapping with buffer makes it work in both versions. I was under the impression that mpl wasn't in the business of fixing bugs for specific versions of on specific platforms etc. In any case, there's another bug (819, see my opening comment) that wasn't fixed until 1.0.2 (try saving a figure). There is also an outstanding bug that prevents this backend working on mac (809) that won't be fixed until 1.0.3.

I'd suggest that 1.0.3 should probably be the minimum supported version to keep things simple. In which case this can stay as is. Unless there is a good reason to want to wrap with buffer() in any case?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my experience, mpl tries to broadly support as many versions of a library on as many platforms as feasible. I don't know if it's stated explicitly anywhere, but at least in my work environment, it is very important to support rather old and possibly buggy versions of core dependencies (e.g. GUI toolkits) for quite some time. Look at the GTK backend, for example, for a number of version-specific hacks that have been required over time. Eventually the idea is to prune that stuff out -- my own rule of thumb is to support at least as far back as whatever was in the (current release - 2) of RHEL.

In this specific case, however, with PySide being so new and cutting edge to begin with, I think it's ok to require a minimum version and not add hacks for 1.0.x which were fairly ephemeral and not widely-used releases. But the version check is important because user's should understand it's breaking because of an old version of PySide and not some other reason.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was inclined to fix the buffer thing since pyside v1.0.1 is packaged for ubuntu, and this simple fix at least makes the backend usable. Anyhow, I agree with Michael and the current approach is okay.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, that's good then.

As a side note, I was under the impression that Ubuntu was more or less the development platform for PySide. Every version of PySide is packaged for it within a few hours of release isn't it?

@gstorer
Copy link
Contributor Author

gstorer commented May 10, 2011

I've added a version check for 1.0.3 or greater. The PySide nightly builds are on 1.0.3 (http://www.pyside.org/files/nightly/) although you're limited to Windows or something Debian based.

@gstorer
Copy link
Contributor Author

gstorer commented May 27, 2011

PySide 1.0.3 has been released. I'll update the dev mailing list to solicit some final testing as packages become available.

@ddale
Copy link
Contributor

ddale commented Jun 5, 2011

Is this patch ready for final testing? It would be nice to merge in time for the next release.

@gstorer
Copy link
Contributor Author

gstorer commented Jun 7, 2011

Yep. The only thing I'm really waiting on is for someone to tell me there are no show stoppers in OS X. This has been a bit tricky since there isn't a PySide 1.0.3 package for OS X yet. I've asked for it on the PySide mailing list today.

@leejjoon
Copy link
Contributor

leejjoon commented Jun 9, 2011

I don't think we have to wait until we have a bug-free PySide. I'm +1 for pulling this immediately. We may update the version check later if necessary.

@leejjoon
Copy link
Contributor

leejjoon commented Jun 9, 2011

Running this code from command line raises an exception during the exit. This only happens for "pyside". With "pyqt", it runs okay. This is not a show stopper and this can be fixed after the patch is pulled.

import matplotlib.pyplot as plt
fig= plt.figure(1)
Error in atexit._run_exitfuncs:
Traceback (most recent call last):
  File "/usr/lib/python2.6/atexit.py", line 24, in _run_exitfuncs
    func(*targs, **kargs)
  File "/home/jjlee/.virtualenvs/mpl-head/lib/python2.6/site-packages/matplotlib/_pylab_helpers.py", line 82, in destroy_all
    manager.destroy()
  File "/home/jjlee/.virtualenvs/mpl-head/lib/python2.6/site-packages/matplotlib/backends/backend_qt4.py", line 373, in destroy
    self._widgetclosed )
RuntimeError: Internal C++ object (PySide.QtGui.QMainWindow) already deleted.
Error in sys.exitfunc:
Traceback (most recent call last):
  File "/usr/lib/python2.6/atexit.py", line 24, in _run_exitfuncs
    func(*targs, **kargs)
  File "/home/jjlee/.virtualenvs/mpl-head/lib/python2.6/site-packages/matplotlib/_pylab_helpers.py", line 82, in destroy_all
    manager.destroy()
  File "/home/jjlee/.virtualenvs/mpl-head/lib/python2.6/site-packages/matplotlib/backends/backend_qt4.py", line 373, in destroy
    self._widgetclosed )
RuntimeError: Internal C++ object (PySide.QtGui.QMainWindow) already deleted.

@gstorer
Copy link
Contributor Author

gstorer commented Jun 9, 2011

I actually get a error from both pyqt and pyside on exit...

@gstorer
Copy link
Contributor Author

gstorer commented Jun 14, 2011

I don't know what was going on before but I can't get a runtime error at all now. This might be platform specific. I'm mostly using Windows XP at work. At any rate I think this is good enough to be pulled into master.

ddale added a commit that referenced this pull request Jun 16, 2011
@ddale ddale merged commit cf0644a into matplotlib:master Jun 16, 2011
@richbwood richbwood mentioned this pull request Dec 19, 2012
magnunor pushed a commit to magnunor/matplotlib that referenced this pull request Dec 5, 2013
@QuLogic QuLogic modified the milestones: v1.1.0, v2.0.0 Nov 4, 2015
fariza added a commit to fariza/matplotlib that referenced this pull request Sep 22, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants