Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

PyQt5, OpenGL, where to start, minimal example code?

2,630 views
Skip to first unread message

John Ladasky

unread,
Oct 2, 2016, 9:14:13 PM10/2/16
to
Hi there,

I am making my first attempt at 3D rendering. My system configuration:

OS : Ubuntu 16.04 64-bit
Python : 3.5.1
Qt : 5.5.1
PyQt : 5.5.1
OpenGL : 4.5.0 (I have a modern GPU)

All software was installed from the Canonical repository. I didn't build any binaries myself.

From my reading, I have concluded that Qt, PyQt, and OpenGL are all rapidly-evolving, and huge, software packages. There may be compatibility problems, and relevant examples with the right software combination may be hard to find.

Two weeks of searching web pages hasn't turned up a single example which demonstrates PyQt5 doing something simple in 3D with OpenGL that I can study. My own attempt to write such a program displays my QOpenGLWidget subclass instance, and calls the methods I defined, but throws this exception:

ImportError: No module named 'PyQt5._QOpenGLFunctions_4_5_Compatibility'

Here's a snippet of the offending method of my QOpenGLWidget:

def initializeGL(self):
ctx = self.context() # This works, ctx is a PyQt5.QtGui.QOpenGLContext
print(ctx.versionFunctions()) # ImportError occurs here

Searching for that ImportError, I found a page which says that error occurs when "you have a more capable version of OpenGL than PyQt has support for", but no advice is offered on how to fix that problem.

I like the idea of using PyQt5, because I'm getting pretty familiar with it, BUT I am open to trying any quick and clear route to 3D rendering. I would appreciate the community's recommendations. Thanks.

blue

unread,
Oct 2, 2016, 10:21:15 PM10/2/16
to
You have here a PyQt5 Reference Guide http://pyqt.sourceforge.net/Docs/PyQt5/index.html
Some example can be found here 4 and 5 http://codeprogress.com/python/libraries/pyqt/

Support for OpenGL http://pyqt.sourceforge.net/Docs/PyQt5/opengl.html told us:

When compiled against Qt v5.1 or later, PyQt5 implements a set of either desktop QOpenGL bindings or OpenGL ES v2 bindings depending on how Qt was configured. This removes the dependency on any third-party OpenGL bindings such as PyOpenGL.

At the moment the desktop bindings are for OpenGL v2.0 and are mostly complete. Other versions will be added in later releases. If there are calls which you need, but are currently unsupported, then please ask for the support to be added.

Obtaining an object that implements the bindings for a particular OpenGL version and profile is done in the same way as it is done from C++, i.e. by calling versionFunctions(). In addition, the bindings object also contains attributes corresponding to all of the OpenGL constants.

Lawrence D’Oliveiro

unread,
Oct 2, 2016, 10:45:50 PM10/2/16
to
On Monday, October 3, 2016 at 2:14:13 PM UTC+13, John Ladasky wrote:
>
> I am making my first attempt at 3D rendering.

Bear in mind there are two kinds of 3D rendering: realtime (with OpenGL) and non-realtime.

John Ladasky

unread,
Oct 2, 2016, 11:14:30 PM10/2/16
to
Real time is what I want. My object is not complex, but I need to rotate it.

John Ladasky

unread,
Oct 2, 2016, 11:33:03 PM10/2/16
to
On Sunday, October 2, 2016 at 7:21:15 PM UTC-7, blue wrote:
> You have here a PyQt5 Reference Guide http://pyqt.sourceforge.net/Docs/PyQt5/index.html
> Some example can be found here 4 and 5 http://codeprogress.com/python/libraries/pyqt/

That's a nice page of examples, but there are no OpenGL examples.

> Support for OpenGL http://pyqt.sourceforge.net/Docs/PyQt5/opengl.html told us:
>
> When compiled against Qt v5.1 or later, PyQt5 implements a set of either desktop QOpenGL bindings or OpenGL ES v2 bindings depending on how Qt was configured. This removes the dependency on any third-party OpenGL bindings such as PyOpenGL.
>
> At the moment the desktop bindings are for OpenGL v2.0 and are mostly complete. Other versions will be added in later releases. If there are calls which you need, but are currently unsupported, then please ask for the support to be added.

I found that page many days ago. I am not sure whether OpenGL 4.5, which is what Ubuntu installed for me, is an extension of OpenGL ES v2, or something completely different.

PyQt5 seems to be at least nominally aware of recent versions of OpenGL, and it knows that I have version 4.5 -- since my program went looking for a module called "QOpenGLFunctions_4_5_Compatibility". On this page...

http://doc.qt.io/qt-5/qtgui-module.html

...the Qt5 QTGui documentation lists a plethora of functions to retrieve OpenGL "specifications" and "compatibility profiles", ranging from OpenGL 1.0 through 4.5.

Note, these are not PyQt docs, they are for Qt. I have been sometimes frustrated by the fact that the PyQt modules do not appear to have a one-to-one mapping with the hierarchy of Qt itself.

