[pyzo] 28/68: Move pyzolib.qt to pyzo/util/qt

Ghislain Vaillant ghisvail-guest at moszumanska.debian.org
Wed Sep 28 09:47:09 UTC 2016


This is an automated email from the git hooks/post-receive script.

ghisvail-guest pushed a commit to branch debian/master
in repository pyzo.

commit 5112cdb8b2af90f5788c8ea1c30c994b57c6f8d2
Author: Almar Klein <almar.klein at gmail.com>
Date:   Mon Sep 5 12:37:35 2016 +0200

    Move pyzolib.qt to pyzo/util/qt
---
 pyzo/__init__.py                           |   2 +-
 pyzo/codeeditor/qt.py                      |  21 +-
 pyzo/core/about.py                         |   2 +-
 pyzo/core/assistant.py                     |   6 +-
 pyzo/core/baseTextCtrl.py                  |   2 +-
 pyzo/core/codeparser.py                    |   2 +-
 pyzo/core/compactTabWidget.py              |   2 +-
 pyzo/core/editor.py                        |   2 +-
 pyzo/core/editorTabs.py                    |   2 +-
 pyzo/core/icons.py                         |   2 +-
 pyzo/core/main.py                          |   2 +-
 pyzo/core/menu.py                          |   2 +-
 pyzo/core/shell.py                         |   2 +-
 pyzo/core/shellInfoDialog.py               |   2 +-
 pyzo/core/shellStack.py                    |   2 +-
 pyzo/core/splash.py                        |   2 +-
 pyzo/tools/__init__.py                     |   3 +-
 pyzo/tools/pyzoFileBrowser/__init__.py     |   2 +-
 pyzo/tools/pyzoFileBrowser/importwizard.py |   2 +-
 pyzo/tools/pyzoHistoryViewer.py            |   3 +-
 pyzo/tools/pyzoInteractiveHelp.py          |   3 +-
 pyzo/tools/pyzoLogger.py                   |   3 +-
 pyzo/tools/pyzoSourceStructure.py          |   4 +-
 pyzo/tools/pyzoWebBrowser.py               |   4 +-
 pyzo/tools/pyzoWorkspace.py                |   2 +-
 pyzo/util/_locale.py                       |   2 +-
 pyzo/util/bootstrapconda.py                |   2 +-
 pyzo/util/pyzowizard.py                    |   2 +-
 pyzo/util/qt/__init__.py                   | 385 +++++++++++++++++++++++++++++
 29 files changed, 422 insertions(+), 50 deletions(-)

diff --git a/pyzo/__init__.py b/pyzo/__init__.py
index 0d05bfd..3f3f468 100644
--- a/pyzo/__init__.py
+++ b/pyzo/__init__.py
@@ -80,7 +80,7 @@ else:
 
 
 from pyzolib import ssdf
-from pyzolib.qt import QtCore, QtGui
+from pyzo.util.qt import QtCore, QtGui
 
 # Import language/translation tools
 from pyzo.util._locale import translate, setLanguage
diff --git a/pyzo/codeeditor/qt.py b/pyzo/codeeditor/qt.py
index 91e3347..91e6a12 100644
--- a/pyzo/codeeditor/qt.py
+++ b/pyzo/codeeditor/qt.py
@@ -1,19 +1,2 @@
-import sys
-# Simple module to allow using both PySide and PyQt4
-
-try:
-    # This is a proper proxy
-    from pyzolib.qt import QtCore, QtGui
-except ImportError:
-    try:
-        #if sys.platform == 'darwin':
-        #    raise ImportError # PySide causes crashes on Mac OS X
-        
-        from PySide import QtCore, QtGui
-    except ImportError:
-        try:
-            from PyQt4 import QtCore, QtGui
-            QtCore.Signal = QtCore.pyqtSignal # Define signal as pyqtSignal
-        except ImportError:
-            raise ImportError("Both PySide and PyQt4 could not be imported.")
-
+# This is the one place where codeeditor depends on Pyzo itself
+from pyzo.util.qt import QtCore, QtGui
diff --git a/pyzo/core/about.py b/pyzo/core/about.py
index 283b910..71411f4 100644
--- a/pyzo/core/about.py
+++ b/pyzo/core/about.py
@@ -3,7 +3,7 @@ import os
 import sys
 
 import pyzolib
-from pyzolib.qt import QtCore, QtGui
+from pyzo.util.qt import QtCore, QtGui
 
 import pyzo
 from pyzo.util import paths
diff --git a/pyzo/core/assistant.py b/pyzo/core/assistant.py
index 81bc29b..5b5ccfa 100644
--- a/pyzo/core/assistant.py
+++ b/pyzo/core/assistant.py
@@ -15,7 +15,7 @@ Copy the "docs" directory to the pyzo root!
 
 """
 
-from pyzolib.qt import QtCore, QtGui
+from pyzo.util.qt import QtCore, QtGui
 from pyzo import getResourceDirs
 import os
 
@@ -132,7 +132,7 @@ class PyzoAssistant(QtGui.QWidget):
             When collection_file is none, it is determined from the
             appDataDir.
         """
-        from pyzolib.qt import QtHelp
+        from pyzo.util.qt import QtHelp
         super().__init__(parent)
         self.setWindowTitle('Help')
         pyzoDir, appDataDir = getResourceDirs()
@@ -257,7 +257,7 @@ class PyzoAssistant(QtGui.QWidget):
         self._helpBrowser.setSource(QtCore.QUrl(url))
 
     def showHelpForTerm(self, name):
-        from pyzolib.qt import QtHelp
+        from pyzo.util.qt import QtHelp
         # Cache for later use:
         self._search_term = name
 
diff --git a/pyzo/core/baseTextCtrl.py b/pyzo/core/baseTextCtrl.py
index d80eef2..0084edf 100644
--- a/pyzo/core/baseTextCtrl.py
+++ b/pyzo/core/baseTextCtrl.py
@@ -19,7 +19,7 @@ from pyzolib import ssdf
 from pyzo.core.pyzoLogging import print
 import pyzo.codeeditor.parsers.tokens as Tokens
 
-from pyzolib.qt import QtCore, QtGui
+from pyzo.util.qt import QtCore, QtGui
 qt = QtGui
 
 
diff --git a/pyzo/core/codeparser.py b/pyzo/core/codeparser.py
index e4d5cfe..86d91ed 100644
--- a/pyzo/core/codeparser.py
+++ b/pyzo/core/codeparser.py
@@ -15,7 +15,7 @@ structure of a source file in for example a tree widget.
 #TODO: replace this module, get data from the syntax highlighter in the code editor
 
 import time, threading, re
-from pyzolib.qt import QtCore, QtGui
+from pyzo.util.qt import QtCore, QtGui
 import pyzo
 
 
diff --git a/pyzo/core/compactTabWidget.py b/pyzo/core/compactTabWidget.py
index 8f4f4f3..f7b72b1 100644
--- a/pyzo/core/compactTabWidget.py
+++ b/pyzo/core/compactTabWidget.py
@@ -10,7 +10,7 @@ See docs of the tab widget.
 
 """
 
-from pyzolib.qt import QtCore, QtGui
+from pyzo.util.qt import QtCore, QtGui
 import sys
 
 if sys.version_info[0] < 3:
diff --git a/pyzo/core/editor.py b/pyzo/core/editor.py
index d8b04fa..27135ac 100644
--- a/pyzo/core/editor.py
+++ b/pyzo/core/editor.py
@@ -15,7 +15,7 @@ file loading/saving /reloading stuff.
 import os, sys
 import re, codecs
 
-from pyzolib.qt import QtCore, QtGui
+from pyzo.util.qt import QtCore, QtGui
 qt = QtGui
 
 from pyzo.codeeditor import Manager
diff --git a/pyzo/core/editorTabs.py b/pyzo/core/editorTabs.py
index 5b1a590..13d873f 100644
--- a/pyzo/core/editorTabs.py
+++ b/pyzo/core/editorTabs.py
@@ -15,7 +15,7 @@ It also has a find/replace widget that is at the bottom of the editor.
 """
 
 import os, sys, time, gc
-from pyzolib.qt import QtCore, QtGui
+from pyzo.util.qt import QtCore, QtGui
 
 import pyzo
 from pyzo.core.compactTabWidget import CompactTabWidget
diff --git a/pyzo/core/icons.py b/pyzo/core/icons.py
index 5584189..e509652 100644
--- a/pyzo/core/icons.py
+++ b/pyzo/core/icons.py
@@ -12,7 +12,7 @@ that show information to the user in a very effective, yet subtle manner.
 
 """
 
-from pyzolib.qt import QtCore, QtGui
+from pyzo.util.qt import QtCore, QtGui
 import pyzo
 
 
diff --git a/pyzo/core/main.py b/pyzo/core/main.py
index 705d358..ba2c6c1 100644
--- a/pyzo/core/main.py
+++ b/pyzo/core/main.py
@@ -20,7 +20,7 @@ from pyzolib import ssdf
 import pyzo
 from pyzo.core.icons import IconArtist
 from pyzo.core import commandline
-from pyzolib.qt import QtCore, QtGui
+from pyzo.util.qt import QtCore, QtGui
 from pyzo.core.splash import SplashWidget
 from pyzo.util import paths
 
diff --git a/pyzo/core/menu.py b/pyzo/core/menu.py
index 15783d8..fbd70b2 100644
--- a/pyzo/core/menu.py
+++ b/pyzo/core/menu.py
@@ -17,7 +17,7 @@ import unicodedata
 import datetime
 import webbrowser
 
-from pyzolib.qt import QtCore, QtGui
+from pyzo.util.qt import QtCore, QtGui
 
 import pyzo
 from pyzo.core.compactTabWidget import CompactTabWidget
diff --git a/pyzo/core/shell.py b/pyzo/core/shell.py
index 5b8a03b..ace41cb 100644
--- a/pyzo/core/shell.py
+++ b/pyzo/core/shell.py
@@ -16,7 +16,7 @@ code in it.
 
 """
 
-from pyzolib.qt import QtCore, QtGui
+from pyzo.util.qt import QtCore, QtGui
 Qt = QtCore.Qt
 
 import os, sys, time, subprocess
diff --git a/pyzo/core/shellInfoDialog.py b/pyzo/core/shellInfoDialog.py
index 4a04269..5257d19 100644
--- a/pyzo/core/shellInfoDialog.py
+++ b/pyzo/core/shellInfoDialog.py
@@ -12,7 +12,7 @@ Implements shell configuration dialog.
 """
 
 import os, sys, time, re
-from pyzolib.qt import QtCore, QtGui
+from pyzo.util.qt import QtCore, QtGui
 
 import pyzo
 from pyzo.core.compactTabWidget import CompactTabWidget
diff --git a/pyzo/core/shellStack.py b/pyzo/core/shellStack.py
index 89c1a74..4425ab2 100644
--- a/pyzo/core/shellStack.py
+++ b/pyzo/core/shellStack.py
@@ -14,7 +14,7 @@ and a dialog to edit the shell configurations.
 
 import os, sys, time, re
 import webbrowser
-from pyzolib.qt import QtCore, QtGui
+from pyzo.util.qt import QtCore, QtGui
 
 import pyzo
 from pyzo import translate
diff --git a/pyzo/core/splash.py b/pyzo/core/splash.py
index f06f4f0..c7d3b98 100644
--- a/pyzo/core/splash.py
+++ b/pyzo/core/splash.py
@@ -13,7 +13,7 @@ Defines splash window shown during startup.
 import os, sys, time
 
 import pyzo
-from pyzolib.qt import QtCore, QtGui
+from pyzo.util.qt import QtCore, QtGui
 
 
 STYLESHEET = """
diff --git a/pyzo/tools/__init__.py b/pyzo/tools/__init__.py
index 38fff9c..a7e574d 100644
--- a/pyzo/tools/__init__.py
+++ b/pyzo/tools/__init__.py
@@ -34,7 +34,8 @@ displayed in the statusbar.
 # - pythonpath editor, startupfile editor (or as part of pyzo?)
 
 import os, sys, imp
-from pyzolib.qt import QtCore, QtGui
+
+from pyzo.util.qt import QtCore, QtGui
 import pyzo
 
 from pyzolib import ssdf
diff --git a/pyzo/tools/pyzoFileBrowser/__init__.py b/pyzo/tools/pyzoFileBrowser/__init__.py
index 61342d4..08bed12 100644
--- a/pyzo/tools/pyzoFileBrowser/__init__.py
+++ b/pyzo/tools/pyzoFileBrowser/__init__.py
@@ -43,9 +43,9 @@ import sys
 import os.path as op
 
 from pyzolib import ssdf
-from pyzolib.qt import QtCore, QtGui
 
 import pyzo
+from pyzo.util.qt import QtCore, QtGui
 from .browser import Browser
 from .utils import cleanpath, isdir
 
diff --git a/pyzo/tools/pyzoFileBrowser/importwizard.py b/pyzo/tools/pyzoFileBrowser/importwizard.py
index eacca19..b5e21d5 100644
--- a/pyzo/tools/pyzoFileBrowser/importwizard.py
+++ b/pyzo/tools/pyzoFileBrowser/importwizard.py
@@ -26,7 +26,7 @@ import unicodedata
 import os.path as op
 
 import pyzo.codeeditor
-from pyzolib.qt import QtCore, QtGui
+from . import QtCore, QtGui
 from pyzo import translate
 
 
diff --git a/pyzo/tools/pyzoHistoryViewer.py b/pyzo/tools/pyzoHistoryViewer.py
index 335d396..04a204e 100644
--- a/pyzo/tools/pyzoHistoryViewer.py
+++ b/pyzo/tools/pyzoHistoryViewer.py
@@ -13,8 +13,9 @@ History class, which is a Qt model, and the PyzoHistoryViewer, which is a Qt vie
 """
 
 import sys, os, time, re
-from pyzolib.qt import QtCore, QtGui
+
 import pyzo
+from pyzo.util.qt import QtCore, QtGui
 from pyzo import translate
 from pyzo.core.menu import Menu
 
diff --git a/pyzo/tools/pyzoInteractiveHelp.py b/pyzo/tools/pyzoInteractiveHelp.py
index d2ead6e..feaa509 100644
--- a/pyzo/tools/pyzoInteractiveHelp.py
+++ b/pyzo/tools/pyzoInteractiveHelp.py
@@ -6,7 +6,8 @@
 
 
 import sys, os, time, re
-from pyzolib.qt import QtCore, QtGui
+
+from pyzo.util.qt import QtCore, QtGui
 import pyzo 
 
 tool_name = "Interactive help"
diff --git a/pyzo/tools/pyzoLogger.py b/pyzo/tools/pyzoLogger.py
index 15a58f7..6969019 100644
--- a/pyzo/tools/pyzoLogger.py
+++ b/pyzo/tools/pyzoLogger.py
@@ -6,8 +6,9 @@
 
 
 import sys, os, code
-from pyzolib.qt import QtCore, QtGui
+
 import pyzo
+from pyzo.util.qt import QtCore, QtGui
 from pyzo.core.shell import BaseShell
 from pyzo.core.pyzoLogging import splitConsole
 
diff --git a/pyzo/tools/pyzoSourceStructure.py b/pyzo/tools/pyzoSourceStructure.py
index fc0f3ae..66f1d7b 100644
--- a/pyzo/tools/pyzoSourceStructure.py
+++ b/pyzo/tools/pyzoSourceStructure.py
@@ -6,9 +6,9 @@
 
 
 import time
-from pyzolib.qt import QtCore, QtGui
-import pyzo
 
+import pyzo
+from pyzo.util.qt import QtCore, QtGui
 from pyzo import translate
 
 tool_name = "Source structure"
diff --git a/pyzo/tools/pyzoWebBrowser.py b/pyzo/tools/pyzoWebBrowser.py
index 017e4fd..883f290 100644
--- a/pyzo/tools/pyzoWebBrowser.py
+++ b/pyzo/tools/pyzoWebBrowser.py
@@ -7,11 +7,11 @@
 
 import time
 import urllib.request, urllib.parse
-from pyzolib.qt import QtCore, QtGui
 
+from pyzo.util.qt import QtCore, QtGui
 imported_qtwebkit = True
 try:
-    from pyzolib.qt import QtWebKit
+    from pyzo.util.qt import QtWebKit
 except ImportError:
     imported_qtwebkit = False
 
diff --git a/pyzo/tools/pyzoWorkspace.py b/pyzo/tools/pyzoWorkspace.py
index db510de..f419930 100644
--- a/pyzo/tools/pyzoWorkspace.py
+++ b/pyzo/tools/pyzoWorkspace.py
@@ -7,8 +7,8 @@
 
 import sys, os, time
 
-from pyzolib.qt import QtCore, QtGui
 import pyzo 
+from pyzo.util.qt import QtCore, QtGui
 
 tool_name = "Workspace"
 tool_summary = "Lists the variables in the current shell's namespace."
diff --git a/pyzo/util/_locale.py b/pyzo/util/_locale.py
index 1b9bbe9..2bad06b 100644
--- a/pyzo/util/_locale.py
+++ b/pyzo/util/_locale.py
@@ -9,9 +9,9 @@ Module for locale stuff like language and translations.
 """
 
 import os, sys, time
-from pyzolib.qt import QtCore, QtGui
 
 import pyzo
+from pyzo.util.qt import QtCore, QtGui
 
 QLocale = QtCore.QLocale
 
diff --git a/pyzo/util/bootstrapconda.py b/pyzo/util/bootstrapconda.py
index a1a5246..ea348b0 100644
--- a/pyzo/util/bootstrapconda.py
+++ b/pyzo/util/bootstrapconda.py
@@ -13,8 +13,8 @@ import threading
 import subprocess
 import urllib.request
 
-from pyzolib.qt import QtCore, QtGui
 import pyzo
+from pyzo.util.qt import QtCore, QtGui
 
 
 base_url = 'http://repo.continuum.io/miniconda/'
diff --git a/pyzo/util/pyzowizard.py b/pyzo/util/pyzowizard.py
index 8d4e49a..1a7b321 100644
--- a/pyzo/util/pyzowizard.py
+++ b/pyzo/util/pyzowizard.py
@@ -14,7 +14,7 @@ import os
 import re
 
 import pyzo
-from pyzolib.qt import QtCore, QtGui
+from pyzo.util.qt import QtCore, QtGui
 from pyzo import translate
 
 from pyzo.util._locale import LANGUAGES, LANGUAGE_SYNONYMS, setLanguage
diff --git a/pyzo/util/qt/__init__.py b/pyzo/util/qt/__init__.py
new file mode 100644
index 0000000..26f7eb5
--- /dev/null
+++ b/pyzo/util/qt/__init__.py
@@ -0,0 +1,385 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2016, Almar Klein
+#
+# This file is distributed under the terms of the (new) BSD License.
+
+""" Module that serves as a proxy for loading Qt libraries.
+
+This module has several goals:
+  * Import QtCore, QtGui, etc. from PySide or PyQt4 (whichever is available).
+  * Fix some incompatibilities between the two.
+  * For applications that bring their own Qt libs, avoid clashes.
+  * Allow using the PySide or PyQt4 libraries of the system 
+    (the ones in /usr/lib/...), so that frozen applications can look good.
+
+To use do ``from pyzo.util.qt import QtCore, QtGui``. Note that this proxy
+package is designed to be portable; it should be possible to use it in
+your own application or library.
+
+To use in frozen applications, create a qt.conf next to the executable,
+that has text as specified in DEFAULT_QT_CONF_TEXT. By modifying the 
+text, preferences can be changed.
+
+
+Notes
+-----
+
+To prevent colliding of Qt libs when an app brings its own libs, in
+particular on KDE, the plugins of Qt should be disabled. This needs
+to be done in two places:
+  * via qt.conf "Plugins = ''"
+  * set the QT_PLUGIN_PATH variable to empty string
+
+The latter is equivalent to QtGui.QApplication.setLibraryPaths([]),
+but has the advantage that it can be set beforehand.
+
+A downside of the plugins being disabled is that the native style
+(GTK+, Oxygen) cannot be used and other features (Unity integrated
+toolbar) are not available. This module allows a work-around by
+loading the native libs.
+
+"""
+
+import sys
+import os
+import imp
+import importlib
+
+VERBOSE = False
+
+
+
+def qt_name():
+    """ Return the name of the Qt lib in use: 'PySide', 'PyQt4' or None.
+    """
+    try:
+        importer_instance._import_qt()
+    except ImportError:
+        pass
+    else:
+        return importer_instance._qtPackage.__name__
+
+
+
+def loadWidget(filename, parent=None):
+    """ Load a widget from a .ui file. Returns a QWidget object.
+    """
+    
+    # Note that PyQt4 has PyQt4.uic.loadUi(filename, basewidget)
+    # allowing the newly created widget to inherit from a given widget
+    # instance. This is not supported in PySide and therefore not
+    # suported by this function.
+    
+    # Check
+    if not os.path.isfile(filename):
+        raise ValueError('Filename in loadWidget() is not a valid file.')
+    
+    if qt_name().lower() == 'pyside':
+        # Import (from PySide import QtCore, QtUiTools)
+        QtCore = importer_instance.load_module('QtCore')
+        QtUiTools = importer_instance.load_module('QtUiTools')
+        # Create loader and load widget
+        loader = QtUiTools.QUiLoader()
+        uifile = QtCore.QFile(filename)
+        uifile.open(QtCore.QFile.ReadOnly)
+        w = loader.load(uifile, parent)
+        uifile.close()
+        return w
+    else:
+        # Import (from PyQt4 import QtCore, uic)
+        QtCore = importer_instance.load_module('QtCore')
+        uic = importer_instance.load_module('uic')
+        # Load widget
+        w = uic.loadUi(filename)
+        # We set the parent explicitly
+        if parent is not None:
+            w.setParent(parent)
+        return w
+
+
+
+class QtProxyImporter:
+    """ Importer to import Qt modules, either from PySide or from PyQt,
+    and either from this Python's version, or the system ones (if
+    available and matching).
+    """
+    
+    def __init__(self):
+        self._qtPackage = None
+        self._enabled = True
+        self._import_path = None  # None for 'normal' (non-system) import
+    
+    
+    def find_module(self, fullname, path=None):
+        """ This is called by Python's import mechanism. We return ourself
+        only if this really looks like a Qt import, and when its imported
+        as a submodule from this stub package.
+        """
+        
+        # Only proceed if we are enabled
+        if not self._enabled:
+            return None
+        
+        # Get different parts of the module name
+        nameparts = fullname.split('.') 
+        
+        # sip is required by PyQt4
+        if fullname == 'sip':
+            self._import_qt()
+            return self
+        
+        # If the import is relative to this package, we will try to
+        # import relative to the selected qtPackage
+        if '.'.join(nameparts[:-1]) == __name__:
+            self._import_qt()
+            return self
+    
+    
+    def load_module(self, fullname):
+        """ This method is called by Python's import mechanism after
+        this instance has been returned from find_module. Here we
+        actually import the module and do some furher processing.
+        """
+        
+        # Get different parts of the module name
+        nameparts = fullname.split('.') 
+        modulename = nameparts[-1]
+        
+        # We can only proceed if qtPackage was loaded
+        if self._qtPackage is None:
+            raise ImportError()
+        
+        # Get qt dir or dummy
+        if self._import_path:
+            qtdir = os.path.dirname(self._qtPackage.__file__)
+        else:
+            qtdir = '/nonexisting/dir/with/subdirs/dummy'
+        
+        # Get real name and path to load it from    
+        if fullname == self._qtPackage.__name__:
+            return self._qtPackage
+        elif fullname == 'sip':
+            realmodulename = 'sip'
+            searchdir = os.path.dirname(qtdir)
+        elif modulename.startswith('Qt') or modulename == 'uic':
+            realmodulename = '%s.%s' % (self._qtPackage.__name__, modulename)
+            searchdir = qtdir
+        else:
+            raise ImportError()
+        
+        # Import. We also need to modify sys.path in case this is a system package
+        if os.path.isdir(qtdir):
+            if VERBOSE: print('load_module explicitly: %s' % fullname)
+            sys.path.insert(0, os.path.dirname(qtdir))
+            try:
+                for entry in os.listdir(searchdir):
+                    if entry.startswith(modulename+'.'):
+                        m = imp.load_dynamic(   realmodulename, 
+                                                os.path.join(searchdir, entry))
+                        break
+                else:
+                    raise ImportError('Could not import %s' % realmodulename)
+            finally:
+                sys.path.pop(0)
+        else:
+            # Module can be inside a zip-file when frozen
+            # Import normally, and disable ourselves so we do not recurse
+            if VERBOSE: print('load_module normally: %s' % realmodulename)
+            self._enabled = False
+            try:
+                p = __import__(realmodulename)
+            finally:
+                self._enabled = True
+            # Get the actual modele
+            if '.' in realmodulename:
+                m = getattr(p, modulename)
+            else:
+                m = p
+        
+        # Also register in sys.modules under the name as it was imported
+        sys.modules[realmodulename] = m
+        sys.modules[fullname] = m
+        
+        # Fix some compatibility issues
+        self._fix_compat(m)
+        
+        # Done
+        return m
+    
+    
+    def _determine_preference(self):
+        """ Determine preference by reading from qt.conf.
+        """
+        
+        # Get dirs to look for qt.conf
+        dirs = [os.path.dirname(sys.executable)]
+        script_dir = ''
+        if sys.path:
+            script_dir = sys.path[0]
+            if getattr(sys, 'frozen', None):
+                script_dir = os.path.dirname(script_dir)
+        dirs.append(script_dir)
+        
+        # Read qt.conf
+        for dir in dirs:
+            qt_conf = os.path.join(dir, 'qt.conf')
+            if os.path.isfile(qt_conf):
+                text = open(qt_conf, 'rb').read().decode('utf-8', 'ignore')
+                break
+        else:
+            text = ''
+        
+        # Parse qt.conf
+        prefer_system = False
+        prefer_toolkit = ''
+        #
+        for line in text.splitlines():
+            line = line.split('#',1)[0].strip()
+            if '=' not in line:
+                continue
+            key, val = [i.strip() for i in line.split('=', 1)]
+            if key == 'PreferSystem' and val.lower() in ('yes', 'true', '1'):
+                prefer_system = True
+            if key == 'PreferToolkit':
+                prefer_toolkit = val
+        
+        return prefer_system, prefer_toolkit
+    
+    
+    def _import_qt(self, toolkit=None):
+        """ This is where we import either PySide or PyQt4.
+        This is done only once.
+        """
+        
+        # Make qtPackage global and only proceed if its not set yet
+        if self._qtPackage is not None:
+            return
+        
+        # Establish preference
+        prefer_system, prefer_toolkit = self._determine_preference()
+        
+        # Check toolkit, use pyside by default
+        prefer_toolkit = toolkit or prefer_toolkit or 'pyside'
+        if prefer_toolkit.lower() not in ('pyside', 'pyqt4'):
+            prefer_toolkit = 'pyside'
+            print('Invalid Qt toolit preference given: "%s"' % prefer_toolkit)
+        
+        # Really import
+        self._qtPackage = self._import_qt_for_real(prefer_system, prefer_toolkit)
+        
+        # Disable plugins if necessary
+        if self._qtPackage and sys.platform.startswith('linux'):
+            if not self._qtPackage.__file__.startswith('/usr'):
+                os.environ['QT_PLUGIN_PATH'] = ''
+    
+    
+    def _import_qt_for_real(self, prefer_system, prefer_toolkit):
+        """ The actual importing.
+        """
+        
+        # Perhaps it is already loaded
+        if 'PySide' in sys.modules:
+            return sys.modules['PySide']
+        elif 'PyQt4' in sys.modules:
+            return sys.modules['PyQt4']
+        
+        # Init potential imports
+        pyside_imports = [('PySide', None)]
+        pyqt4_imports = [('PyQt4', None)]
+        pyside_system_imports = []
+        pyqt4_system_imports = []
+        
+        # Get possible paths, but only on Linux
+        if sys.platform.startswith('linux'):
+            # Determine where PySide or PyQt4 can be
+            ver = sys.version[:3]
+            possible_paths = ['/usr/local/lib/python%s/dist-packages' % ver,
+                os.path.expanduser('~/.local/lib/python%s/site-packages' % ver)]
+            if os.path.isdir('/usr/lib/python%s' % ver):
+                possible_paths.append('/usr/lib/python%s/dist-packages' % ver[0])
+            # Trty if it is there
+            for path in possible_paths:
+                if os.path.isdir(os.path.join(path, 'PySide')):
+                    pyside_system_imports.append(('PySide', path))
+                if os.path.isdir(os.path.join(path, 'PyQt4')):
+                    pyqt4_system_imports.append(('PyQt4', path))
+        
+        # Combine imports in right order
+        if prefer_system:
+            if 'pyside' == prefer_toolkit.lower():
+                imports =   pyside_system_imports + pyqt4_system_imports + \
+                            pyside_imports + pyqt4_imports
+            else:
+                imports =   pyqt4_system_imports + pyside_system_imports + \
+                            pyqt4_imports + pyside_imports
+        else:
+            if 'pyside' == prefer_toolkit.lower():
+                imports =   pyside_imports + pyqt4_imports #+ \
+                            #pyside_system_imports + pyqt4_system_imports
+            else:
+                imports =   pyqt4_imports + pyside_imports #+ \
+                            #pyqt4_system_imports + pyside_system_imports
+        
+        # Try importing
+        package = None
+        for package_name, path in imports:
+            if path:
+                sys.path.insert(0, path)
+            if VERBOSE: print('Attempting to import %s (system=%i)' % (package_name, bool(path)))
+            self._import_path = path
+            try:
+                return __import__(package_name, level=0)
+            except ImportError as err:
+                if VERBOSE: print('Import failed')
+            finally:
+                if path:
+                    sys.path.pop(0)
+        else:
+            raise ImportError('Could not import PySide nor PyQt4.')
+    
+    
+    def _fix_compat(self, m):
+        """ Fix incompatibilities between PySide and PyQt4. 
+        """
+        if self._qtPackage.__name__ == 'PySide':
+            pass
+        else:
+            if m.__name__.endswith('QtCore'):
+                m.Signal = m.pyqtSignal
+        
+        # todo: more compat, like uic loading
+
+
+importer_instance = QtProxyImporter()
+sys.meta_path.insert(0, importer_instance)
+
+
+
+
+DEFAULT_QT_CONF_TEXT = """## This file contains configuration options for Qt.
+## It disables plugins so that an application that brings its own 
+## Qt libraries do not clashs with the native Qt. It also has options
+## that the pyzo qt proxy uses to allow you to use your system
+## PySide/PyQt4 libraries.
+
+[Py]
+
+## Preferred toolkit: PySide or PyQt4
+PreferToolkit = PySide
+
+## Uncomment if pyzo should try to use the system libraries
+## Note that you version of Python must be ABI compatible with the
+## version on your system for this to work
+#PreferSystem = yes
+
+
+[Paths]
+
+## This disables plugins, avoiding Qt library clashes
+Plugins = ''
+
+## On Ubuntu Unity, if PreferSystem is enabled, uncomment this to
+## enable the fancy menu bar.
+#Plugins = /usr/lib/x86_64-linux-gnu/qt4/plugins
+
+"""

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/pyzo.git



More information about the debian-science-commits mailing list