瀏覽代碼

Merge branch 'master' of https://github.com/takluyver/pynsist into pyqt-opencv-example

Hugo Cachitas 8 年之前
父節點
當前提交
aced9b4d13

+ 17 - 0
doc/releasenotes.rst

@@ -1,6 +1,23 @@
 Release notes
 =============
 
+Version 1.8
+-----------
+
+* New example applications using:
+  - PyQt5 with QML
+  - `Pywebview <https://github.com/r0x0r/pywebview>`__
+* The code to pick an appropriate wheel now considers wheels with Python version
+  specific ABI tags like ``cp35m``, as well as the stable ABI tags like ``abi3``.
+* Fixed a bug with fetching a wheel when another version of the same package
+  is already cached.
+* Fixed a bug in extracting files from certain wheels.
+* Installers using :ref:`bundled Python <python_bundled>` may need a Windows
+  update package for the Microsoft C runtime. They now download this from the
+  `RawGit <https://rawgit.com/>`__ CDN, rather than hitting GitHub directly.
+* If the Windows update package fails to install, an error message will be
+  displayed.
+
 Version 1.7
 -----------
 

+ 9 - 0
examples/pyqt5_qml/basicqml/JSManager.qml

@@ -0,0 +1,9 @@
+import QtQuick 2.7
+import QtQuick.Controls 1.4
+import QtQuick.Dialogs 1.2
+import QtQuick.Layouts 1.1
+
+Item {
+    id: jsManager
+    signal text(string text)
+}

+ 0 - 0
examples/pyqt5_qml/basicqml/__init__.py


+ 17 - 0
examples/pyqt5_qml/basicqml/main.js

@@ -0,0 +1,17 @@
+"use strict";
+
+function JSManager() {
+    return Qt.createQmlObject("import JSManager 1.0; JSManager {}",
+                              appWindow, "JSManager");
+}
+
+function onLoad(){
+    var jsManager = new JSManager();
+
+    // Populate text
+    jsManager.text.connect(function(text){
+      jsText.text = text;
+    });
+
+    jsManager.get_text();
+}

+ 25 - 0
examples/pyqt5_qml/basicqml/main.py

@@ -0,0 +1,25 @@
+import os
+import sys
+import time
+import threading
+from PyQt5 import QtCore, QtGui, QtQml
+
+
+THIS_DIR = os.path.dirname(os.path.abspath(__file__))
+
+
+class JSManager(QtCore.QObject):
+    text = QtCore.pyqtSignal(QtCore.QVariant)
+
+    @QtCore.pyqtSlot()
+    def get_text(self):
+        def go():
+            _text = "Hello from JavaScript"
+            self.text.emit(_text)
+        threading.Thread(target=go).start()
+
+
+app = QtGui.QGuiApplication(sys.argv)
+QtQml.qmlRegisterType(JSManager, 'JSManager', 1, 0, 'JSManager')
+engine = QtQml.QQmlApplicationEngine(os.path.join(THIS_DIR, "main.qml"))
+app.exec_()

+ 36 - 0
examples/pyqt5_qml/basicqml/main.qml

@@ -0,0 +1,36 @@
+import QtQuick 2.7
+import QtQuick.Controls 1.4
+import QtQuick.Layouts 1.0
+
+import "main.js" as App
+
+ApplicationWindow {
+    id: appWindow
+    objectName: "appWindow"
+    visible: true
+    width: 800;
+    height: 600;
+
+    ColumnLayout {
+        anchors.horizontalCenter: parent.horizontalCenter
+        anchors.verticalCenter: parent.verticalCenter
+        anchors.margins: 3
+        spacing: 3
+        Column {
+            Text {
+                id: mainText
+                objectName: "mainText"
+                text: "Hello from QML"
+            }
+        }
+        Column {
+            Text {
+                id: jsText
+                objectName: "jsText"
+            }
+        }
+    }
+    Component.onCompleted: {
+        App.onLoad();
+    }
+}

+ 14 - 0
examples/pyqt5_qml/installer.cfg

@@ -0,0 +1,14 @@
+[Application]
+name=QML App (PyQt5)
+version=1.0
+entry_point=basicqml:main
+
+[Python]
+version=3.5.2
+bitness=64
+format=bundled
+
+[Include]
+packages=basicqml
+pypi_wheels= PyQt5==5.7
+    sip==4.18.1

+ 12 - 0
examples/pywebview/README.md

