Skip to content
New issue

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

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simple PyQt5 GUI Looks Like GTK When Compiling with PyInstaller on macOS and Windows #3417

Closed
leomoon opened this issue Mar 21, 2018 · 20 comments
Labels
area:hooks/PyQt5 Related to PyQt5 area:hooks Caused by or effecting some hook solution:duplicate Resolved: This issue is a duplicate.

Comments

@leomoon
Copy link

leomoon commented Mar 21, 2018

I used to build using PyInstaller and everything was working perfectly. I don't know what has changed. I had a pre-configured VM that I used to compile and now it doesn't work as expected.

When I build now, the GUI looks like GTK (very old looking GUI) for some reason.

I've made a VERY simple PyQt5 app and made a clean VM with Python 3.6.4, PyInstaller, PyQt5, and six.
I've tried on macOS 10.10, 10.13, Windows 10, Windows 10 VM.
I've tried --hidden-import=PyQt5
I've tried everything again using Python 3.6.3 and PyInstaller 3.3
I've tried everything again using Python 3.6.3 and PyInstaller dev

I'm running out of things to test.

Here is the simple PyQt5 app sample app:
PROBLEM.zip

Here is the build output:

C:\Users\Admin\Desktop\PROBLEM>C:\Python\python -m PyInstaller --paths C:\Python\Lib\site-packages\PyQt5\Qt\bin --add-binary *.dll;. --clean --noupx --name "TEST" main.py
250 INFO: PyInstaller: 3.4.dev0+1652c1968
265 INFO: Python: 3.6.4
265 INFO: Platform: Windows-10-10.0.16299-SP0
265 INFO: wrote C:\Users\Admin\Desktop\PROBLEM\TEST.spec
265 INFO: UPX is not available.
265 INFO: Removing temporary files and cleaning cache in C:\Users\Admin\AppData\Roaming\pyinstaller
296 INFO: Extending PYTHONPATH with paths
['C:\\Users\\Admin\\Desktop\\PROBLEM',
 'C:\\Python\\Lib\\site-packages\\PyQt5\\Qt\\bin',
 'C:\\Users\\Admin\\Desktop\\PROBLEM']
296 INFO: checking Analysis
312 INFO: Building Analysis because out00-Analysis.toc is non existent
312 INFO: Initializing module dependency graph...
312 INFO: Initializing module graph hooks...
312 INFO: Analyzing base_library.zip ...
3421 INFO: running Analysis out00-Analysis.toc
3437 INFO: Adding Microsoft.Windows.Common-Controls to dependent assemblies of final executable
  required by C:\Python\python.exe
3609 INFO: Caching module hooks...
3609 INFO: Analyzing C:\Users\Admin\Desktop\PROBLEM\main.py
3640 INFO: Loading module hooks...
3640 INFO: Loading module hook "hook-encodings.py"...
3718 INFO: Loading module hook "hook-pydoc.py"...
3718 INFO: Loading module hook "hook-PyQt5.py"...
3718 INFO: Loading module hook "hook-PyQt5.Qt.py"...
3718 INFO: Loading module hook "hook-PyQt5.QtCore.py"...
3782 INFO: Loading module hook "hook-PyQt5.QtGui.py"...
4125 INFO: Loading module hook "hook-PyQt5.QtPrintSupport.py"...
4171 INFO: Loading module hook "hook-PyQt5.QtWidgets.py"...
4187 INFO: Loading module hook "hook-xml.py"...
4422 INFO: Looking for ctypes DLLs
4437 INFO: Analyzing run-time hooks ...
4437 INFO: Including run-time hook 'pyi_rth_qt5.py'
4437 INFO: Looking for dynamic libraries
5187 INFO: Looking for eggs
5187 INFO: Using Python library C:\Python\python36.dll
5187 INFO: Found binding redirects:
[]
5203 INFO: Warnings written to C:\Users\Admin\Desktop\PROBLEM\build\TEST\warnTEST.txt
5250 INFO: Graph cross-reference written to C:\Users\Admin\Desktop\PROBLEM\build\TEST\xref-TEST.html
5281 INFO: Appending 'binaries' from .spec
5328 INFO: checking PYZ
5328 INFO: Building PYZ because out00-PYZ.toc is non existent
5328 INFO: Building PYZ (ZlibArchive) C:\Users\Admin\Desktop\PROBLEM\build\TEST\out00-PYZ.pyz
5890 INFO: Building PYZ (ZlibArchive) C:\Users\Admin\Desktop\PROBLEM\build\TEST\out00-PYZ.pyz completed successfully.
5906 INFO: checking PKG
5906 INFO: Building PKG because out00-PKG.toc is non existent
5906 INFO: Building PKG (CArchive) out00-PKG.pkg
5937 INFO: Building PKG (CArchive) out00-PKG.pkg completed successfully.
5953 INFO: Bootloader C:\Python\lib\site-packages\PyInstaller\bootloader\Windows-32bit\run.exe
5953 INFO: checking EXE
5953 INFO: Building EXE because out00-EXE.toc is non existent
5953 INFO: Building EXE from out00-EXE.toc
5953 INFO: Appending archive to EXE C:\Users\Admin\Desktop\PROBLEM\build\TEST\TEST.exe
5984 INFO: Building EXE from out00-EXE.toc completed successfully.
6000 INFO: checking COLLECT
6000 INFO: Building COLLECT because out00-COLLECT.toc is non existent
6000 INFO: Building COLLECT out00-COLLECT.toc
8703 INFO: Building COLLECT out00-COLLECT.toc completed successfully.

Any help is greatly appreciated.

@leomoon leomoon changed the title Simple PyQt5 GUI Looks Like GTK When Compiling with PyInstaller macOS and Windows Simple PyQt5 GUI Looks Like GTK When Compiling with PyInstaller on macOS and Windows Mar 21, 2018
@leomoon
Copy link
Author

leomoon commented Mar 21, 2018

Here is the simple PyQt5 app:

main.py:

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(136, 233)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout.setObjectName("verticalLayout")
        self.label = QtWidgets.QLabel(self.centralwidget)
        font = QtGui.QFont()
        font.setPointSize(36)
        font.setBold(True)
        font.setWeight(75)
        self.label.setFont(font)
        self.label.setAlignment(QtCore.Qt.AlignCenter)
        self.label.setObjectName("label")
        self.verticalLayout.addWidget(self.label)
        self.pushButton_4 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_4.setObjectName("pushButton_4")
        self.verticalLayout.addWidget(self.pushButton_4)
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setObjectName("pushButton")
        self.verticalLayout.addWidget(self.pushButton)
        self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_2.setObjectName("pushButton_2")
        self.verticalLayout.addWidget(self.pushButton_2)
        self.pushButton_3 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_3.setObjectName("pushButton_3")
        self.verticalLayout.addWidget(self.pushButton_3)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 136, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.label.setText(_translate("MainWindow", "TEST"))
        self.pushButton_4.setText(_translate("MainWindow", "PushButton"))
        self.pushButton.setText(_translate("MainWindow", "PushButton"))
        self.pushButton_2.setText(_translate("MainWindow", "PushButton"))
        self.pushButton_3.setText(_translate("MainWindow", "PushButton"))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

And I compile it using the command below:

C:\Python\python -m PyInstaller --paths C:\Python\Lib\site-packages\PyQt5\Qt\bin --hidden-import=PyQt5 --clean --noupx --name "TEST" main.py

@htgoebel
Copy link
Member

Looks like some files are not packages, e.g. icons, themes, etc. Please look at the https://github.com/pyinstaller/pyinstaller/wiki/Recipes or search the open and closed issue about the gui system you are using. And please have a look at Make sure everything is packaged correctly for tips to find out what is missing.

@htgoebel
Copy link
Member

Further you may search for some Qt theming guide.

@leomoon
Copy link
Author

leomoon commented Mar 21, 2018

My build process has not changed at all. The only things that have changed since it was working are:

sip (4.19.6) is now sip (4.19.8)
PyQt5 (5.9.2) is now PyQt5 (5.10.1)
PyInstaller 3.3 is now PyInstaller 3.3.1
Python 3.6.3 is now Python 3.6.4

I just tried installing everything again on a clean VM with the latest version of Python and PyInstaller but old version of PyQt5 and it works!

So something has changed in the new version of PyQt5 (after version 5.9.2).

I want to debug this for your guys but I don't know how to compare the two versions of PyQt5.

Any suggestions?

@tallforasmurf
Copy link
Contributor

Probably one or more of the theme files is not being included. @bjones1 has a rework of the PyQt5 hooks under way at #3233. If you are up for it, try getting his code at

https://github.com/bjones1/pyinstaller/tree/pyqt5_fix

and trying it. If it works, close this and add a note on that thread.

@leomoon
Copy link
Author

leomoon commented Mar 23, 2018

I confirm that the pyqt5_fix works. Use this dev version of PyInstaller if you must use the latest version of PyQt5:

https://github.com/bjones1/pyinstaller/tree/pyqt5_fix

Or install the latest stable version of PyInstaller (currently 3.3.1) and old versions of SIP and PyQt5 until the dev version of PyInstaller is merged with the main branch.

On Windows:

sip-4.19.6-cp36-none-win32.whl
PyQt5-5.9.2-5.9.3-cp35.cp36.cp37-none-win32.whl
pyqt5_tools-5.9.0.1.2-cp36-none-win32.whl (if you need the PyQt designer)

On macOS:

sip-4.19.8-cp36-cp36m-macosx_10_6_intel.whl
PyQt5-5.9.2-5.9.3-cp35.cp36.cp37-abi3-macosx_10_6_intel.whl

@leomoon leomoon closed this as completed Mar 23, 2018
@normanius
Copy link

Just wanted to confirm that pyqt5_fix_cleaned fixed the issue for me as well. Many thanks to @bjones1 and everyone who contributed to these fixes!

I upgraded from

   Python: 3.5.4 (v3.5.4:3f56838976, Aug  7 2017, 12:56:33) 
       Qt: Qt 5.9.3
     PyQt: 5.9.2 (Qt: 5.9.3)

to

   Python: 3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 05:52:31) 
       Qt: 5.10.1
     PyQt: 5.10.1 (Qt: 5.10.1)

For those that stumble upon this. "Very old GUI" (on MAC) means this:

very-old-looking-gui

Instead it should look like this:

macos-native

@htgoebel htgoebel added the solution:duplicate Resolved: This issue is a duplicate. label Sep 1, 2018
@htgoebel htgoebel added this to the PyInstaller 3.4 milestone Sep 2, 2018
@htgoebel htgoebel added area:hooks Caused by or effecting some hook area:hooks/PyQt5 Related to PyQt5 labels Sep 2, 2018
@mpasternak
Copy link

Should this be fixed in 3.4? I've just hit this issue on macOS with PyQt5 5.11.3 and PyQt5-sip 4.19.13. Downgrading to PyQt5 5.9.2 did not help. Apps look like ran on X11 server (no font anti-aliasing). Please help.

@htgoebel
Copy link
Member

Should this be fixed in 3.4?

@mpasternak Try it out

@mpasternak
Copy link

Looks like I expressed myself in an incorrect way, sorry for confusion.

I tried it with PyInstaller 3.4 and PyQt5 5.9.2 and 5.11.3 . App looks bad.

@bjones1
Copy link
Contributor

bjones1 commented Oct 31, 2018

@mpasternak, please provide a short example and I'll take a look.

@mpasternak
Copy link

Not exactly a short example, but the repo is here: http://github.com/mpasternak/pfreader-gui ; I've just re-added app.spec there.

Here's the log and here is the PNG file with screenshot. macOS Mojave 10.14.1 . packages.txt contains list of all packages in my venv.
packages.txt

pyinstaller.log.txt
zrzut ekranu 2018-10-31 o 17 06 57

@bjones1
Copy link
Contributor

bjones1 commented Oct 31, 2018

Provide me a short single-file source, post it here, and I'll be happy to built it on my PC (Windows). I don't want to download your git files.

@mpasternak
Copy link

@bjones1 , the problem occurs on macOS.

@bjones1
Copy link
Contributor

bjones1 commented Oct 31, 2018

Oops, sorry -- I misread the issue. I can't help here, since I don't own a Mac. Patches/fixes welcome. I'm guessing some needed PyQt5 files aren't copied -- if you can figure out what these are, that would help.

@mpasternak
Copy link

@bjones1 no need to sorry, I'm grateful for your time, thank you. There must be some files omitted because the app generated is 23 MB as opposed to the one generated with py2app (240 MB). On the other hand, albeit small, albeit no font aliasing, it seems to work.

I'm going to use py2app for now, but if anyone has any hints for pyinstaller, I'll be no less grateful. Thanks!

@htgoebel
Copy link
Member

htgoebel commented Nov 1, 2018

@mpasternak The original issue was for windows. Please be more careful when posting comments, as such mistakes cost the rare spare time of us volunteers. Thanks.

@kozmaz87
Copy link

kozmaz87 commented Feb 6, 2020

And the solution for windows does not seem to be added to this conversation so I am adding it now:
Most of Qt's plugins are not added by PyInstaller by default. The fix is simple: force its hand!

# Qt5 deps in stupid location
librarylocation = os.path.join(os.path.normpath(sys.exec_prefix), 'Library')

datas = datas | {
    ('{}/resources/*.*'.format(librarylocation), 'PyQt5/Qt/bin/'),
    ('{}/plugins/platforms'.format(librarylocation), 'platforms'),
    ('{}/plugins/imageformats'.format(librarylocation), 'imageformats'),
    ('{}/plugins/styles'.format(librarylocation), 'styles')
}

Add as many of those plugins as you need but in particular here you need the styles one, which has the windowsvista style that looks significantly better than the other 2.

@bjones1
Copy link
Contributor

bjones1 commented Feb 6, 2020

These files should already be copied by current PyInstaller.

@kozmaz87
Copy link

kozmaz87 commented Feb 6, 2020

I can assure you it does not get copied by 3.6 All the hooks are running and they miss all these dlls and everything.

UPDATE: So it seems that if you install PyQt5 from pip it is a very different layout in the venv from the one in a conda package. This fix relates to Anaconda which some of us has to suffer through... not my fav build system but the company I work for uses that.

The difference seems to be that in a pip package in a standard venv it is stored here:

Lib\site-packages\PyQt5\Qt\plugins

which looks good to me

In an Anaconda env it is here:

Library\plugins

while the rest of the PyQt5 package sits in

Lib\site-packages\PyQt5\

which I wholeheartedly agree is batshit crazy :D

PyInstaller may or may not claim to support it but since there is an virtual env however it may be layed out and the import works and functions then I would expect PyInstaller to find things. This may or may not be a bug depending how you look at it but it would warrant a warning maybe because I wasted a lot of time figuring this shit out :D

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 17, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area:hooks/PyQt5 Related to PyQt5 area:hooks Caused by or effecting some hook solution:duplicate Resolved: This issue is a duplicate.
Projects
None yet
Development

No branches or pull requests

7 participants