Skip to content
macdeployqt output

PyQt and py2app: Seriously I don’t know what to do with you when you’re like this

PyQt and py2app: Seriously I don’t know what to do with you when you’re like this published on 9 Comments on PyQt and py2app: Seriously I don’t know what to do with you when you’re like this

OK. For some crazy reason I needed to display jpegs in my python application. I know! I am a wild woman! Somebody get me chamomile and sweatpants!

I’m going to spend a while telling you how you CAN’T get jpegs to show up. If you want you can skip this part and go down to where it says “DO NOT BE SCARED.”

No problem:

  • designing a UI in Qt Designer
  • writing the application in python
  • using Pixmaps to display images — pngs! jpegs! gifs! Whee!
  • creating an app with py2app (once you’ve got it successfully installed — and that is no mean feat. I’m looking for the link that saved me…)

Medium problem:

  • Getting the ” you might be loading two sets of Qt binaries” error to go away.

You can do this by including a blank qt.conf file in your application’s Resources folder (myApp.app/Contents/Resources). macdeployqt will make a qt.conf file for you — more on that later.

Big problem:

  • Seeing the jpegs when I run the app

WHY CAN’T I SEE MY JPEGS IN MY APPED-UP PYQT APPLICATION?

  • In Qt, jpeg support is a plugin. (Only png support is native.)
  • py2app will not link plugins libraries. No, it will not.

Some people got this to work in C :

I used the qtdeploy tool to copy the frameworks into my app and provided a path to the imageformats plugin folder. This caused deployqt to copy the plugins to my bundle as well and re-link those against the frameworks in the bundle respectively. This looked like this:

$ deployqt /path/to/myApp.app /path/to/qt/plugins/imageformats/

I had to add the following to my main.cpp to have the app load the libraries correctly:

–snip–
// Set the plugins directory correctly.
// This has to be done for bundles in OS X if they are packed using the deployqt tool.
#ifdef Q_WS_MAC
QDir dir(QApplication::applicationDirPath());
dir.cdUp();
dir.cd(“Plugins”);
QApplication::setLibraryPaths(QStringList(dir.absolutePath()));
#endif
–/snip–

Bastian Bense is very smart and persevering and I respect him. Also his advice to use macdeployqt is good, and I believe will solve your plugins issue IF you are building a C/Qt application. Even if you are making a python app, running macdeployqt on it automatically makes your qt.conf file that will get rid of the “two Qt libraries” warning.

(macdeployqt comes with Qt 4.5, and you will probably have to build it from source. I had a coworker slip me the executable. I recommend having resourceful coworkers.)

HOW TO RUN macdeployqt:

  • Build your app normally with py2app
  • Run macdeployqt on the resulting app like this:
    macdeployqt /path/to/your/app/MacOS/mySexyApp.app

And here’s an example of macdeployqt’s output:

macdeployqt output

Your plugins will appear in the folder PlugIns (note the capital *I* in Plug*I*ns).

If you like, you add that PlugIns directory to your library path like this:


if __name__ == ‘__main__’:

app = QApplication(sys.argv)
QApplication.addLibraryPath(QApplication.applicationDirPath() + “/../PlugIns”)
form = conformUI()
form.show()
sys.exit(app.exec_())

BUT. BUT BUT BUT.

If you built your app with py2app you still won’t see your jpegs.

To the best of my understanding, macdeployqt is designed to take care of stuff you would normally use otool and install_name_tool to do. But macdeployqt, otool or install_name_tool won’t help a py2app-built app, because the app forms its library links at runtime. I really don’t know much about otool or install_name_tool. I would love to be wrong about this. If I am wrong, please tell me.

NOW.

If you are like me you are depressed and scared that your beloved application is now down a featureset.

DO NOT BE SCARED.

I HAVE MADE JPEGS WORK IN MY PY2APP-BUILT APPLICATION.

I just used a ridiculous workaround. I open the images with PIL, transform them to png-friendly string content, and give that string content to a Pixmap.

I was already using reportlabs to make some PDFs, so I already had PIL (Python Imaging Library) installed.