@@ -0,0 +1,12 @@
+This is an example [Pywebview](https://github.com/r0x0r/pywebview) application
+built using Pynsist.
+
+First, run `./download.sh` to fetch and unpack the necessary Windows libraries.
+Then build with:
+
+    pynsist installer.cfg
+
+At present, the user must separately install the MS Visual C++ 2010 redistributable,
+because pywin32 is compiled using that.
+
+http://www.microsoft.com/en-us/download/details.aspx?id=14632

+ 35 - 0
examples/pywebview/download.sh

@@ -0,0 +1,35 @@
+#!/bin/bash
+# Download pywin32 for Python 3.5, 64 bit
+set -e
+
+if [ ! -f pywin32.exe ]; then
+  wget -O pywin32.exe https://sourceforge.net/projects/pywin32/files/pywin32/Build%20220/pywin32-220.win-amd64-py3.5.exe
+fi
+
+# Comtypes (this is actually pure Python, but it's Windows only,
+# so it's easiest to get it like this)
+if [ ! -f comtypes.zip ]; then
+  wget -O comtypes.zip https://github.com/enthought/comtypes/archive/1.1.3.zip
+fi
+
+rm -rf pynsist_pkgs
+mkdir pynsist_pkgs
+
+# Unpack pywin32
+td=$(mktemp -d)
+unzip pywin32.exe -d $td || true  # Suppress some warning/error unzipping
+echo "Copying pywin32 files into pynsist_pkgs/"
+cp --recursive $td/PLATLIB/* pynsist_pkgs/
+rm -r $td
+
+# Unpack comtypes
+td=$(mktemp -d)
+unzip comtypes.zip -d $td
+# If comtypes.gen exists, it gets stuck trying to write there; if not, it
+# falls back to %APPDATA%.
+rm -r $td/comtypes-*/comtypes/gen/
+echo "Running 2to3 on comtypes"
+2to3 -wn --no-diffs $td/comtypes-*/comtypes/
+echo "Copying comtypes files into pynsist_pkgs/"
+cp --recursive $td/comtypes-*/comtypes pynsist_pkgs/
+rm -r $td

+ 19 - 0
examples/pywebview/installer.cfg

@@ -0,0 +1,19 @@
+[Application]
+name=Pywebview example
+version=1.0
+entry_point=simple_browser:main
+# Yuck, pywin32 stores modules in odd places, so we need this to get them loaded
+# correctly
+extra_preamble=pywin32_paths.py
+
+[Python]
+version=3.5.1
+bitness=64
+format=bundled
+
+[Include]
+# pywin32 should also be included here, but it contains many pieces in odd
+# locations, so it's probably not simple. When building from Linux, the
+# download.sh script copies the necessary files in.
+packages=comtypes
+  webview

+ 12 - 0
examples/pywebview/pywin32_paths.py

@@ -0,0 +1,12 @@
+sys.path.extend([
+    os.path.join(pkgdir, 'win32'),
+    os.path.join(pkgdir, 'win32', 'lib'),
+    os.path.join(pkgdir, 'Pythonwin'),
+])
+
+# Preload pywintypes and pythoncom
+pwt = os.path.join(pkgdir, 'pywin32_system32', 'pywintypes35.dll')
+pcom = os.path.join(pkgdir, 'pywin32_system32', 'pythoncom35.dll')
+import imp
+imp.load_dynamic('pywintypes', pwt)
+imp.load_dynamic('pythoncom', pcom)

+ 16 - 0
examples/pywebview/simple_browser.py

@@ -0,0 +1,16 @@
+"""
+This example demonstrates how to create a webview window.
+
+Adapted from a pywebview example:
+https://github.com/r0x0r/pywebview/blob/master/examples/simple_browser.py
+"""
+
+import webview
+
+def main():
+    # Create a non-resizable webview window with 800x600 dimensions
+    webview.create_window("Simple browser", "http://pynsist.readthedocs.io/",
+                            width=800, height=600, resizable=False)
+
+if __name__ == '__main__':
+    main()

+ 8 - 0
nsist/pyapp_msvcrt.nsi

@@ -54,6 +54,14 @@ Section "-msvcrt"
   # This WUSA exit code means a reboot is needed.
   ${If} $1 = 0x00240005
     SetRebootFlag true
+  ${Else}
+    IntOp $0 $1 & 0x80000000
+    ${If} $0 <> 0
+      MessageBox MB_OK "Failed to install important update! \
+            ${PRODUCT_NAME} will not run until you install the Visual C++ \
+            redistributable for Visual Studio 2015.\
+            $\n$\nhttp://www.microsoft.com/en-us/download/details.aspx?id=48145"
+    ${EndIf}
   ${EndIf}
 
   skip_msvcrt:

+ 2 - 0
nsist/pypi.py

@@ -91,6 +91,8 @@ class WheelDownloader(object):
                                    for p in release_dir.iterdir())
         if rel is None:
             return None
+
+        logger.info('Using cached wheel: %s', rel.filename)
         return release_dir / rel.filename
 
     def fetch(self):