13

I looked this question here:

Is it possible to require PyQt from setuptools setup.py?

What's the proper way of distributing a python application that has a gui and it's based on PyQt ? (I am using PyQt5 and Python3)

I am still learning how to distribute things, so I don't know if my question makes sense.


Edit:

The answer is correct, sudo pip3 install . worked for me for my own setup.py file, but apparently pyqt5 doesn't include QtWebKitWidgets module, and it isn't available for installation in a separate package in pip3. So now I am thinking of moving away from Python completely and go with Javascript + Electron as a multiplataform easy to run language for development.

Community
  • 1
  • 1
eri0o
  • 2,285
  • 4
  • 27
  • 43

1 Answers1

10

Can I require PyQt5 via setup.py?

In a word yes, as long as you restrict your support to PyQt5 and Python3.

The requirements specified in setup.py are typically provided by requesting packages from the Python Package Index (PyPi). Until recently these packages were source only, meaning that an installation depending on PyQt5 would only work on a system where it was possible to build it from source. Building on Windows in particular requires quite a lot of set up, and this would therefore put your application out of reach for anyone unable or unwilling to do this.

Note: As far as I am aware, it was never actually possible to build from source via PyPi. The standard approach was to download the source/binaries from Riverbank Software and build/install from there.

This problem was solved by the introduction of Python Wheels which provide a means to install C extension packages without the need for compilation on the target system. This is achieved by platform-specific .whl files. Wheels for PyQt5 on Python3 are available on PyPi for multiple platforms, including MacOS X, Linux (any), Win32 and Win64 which should cover most uses.

For example, this is the output when pip-installing PyQt5 on Python3 on a Mac:

mfitzp@MacBook-Air ~ $ pip3 install pyqt5
Collecting pyqt5
  Downloading PyQt5-5.6-cp35-cp35m-macosx_10_6_intel.whl (73.2MB)
    100% |████████████████████████████████| 73.2MB 2.5kB/s 
Collecting sip (from pyqt5)
  Downloading sip-4.18-cp35-cp35m-macosx_10_6_intel.whl (46kB)
    100% |████████████████████████████████| 49kB 1.8MB/s 
Installing collected packages: sip, pyqt5
Successfully installed pyqt5-5.6 sip-4.18

To set PyQt5 as a dependency of your own package simply specify it as normal in your setup.py e.g. install_requires=['PyQt5']

What's the proper way of distributing a Python GUI application?

Here you have a few options. The above means that anyone with Python3 installed can now install your application using pip. However, this assumes that the end-user has Python and knows what pip is. If you are looking to distribute your application with a Windows installer, MacOSX 'app' bundle, or Linux package, you will need to use one of the tools dedicated to that purpose.

Windows

  • cx_Freeze is a cross-platform packager that can package Python applications for Windows, Mac and Linux. It works by analysing your project and freezing the required packages and subpackages. Success depends largely on which packages you depend on and their complexity/correctness.
  • PyInstaller is another cross-platform packager that can package Python applications for Windows, Mac and Linux. This works in a similar way to cx_Freeze and will likely perform both better/worse depending on the packages.
  • PyNSISt builds NSIS installer packages for Windows. This has the advantage of being very straightforward: it simply packages all the files together as-is, without 'freezing'. The downside is that packages can end up very large and slower to install (but see the file-filter options). It now supports bundling of .whl files which will solve this in many cases. By far the easiest if you're targeting Windows-only.

MacOSX

  • cx_Freeze see above.
  • PyInstaller see above.
  • Py2app creates .app bundles from the definition in your setup.py. Big advantage is the custom handlers that allow you to adjust packaging of troublesome packages. If you're only targetting MacOSX this is probably your best option.

Linux

Note: It is possible to write a very complex setup.py that allows you to build using one or more tools on different platforms, but I have usually ended up storing separate configs (e.g. setup-py2app.py) for clarity.

mfitzp
  • 15,275
  • 7
  • 50
  • 70
  • So I can write `install_requires=['PyQt5']` inside setup.py now? – eri0o May 18 '16 at 23:46
  • 1
    @Elric sure can — just tested it here to be sure, and it's fine. – mfitzp May 18 '16 at 23:53
  • Ok, tested here. Wheels still aren't available for Ubuntu (and I think any other Linux distribution). So it won't work unless you are in Mac OS. – eri0o May 19 '16 at 11:54
  • @Elric Not just MacOS X but also Win32 and Win64 are there and work (just tested here). What does it give when trying on Ubuntu? The "manylinux" should work - although that wheel is 64bit only so wont work on 32bit linux. – mfitzp May 19 '16 at 12:02
  • 3
    It might be worth mentioning [PyInstaller](http://www.pyinstaller.org/) too - I switched to it from cx_Freeze because of various problems and it not being maintained very well, and I'm really happy with PyInstaller. – The Compiler May 20 '16 at 10:54
  • Linux wheels probably require a new version of pip to install them - if they're not installing, try `pip install --upgrade pip` first. – Thomas K May 22 '16 at 19:16
  • 1
    Pynsist can now build installers using wheels, which makes it super easy to package a PyQt5 app. Example config file here: https://github.com/takluyver/pynsist/blob/master/examples/pyqt5/installer.cfg – Thomas K May 22 '16 at 19:17
  • @TheCompiler thanks for the tip, I completely forgot about PyInstaller (not used it before, but will give it a go). – mfitzp May 23 '16 at 00:11