Note that I had to install PIL as a prerequisite to using reportlabs because most of my images are pngs. Note that the only reason most of my images are pngs is because converting jpgs to pngs was my original workaround to jpgs not showing up in my python app. HA HA HA ROFLMAO.

RECIPE FOR JPEGS SHOWING IN PYTHON APP

  • Install PIL (Python Imaging Library)
  • Add these import statements:

    from PIL import Image
    import StringIO

  • Use code like this to make a PIL Image and turn it Pixmap:

    if panelItem.getImagePath() :
    pilImage = Image.open(panelItem.getImagePath())
    stringIO = StringIO.StringIO()

    pilImage.save(stringIO, format=’png’)
    pixmapImage = QPixmap()
    pixmapImage.loadFromData(stringIO.getvalue())

    if pixmapImage:
    pixmapImage = pixmapImage.scaledToWidth(preferredWidth)
    self.setPixmap(pixmapImage)

WHEWWWWWWWW. It takes a little longer to run, but it works.

py2app finds the PIL libraries and includes them, easy-peasy.

But nothing I can find will get a py2app-built application to pick up and use those Qt plugins directories. Nothing nothing nothing. It’s almost like putting libraries in the Qt plugins directory is the precise way to keep them safe from ever ending up in an app. It is like Arkham Asylum for libraries.

THE PLUGINS ARE RUNNING THE ASYLUM.

But I’m so freakin’ excited that my jpegs are showing up that I think I might cry.

Or get some chili.

Can’t decide.

I still py2app it to make the app and run macdeployqt to add the nice qt.conf.

(2,320 visits, 6 today)

9 Comments

Ok, it’s been three years since this post and the world has changed, but I found a stupid, but seemingly working, way to have my app bundle embed the *svg* plugins, which wasn’t included by default, and btw to fix the “you might be loading two sets of Qt binaries” infamous error. Your post helped me on the first part with the pointer to macdeployqt, I found out that the best, although dirty, way to finally achieve my end was :

1. python3 setup.py py2app
2. macdeployqt dist/Tkacz.app
(Ignore the long “WARNING: Could not find any external (…) before trying again.”
3. cp /Developer/Applications/Qt/plugins/imageformats/libqsvg.dylib dist/Tkacz.app/Contents/PlugIns/imageformats/
4. macdeployqt dist/Tkacz.app (Yes, again. That’s because I haven’t found a way to make it aware of the need to embed the SVG lib, but the app crashes after manual embedding. The second run seems to fix that.).

Maybe this may be helpful to someone struggling inside this strange asylum of bundling PyQt apps for osx.

Useless? No! Bizarre? Yes. Smelling of overkill? Quite. But ReportLab turned my application from broken to unbroken after a half day of pure *headdesk* — and for that I will buy them a beer.
Thank you for the advice to ask pythonmac. I should do that. I’ve seen most of my PyQt workarounds cause temporary euphoria and long-term coming-back-to-bite-you — I can hardly expect this one to be different.

Well, in this case, at least, I think the issue is with OS-X vs. Windows, rather than py2app vs. py2exe.

In generally, Windows is very sloppy with linking, which results in dll hell, but does sometimes make things like this easier to do.

As for your problem — that is a useless work-around if you want to write an app that can open a jpeg, which would be a pretty reasonable thing to want to do.

There has got to be a solution, however. I don’t know a thing about QT, and not much about the inner workings of linking on the Mac, but there are people that do on the pythomac list — I don’t think I’ve seen you there — it’s worth posting a question.

http://mail.python.org/mailman/listinfo/pythonmac-sig

After hours of stumbling around with the same issue, I’d like to share the that worked for me on windows:
using python2.6

copy the following directory into your dist directory generated by py2exe:
C:\Python26\Lib\site-packages\PyQt4\plugins\imageformats

I just dropped the imageformats directory directly into my dist directory, without any further modifications to qt.conf or anything like that. I haven’t tried it, but this may work for phonon as well.

Me and a coworker were just talking today about how py2exe seems to handle things better than py2app (also/as a result of more users, more documentation, more helper apps, etc.) I’m glad you got py2exe to bend to your will. I look forward to seeing what develops for Python on Mac.

Primary Sidebar