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

Already on GitHub? Sign in to your account

Pyside support #259

Merged
6 commits merged into from Feb 16, 2011

Conversation

Projects
None yet
3 participants
Contributor

epatters commented Feb 3, 2011

Adds a Qt bindings switcher to allow PyQt and PySide support. Because PySide only supports the new-style PyQt string API, a number of changes had to be made. Going forward, however, it should be easy to maintain support for both sets of bindings: just remember that implicit QString -> unicode, QByteArray -> str conversion is being performed. Incidentally, this should ease the Python 3 conversion, since PyQt in Python 3 only supports the new-style string API.

Note that even the most recent PySide beta 5 release will segfault sporadically. This is fixed in the PySide master branch and IPython will work with the upcoming RC 1 release.

Owner

takluyver commented Feb 4, 2011

Thanks, that will also help the Python 3 port, where the new string API is the default. I'd already made some of the relevant changes, but I suspect you've done a more thorough job than I did.

Owner

fperez commented Feb 9, 2011

Thanks for this work, Evan!

I merged and tested, and the PyQt part seems OK. But when I try to run with pyside, I get:

uqbar[~]> QT_API='pyside' iqlab
Traceback (most recent call last):
  File "/home/fperez/usr/bin/ipython-qtconsole", line 4, in 
    from IPython.frontend.qt.console.ipythonqt import main
  File "/home/fperez/usr/lib/python2.6/site-packages/IPython/frontend/qt/console/ipythonqt.py", line 18, in 
    from IPython.frontend.qt.kernelmanager import QtKernelManager
  File "/home/fperez/usr/lib/python2.6/site-packages/IPython/frontend/qt/kernelmanager.py", line 87, in 
    class QtSubSocketChannel(SocketChannelQObject, SubSocketChannel):
  File "/home/fperez/usr/lib/python2.6/site-packages/IPython/frontend/qt/kernelmanager.py", line 105, in QtSubSocketChannel
    display_data_received = QtCore.pyqtSignal(object)
AttributeError: 'module' object has no attribute 'pyqtSignal'

Note that I'm using pyside binaries indicated here: http://developer.qt.nokia.com/wiki/PySide_Binaries_Linux for Ubuntu 10.10. Do you think it's just that these bindings are incomplete, or is there an issue on your side of the code?

Contributor

epatters commented Feb 9, 2011

It looks the 'display_data_received' signal was added in the master branch after I started my 'pyside-support' branch, so I didn't fix it.

Compare this:

https://github.com/ipython/ipython/blob/master/IPython/frontend/qt/kernelmanager.py#L87

with this:

https://github.com/epatters/ipython/blob/pyside-support/IPython/frontend/qt/kernelmanager.py#L87

We need only replace QtCore.pyqtSignal with QtCore.Signal to fix this. Hopefully there are not too many other things to patch because of the time lag.

If you want, I can merge with the master branch to make sure this is right. But Brian suggested on the mailing list that I refrain from doing that.

Owner

fperez commented Feb 9, 2011

To keep the history a little cleaner and to be able to better see the work that's only new on this branch, doing a rebase against master would perhaps be the best option. Do you feel comfortable doing a rebase?

If you're OK rebasing against master, go ahead and do that; otherwise go ahead and merge master into your branch, it's not that bad.

Contributor

epatters commented Feb 9, 2011

I'll give the rebase a shot first. It's time I learn how to do that anyway.

Evan Patterson and others added some commits Jan 6, 2011

Paved the way for PySide support.
Created a Qt API switcher that imports PyQt4 or PySide as appropriate. If PyQt4 is loaded, the new-style QString API is used. This facillates both Python 3 and PySide compatibility.
Contributor

epatters commented Feb 9, 2011

OK, should be good to go. Let me know if you encounter further problems, Fernando.

Owner

fperez commented Feb 10, 2011

Hi Evan,

thanks, the new code causes no conflicts. But as soon as I tried running it, I opened a console and hit up arrow, and the window disappeared, with this message left on my terminal:

Segmentation fault
(epatters-pyside-support)uqbar[ipython]> Killed by parent poller!

Do you think this is due to the binary packages I'm using or a problem on your side?

Also, I would improve this message:

RuntimeError: Invalid Qt API "foo"

to read something like:

RuntimeError: Invalid Qt API "foo", valid values are: "pyqt" or "pyside"

Thanks for working on this, it looks like we're close, we just need to sort out where the crashes are coming from (I'm willing to install fresher packages for pyside if you think that's the issue).

Contributor

epatters commented Feb 10, 2011

That is indeed the issue. To get this working, I had to submit several bugs to the PySide team (which is why it took so long to get this pull request together). The upshot is that until the next beta/RC is released, you need to build PySide from the master branch. Fortunately, there are some Linux build scripts that make this very easy.

I'll do something about that message.

Owner

fperez commented Feb 11, 2011

OK, I built all of pyside from master (that took a while :) and now I don't see any segfaults. But trying to display something shows a problem:

In [2]: plot(rand(100))
Out[2]: []

In [3]: display(*getfigs())

# NOTE: nothing shows up here where the figure should be
In [3]: 

In [4]: 

In addition to no figure being displayed, this error appears on the console:

Error calling slot "_dispatch" 
Traceback (most recent call last):
  File "/home/fperez/ipython/ipython/IPython/frontend/qt/base_frontend_mixin.py", line 102, in _dispatch
    handler(msg)
  File "/home/fperez/ipython/ipython/IPython/frontend/qt/console/rich_ipython_widget.py", line 105, in _handle_display_data
    self._append_svg(svg)
  File "/home/fperez/ipython/ipython/IPython/frontend/qt/console/rich_ipython_widget.py", line 144, in _append_svg
    image = svg_to_image(svg)
  File "/home/fperez/ipython/ipython/IPython/frontend/qt/svg.py", line 71, in svg_to_image
    renderer = QtSvg.QSvgRenderer(QtCore.QByteArray(string))
TypeError: 'PySide.QtCore.QByteArray' called with wrong argument types:
  PySide.QtCore.QByteArray(unicode)
Supported signatures:
  PySide.QtCore.QByteArray()
  PySide.QtCore.QByteArray(PySide.QtCore.QByteArray)
  PySide.QtCore.QByteArray(str)
  PySide.QtCore.QByteArray(int, char)

I can test again once you sort this out, though I'm afraid I can't offer much help myself beyond testing :)

Owner

takluyver commented Feb 13, 2011

It looks like you're getting unicode from the json message, and Qt's XML reader expects an 8 bit string. svg_to_image(svg.encode("utf-8")) should resolve that.

Contributor

epatters commented Feb 15, 2011

Oddly, I could not reproduce Fernando's problem (my strings were always ASCII, not unicode). But in any case it should be fixed.

I hope this is the last of these incompatibility issues, although it probably isn't :)

Owner

fperez commented Feb 16, 2011

Great! No other issues that I can see from this side, so go for the merge. Many thanks!

This issue was closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment