pyqtdeploy, oder wir packen das Python-Programm in exe'shnik ... auf die harte Tour

KDPV


Sicherlich hat jeder, der mindestens einmal etwas in Python geschrieben hat, darüber nachgedacht, wie er sein Programm (oder sogar ein einfaches Skript) ohne Kopfschmerzen verteilen kann: ohne den Interpreter selbst installieren zu müssen, verschiedene Abhängigkeiten, plattformübergreifend, so dass eine Datei -exe'shnikom (als letztes Mittel, Archiv) und die kleinstmögliche Größe.


: PyInstaller, cx_Freeze, py2exe, py2app, Nuitka … , PyQt? , ( ) , PyQt, PyQt pyqtdeploy. , , , . , , , — ( ). , : , , , , .


pyqtdeploy , , , , ?


. linux. , "exe'" .


, ( ). PyInstaller — , , . 170 ( , PyQt5 180 ). , , — QtCore, QtGui, QtWidgets — . --exclude-module . , --onefile , 60 , . , , ( - ) 170 .


pyqtdeploy. " PyQt… - , - PyQt Qt?" — .


pyqtdeploy? , , . ( , PyQt, ) Qt ( rcc) , C++, , //… . pyqtdeploy Python 3.5+ PyQt5. ( ):


  • exe' PyQt4 PyQt5, Python 2.7 Python 3.3+ ( Python 3.7.2);
  • ( exe') ( , — );
  • :
    • android-32;
    • android-64;
    • ios-64;
    • linux-64;
    • macos-64;
    • win-32;
    • win-64;
  • PyQt Qt , - QtCore, - .

pyqtdeploy


, Python 3.5+ PyQt5:


pip install PyQt5 pyqtdeploy

exe' :


  • Python-, (!);
  • sysroot , ;
  • "" .pdy, exe' ( Qt, PyQt, Python, );
  • exe' qmake.


: main.py — " " , mainwindow.py — , resources icon.png mainwindow.ui, Qt Designer. , :


main.py
src/
    |---__init__.py
    |---gui/
        |---mainwindow.py
        |---__init__.py
    |---resources/
        |---__init__.py
        |---images/
            |---icon.png
            |---__init__.py
        |---ui/
            |---mainwindow.ui
            |---__init__.py

sysroot ()


, , . sysroot.json ( , ). , (Python, Qt ..). pyqtdeploy API, , //whatever, pyqtdeploy. ( ):


openssl ( ) — (). , sysroot.json, :


"android|macos|win#openssl": {
    "android#source": "openssl-1.0.2r.tar.gz",
    "macos|win#source": "openssl-1.1.0j.tar.gz",

    "win#no_asm": true
}

, , : arch1|arch2|...#plugin-name. , (ios, android, macos, win, linux), — . , .


:


  • source () — ;
  • no_asm ( ) — . , PATH nasm;
  • python_source ( ) — , , OpenSSL macOS Python v3.6.4 ;

zlib ( ) — ( , , , ) ():


"ios|linux|macos|win#zlib": {
    "source": "zlib-1.2.11.tar.gz",

    "static_msvc_runtime": true
}

:


  • source () — , ;
  • static_msvc_runtime ( ) — MSVC (Windows);

qt5 () — ():


"qt5": {
    "android-32#qt_dir": "android_armv7",
    "android-64#qt_dir": "android_arm64_v8a",
    "ios#qt_dir": "ios",

    "linux|macos|win#source": "qt-everywhere-src-5.12.2.tar.xz",
    "edition": "opensource",

    "android|linux#ssl": "openssl-runtime",
    "ios#ssl": "securetransport",
    "macos|win#ssl": "openssl-linked",

    "configure_options": [
        "-opengl", "desktop", "-no-dbus", "-qt-pcre"
    ],
    "skip": [
        "qtactiveqt", "qtconnectivity", "qtdoc", "qtgamepad",
        ...
    ],

    "static_msvc_runtime": true
}

:


  • qt_dir ( , source) — Qt;
  • source ( , qt_dir) — Qt;
  • edition (, source) — 2 :
    • commercial;
    • opensource;
  • ssl — 3 :
    • openssl-linked — ( openssl);
    • securetransport — SSL, Qt (, , Apple’s Secure Transport);
    • openssl-runtime — OpenSSL, ;
  • configure_options — , Qt. , ;
  • skip — ( , top-level , ). Qt , qt — top-level . , , . , top-level ();
  • disabled_features — . configure -list-features ()
  • static_msvc_runtime ( ) — MSVC (Windows);

python () — ():


"python": {
    "build_host_from_source": false,
    "build_target_from_source": true,
    "source": "Python-3.7.2.tar.xz"
}

:


  • build_host_from_source () — true — Python , false — Python ( win32);
  • build_target_from_source () — true — Python , false — Python ( Python win32);
  • source (, Python ) — Python;
  • version (, Python) — Python;
  • dynamic_loading ( ) — true — (, C);
  • host_installation_bin_dir ( ) — Python, ( , win , — PATH);

sip () — , Python-bindings C/C++ ( ):


"sip": {
    "module_name": "PyQt5.sip",
    "source": "sip-4.19.15.tar.gz"
}

:


  • module_name () — sip-;
  • source () — sip;

pyqt5 () — ():


"pyqt5": {
    "android#disabled_features": [
        "PyQt_Desktop_OpenGL", "PyQt_Printer", "PyQt_PrintDialog",
        "PyQt_PrintPreviewDialog", "PyQt_PrintPreviewWidget"
    ],
    "android#modules": [
        "QtCore", "QtGui", "QtNetwork", "QtPrintSupport", "QtWidgets",
        "QtAndroidExtras"
    ],

    "ios#disabled_features": [
        "PyQt_Desktop_OpenGL", "PyQt_MacOSXOnly",
        ...
    ],
    "ios|macos#modules": [
        "QtCore", "QtGui", "QtNetwork", "QtPrintSupport", "QtWidgets",
        "QtMacExtras"
    ],

    "linux#modules": [
        "QtCore", "QtGui", "QtNetwork", "QtPrintSupport", "QtWidgets",
        "QtX11Extras"
    ],

    "win#disabled_features": ["PyQt_Desktop_OpenGL"],
    "win#modules": [
        "QtCore", "QtGui", "QtNetwork", "QtPrintSupport", "QtWidgets",
        "QtWinExtras"
    ],

    "source": "PyQt5_*-5.12.1.tar.gz"
}

:


  • disabled_features ( ) — . , , Qt ();
  • modules () — , ();
  • source () — PyQt;

pyqt3D, pyqtchart, pyqtdatavisualization, pyqtpurchasing, qscintilla ( ) — , PyQt. source — .


, . sysroot , . , , .


sysroot


sysroot.json :


{
    "linux#zlib": {
        "source": "zlib-1.2.11.tar.gz"
    },

    "linux#qt5": {
        "source": "qt-everywhere-src-5.12.2.tar",
        "edition": "opensource",

        "configure_options": [
            "-no-dbus", "-no-system-proxies", "-no-cups", "-no-sql-db2",
            "-no-sql-ibase", "-no-sql-mysql", "-no-sql-sqlite",
            "-no-sql-sqlite2", "-no-sql-oci", "-no-sql-odbc",
            "-no-sql-psql", "-no-sql-tds", "-no-sqlite", "-ccache",
            "-optimize-size"
        ],
        "skip": [
            "qt3d", "qtactiveqt", "qtandroidextras", "qtcanvas3d",
            "qtcharts", "qtconnectivity", "qtdatavis3d", "qtdeclarative",
            "qtdoc", "qtgamepad", "qtgraphicaleffects", "qtlocation",
            "qtmacextras", "qtmultimedia", "qtnetworkauth", "qtpurchasing",
            "qtquickcontrols", "qtquickcontrols2", "qtremoteobjects",
            "qtscript", "qtscxml", "qtsensors", "qtserialbus",
            "qtserialport", "qtspeech", "qtsvg", "qttools",
            "qttranslations", "qtvirtualkeyboard", "qtwayland",
            "qtwebchannel", "qtwebengine", "qtwebglplugin",
            "qtwebsockets", "qtwebview", "qtwinextras", "qtx11extras",
            "qtxmlpatterns"
        ],
        "disabled_features": [
            "network", "bearermanagement", "dnslookup", "dtls", "ftp",
            "http", "localserver", "networkdiskcache", "networkinterface",
            "networkproxy", "socks5", "udpsocket", "concurrent", "future",
            "cups", "printer", "printdialog", "printpreviewdialog",
            "printpreviewwidget", "sql", "sqlmodel", "testlib", "xml"
        ]
    },

    "linux#python": {
        "build_host_from_source": false,
        "build_target_from_source": true,
        "source": "Python-3.7.2.tgz",

        "dynamic_loading": true
    },

    "linux#sip": {
        "module_name": "PyQt5.sip",
        "source": "sip-4.19.15.tar.gz"
    },

    "linux#pyqt5": {
        "modules": ["QtCore", "QtGui", "QtWidgets"],
        "source": "PyQt5_*-5.12.2.tar.gz"
    }
}

? -, (, ssl, pyqt3D ). -, exe' linux ( , linux-64; , ).


, qt5 - , (, ). top-level QtBase. -optimize-size -ccache. Qt , , ( 5 ), , — ccache ( , linux), ( 5). , apt install ccache.


pyqt5 QtCore, QtGui, QtWidgets.


python dynamic_loading, C-extension.


sysroot, : zlib, Qt5, Python, sip, PyQt5 sysroot.json ( , ). :


pyqtdeploy-sysroot sysroot.json

, .


--verbose. , , . , dev-. , . , python3-dev, (, Requirements). , Qt Python ( , ).


, , , .


"" ()


, , exe'. pyqtdeploy GUI. ( .pdy ):


pyqtdeploy main.pdy

Anwendungsquelle


Application Source. :


  • Name — exe';
  • Main script file ( , Entry Point) — , ( , main.py);
  • Entry Point ( , Main script file) — , setuptools;
  • sys.path — , zip- (, Python egg), sys.path ( , , );
  • Target Python version — Python;
  • Target PyQt version — PyQt4 PyQt5 (, , PyQt, );
  • Use console — , ( Windows). ;
  • Application bundle — , bundle ( MacOS);
  • Application Package Directory — , . Scan… "" (src) main.py, , . (.. main.py src), main.py ( , Main script file).

: .py "" ( -) — .


:


  • Scan… — Application Package Directory;
  • Remove all — Application Package Directory;
  • Include all — Application Package Directory;
  • Exclude all — Application Package Directory;
  • Exclusions — , Application Package Directory. ;

qmake. qmake, ( );


PyQt-Module


PyQt Modules. PyQt-, . , . QtCore, QtGui, QtWidgets, uic; sip .
PyQt, , ( ).


Standardbibliothek


Standard Library. , , . - , . ( ) , ().


. - ( pip), - ( ), ImportError. . , PIL, fractions.


Python / (, ssl), . , . INCLUDEPATH (headers), LIBS — ( , ).


Andere Pakete


Other Packages. (, pypi). , Application source: , ( , site-packages virtual environment), Scan / ( PIL).


Other Extension Modules. C, exe' (; , , ).


, . . Package Lib.a, Name , — Package.Lib ( .a); LIBS , , -L/home/user1/venv/programme1/lib/python3.7/site-packages/Package -lLib ( , " ", /home/user1/venv/programme1/lib/python3.7/site-packages/Package/Lib.a).


, , -, , -, qmake ( , pyqt' ).


, , , Lib.so? — Package.Lib.so (.. , + ) exe'. , . , ImportError. , , _imaging.so, PIL'.


Locations. , . ( sysroot , main.pdy), .


exe' ()


- :


pyqtdeploy-build main.pdy
cd build-linux-64
../sysroot-linux-64/host/bin/qmake
make #nmake  win

, , — .


#1 — , ""


, exe', , PyInstaller:


if getattr(sys, 'frozen', False):
    #   exe'
else:
    #    exe'

#2 — (, .)


Qt " ", rcc exe'. . icon.png src/resources/images, " " — :/src/resources/images/icon.png. , . — Qt' . .. - :


icon = QIcon(':/src/resources/images/icon.png')

. , , :


icon_file = open(':/src/resources/images/icon.png', 'rb')
icon = icon_file.read()

, open , , .


Qt (, , , GUI Qt Designer .ui, loadUi), - :


ui_file = QtCore.QFile(':/src/resources/images/icon.png')
ui_file.open(QtCore.QIODevice.ReadOnly)
data = ui_file.readAll()
ui_file.close()
ui_file = BytesIO(bytes(data))


, exe', - ? PyQt, , , . - ( PyInstaller). — . ~40 (c -optimize-size ~35 ), - , .


Wenn wir das minimal notwendige Qt und PyQt gesammelt haben, wäre es schön zu versuchen, mit PyInstaller oder cx_Freeze eine darauf basierende Exe zu erstellen und die Größe zu betrachten, aber dies ist, wie sie sagen, eine andere Geschichte ...

Source: https://habr.com/ru/post/undefined/


All Articles