[IPython-dev] Qt api selection re. ipython and matplotlib

Brian Granger ellisonbg at gmail.com
Wed Jul 6 02:19:37 EDT 2011


On Tue, Jul 5, 2011 at 11:06 PM, MinRK <benjaminrk at gmail.com> wrote:
> On Jul 5, 2011, at 18:32, Darren Dale <dsdale24 at gmail.com> wrote:
>
>> On Tue, Jul 5, 2011 at 8:39 PM, MinRK <benjaminrk at gmail.com> wrote:
>>> On Tue, Jul 5, 2011 at 09:45, Eric Firing <efiring at hawaii.edu> wrote:
>>>> On 07/05/2011 01:36 AM, Darren Dale wrote:
>>>>>
>>>>> On Tue, Jul 5, 2011 at 2:22 AM, Eric Firing<efiring at hawaii.edu>  wrote:
>>>>>>
>>>>>> On 07/04/2011 06:51 PM, MinRK wrote:
>>>>>>>
>>>>>>> On Mon, Jul 4, 2011 at 20:57, Eric Firing<efiring at hawaii.edu>    wrote:
>>>>>>>>
>>>>>>>> If I remove the version-setting from qt.py, then ipython still works
>>>>>>>> with mpl and PyQt4 via "ipython pylab=qt", but it does not work with
>>>>>>>> qtconsole or with PySide.
>>>>>>>
>>>>>>> I don't think we are going to rewrite the whole qtconsole to support
>>>>>>> version 1 for 0.11 this week.  What we can do is change the default
>>>>>>> behavior in qt_for_kernel,
>>>>>>>
>>>>>>>
>>>>>>> (https://github.com/ipython/ipython/blob/master/IPython/external/qt_for_kernel.py)
>>>>>>> which is where code that interacts with other applications gets
>>>>>>> imported.  Currently, we use our v2 import unless matplotlib<= 1.0.1
>>>>>>> is detected.  However, we can change that default to be more
>>>>>>> conservative.  User code (e.g. matplotlib code, integration with other
>>>>>>> apps) is not in the same process as the QtConsole, so we can have v1
>>>>>>> code in the kernel with v2 in the frontend.
>>>>>
>>>>> Good point.
>>>>>
>>>>>> If ipython and mpl have to be synchronized, and if we want to be able to
>>>>>> choose to use pyside or pyqt4, then I think we need more than a change in
>>>>>> the ipython default.  It looks like this calls for yet another pesky
>>>>>> rcParams entry in mpl.  Then that can be used for figuring out what to
>>>>>> import in both matplotlib and ipython.  The default, if there is no
>>>>>> rcParams
>>>>>> entry, would be PyQt4 with the platform default API version.
>>>>>>
>>>>>> Darren, does this sound like a solution that would work for you?
>>>>>
>>>>> If ipython changes its qt_for_kernel to not set the api level, then it
>>>>> seems to me that either the environment variable approach or the
>>>>> rcParams approach will work for pylab/pyplot. The rcParams approach is
>>>>> a little awkward for folks using the OO interface, but it looks like
>>>>> it would work. You mentioned that it does not work with the ipython
>>>>> console and pyside though, what doesn't work?
>>>>
>>>> No figure is displayed after plotting, and then there is an error upon
>>>> exiting ipython if the figure (which was never displayed) is not closed.
>>>>
>>>> Eric
>>>>
>>>>
>>>
>>> I think the logic should be something along the lines of:
>>>
>>> if matplotlib:
>>>    if matplotlib <= 1.0.1:
>>>         use PyQt+v1 # old matplotlib can't support v2, if I
>>> understand correctly
>>>    else:
>>>         ask matplotlib
>>> if no answer or no matplotlib:
>>>    if QT_API defined:
>>>        if QT_API=pyqt:
>>>                use PyQt+v2 #because this is an ETS env variable, and
>>> ETS requires v2
>>>        elif QT_API=pyside:
>>>           use pyside
>>>    else:
>>>        try pyqt+v1
>>>        if no pyqt:
>>>             try pyside
>>>
>>> gist: QT_API should be respected if set, and use v2 unless matplotlib
>>> is too old to allow it.  If nothing is specified, the default is
>>> pyqt+v1, the safest option, but PySide should still be chosen if it's
>>> the only Qt installed.
>>>
>>> Does this make sense?
>>
>> You won't be able to tell what PyQt API to use from matplotlib. I
>> think the default api (version 1) would be the appropriate choice
>> unless QT_API is set, since as you say this is an ETS environment
>> variable and ETS is the only python2 library I am aware of that
>> actually requires PyQt4's v2 API. It would be useful to document this
>> somewhere, perhaps at
>> http://ipython.org/ipython-doc/dev/interactive/reference.html#gui-event-loop-support-support
>
> I didn't mean that it would ask matplotlib what PyQt API to use, only
> whether to use PyQt or PySide.  Eric issues a PR that suggested such
> an option was incoming.
>
> I've issued another pull request based on Eric's that handles various
> cases, and also tries to explain some of this mess in the docs as you
> suggested.
>
> PyQt4 unmolested will happen most of the time, but PySide when
> requested will still be used, and PySide will be a fallback for
> ``gui=qt`` if PyQt isn't installed.
>
> The *only* way PyQt4 will be using v2 is if the ETS env variable is
> set as QT_API=pyqt, *and* matplotlib had nothing to say about PyQt vs
> PySide (matplotlib being <= 1.0.1 also prevents PyQt with v2).  If we
> gathered from matplotlib that we should use PyQt, it will not be
> patched to v2.
>
> This places matplotlib / PyQt v1 code at the highest priority, but
> also allows ETS, and code that uses modern interfaces, to work via
> QT_API.
>
>>
>> By the way, I find the new ipython's new argument parsing really
>> non-intuitive. It took me 5 attempts to figure out how to do "ipython
>> gui=qt", even after skimming the output of "ipython -h". What's wrong
>> with "ipython --gui=qt"? Does ipython really need to put its own
>> unique spin on argument parsing?
>
> The reason for Brian's design here is that now the command line args
> are coupled with the config system.  Specifying a value on the command
> line is now identical to specifying it in a config file, so it looks
> like a Python assignment (because it is).  It also means that 100% of
> IPython is configurable from the command-line.

As Min mentions, the config system syntax *is* Python and we wanted to
use a syntax that reflected that.  When you do:

Foo.bar=10

At the command line, we parse that as Python code and run it through
the traits machinery.  Making this:

--Foo.bar=10

Only obscures the fact that it is parsed as Python.  This approach
also allows us to do things like the following at the command line:

Foo.bar=[0,1,2]

or even:

Foo.bar=range(3)

Which is then validated by traits as a list of ints.  We do realize
that there is going to be an adjustment period for users and we do
need to continue to improve documentation to point out these important
changes.

Cheers,

Brian

>
> -MinRK
> _______________________________________________
> IPython-dev mailing list
> IPython-dev at scipy.org
> http://mail.scipy.org/mailman/listinfo/ipython-dev
>



-- 
Brian E. Granger
Cal Poly State University, San Luis Obispo
bgranger at calpoly.edu and ellisonbg at gmail.com



More information about the IPython-dev mailing list