> Obtaining an object that implements the bindings for a particular OpenGL version and profile is done in the same way as it is done from C++, i.e. by calling versionFunctions(). In addition, the bindings object also contains attributes corresponding to all of the OpenGL constants.

And as you can see: trying to call versionFunctions() is exactly where my program failed.

Phil Thompson

unread,
Oct 3, 2016, 4:30:29 AM10/3/16
to
Try passing a QOpenGLVersionProfile object to versionFunctions() that has a version set to one supported by PyQt.

Phil

wxjm...@gmail.com

unread,
Oct 3, 2016, 5:23:12 AM10/3/16
to
-----

PyQt5 or ...

How to bind a Unicode compliant product/tools
with a non Unicode compliant toy.

Regards.


John Ladasky

unread,
Oct 4, 2016, 12:59:48 AM10/4/16
to
On Monday, October 3, 2016 at 1:30:29 AM UTC-7, Phil Thompson wrote:
> On 3 Oct 2016, at 4:29 am, John Ladasky <j...@s...net> wrote:

> > And as you can see: trying to call versionFunctions() is exactly where my program failed.
>
> Try passing a QOpenGLVersionProfile object to versionFunctions() that has a version set to one supported by PyQt.

Hi Phil,

I'm trying to follow your advice. It's strange, "from PyQt5.QtGui import QOpenGLVersionProfile" works fine, and I can make an object of that type.

However: http://pyqt.sourceforge.net/Docs/PyQt5/ DOES NOT DOCUMENT QOpenGLVersionProfile. I did find Qt documentation, at http://doc.qt.io/qt-5/qopenglversionprofile.html. I will investigate this issue further. Sometimes it isn't obvious how the C++ constructors are wrapped in Python.

If I ever understand a GUI like PyQt5 well enough, I'd like to contribute to its documentation. Sigh.

Phil Thompson

unread,
Oct 4, 2016, 3:56:53 AM10/4/16
to
On 4 Oct 2016, at 5:57 am, John Ladasky <john_l...@sbcglobal.net> wrote:
>
> On Monday, October 3, 2016 at 1:30:29 AM UTC-7, Phil Thompson wrote:
>> On 3 Oct 2016, at 4:29 am, John Ladasky <j...@s...net> wrote:
>
>>> And as you can see: trying to call versionFunctions() is exactly where my program failed.
>>
>> Try passing a QOpenGLVersionProfile object to versionFunctions() that has a version set to one supported by PyQt.
>
> Hi Phil,
>
> I'm trying to follow your advice. It's strange, "from PyQt5.QtGui import QOpenGLVersionProfile" works fine, and I can make an object of that type.
>
> However: http://pyqt.sourceforge.net/Docs/PyQt5/ DOES NOT DOCUMENT QOpenGLVersionProfile. I did find Qt documentation, at http://doc.qt.io/qt-5/qopenglversionprofile.html. I will investigate this issue further. Sometimes it isn't obvious how the C++ constructors are wrapped in Python.

QOpenGLVersonProfile missing from the docs is a bug.

> If I ever understand a GUI like PyQt5 well enough, I'd like to contribute to its documentation. Sigh.

If you are an OpenGL expert then you could help a lot by answering my questions about how individual functions should be bound.

Phil

John Ladasky

unread,
Oct 9, 2016, 1:21:00 AM10/9/16
to
Well, I've made some progress. My program doesn't draw any 3D objects yet, but it creates an OpenGL rendering window, binds the OpenGL functions, and generates no errors. Here's the corrected initializeGL method:


def initializeGL(self):
c = self.context()
f = QSurfaceFormat() # The default
p = QOpenGLVersionProfile(f)
self.GL = c.versionFunctions(p)
super().initializeGL()



On Tuesday, October 4, 2016 at 12:56:53 AM UTC-7, Phil Thompson wrote:
> On 4 Oct 2016, at 5:57 am, John Ladasky <j...@s...net> wrote:
> >
> > On Monday, October 3, 2016 at 1:30:29 AM UTC-7, Phil Thompson wrote:
> >> On 3 Oct 2016, at 4:29 am, John Ladasky <j...@s...net> wrote:
> > If I ever understand a GUI like PyQt5 well enough, I'd like to contribute to its documentation. Sigh.
>
> If you are an OpenGL expert

Ha!

While I have experience with quite a few scientific computing Python tools (numpy, scipy, matplotlib, pandas, scikit-learn), I know less about OpenGL than I do PyQt5. There's always more to learn.

>then you could help a lot by answering my questions about how individual functions should be bound.

In all the examples I've encountered on the Net (most of which are written in C++ -- or if they are PyQt examples, they're binding older versions of OpenGL), the preferred approach seems to be the one that I've taken above. If you want to call an OpenGL function, you have to look it up in the self.GL namespace.
0 new messages