diff options
author | Alexandru Croitor <alexandru.croitor@qt.io> | 2018-04-17 14:12:50 +0200 |
---|---|---|
committer | Alexandru Croitor <alexandru.croitor@qt.io> | 2018-04-20 13:48:40 +0000 |
commit | f3e798c4572e308f6f520c6d966ae7f74fe835b7 (patch) | |
tree | bcf7cebcc9fb224d161ff491494294fd66c78ffe /sources/pyside2/libpyside | |
parent | 516682fc232db273511440d3c7107ab15f08b5ea (diff) |
Improve qt.conf registration handling
When PyInstaller is used to deploy a PySide2 application, it changes
the layout of the copied PySide2 files (no Qt subfolder, all shared
libraries are copied next to tehe generated executable). In that case
using the internal qt.conf won't work.
Detect if there a exists a qt.conf file next to the executable, and
use that file instead.
Note that this won't work when the executable path has unicode
characters in conjunction with Python 2 and Windows, but that is an
unsupported config anyway (due to the mixing MSVC issue).
Also add a logging category to ease figuring out which qt.conf file
is used if a need ever arises to do so.
Task-number: PYSIDE-642
Change-Id: I1260cbc13e5e62be72c4ed9c64c2aa5905d2e9c6
Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
Diffstat (limited to 'sources/pyside2/libpyside')
-rw-r--r-- | sources/pyside2/libpyside/pyside.cpp | 41 | ||||
-rw-r--r-- | sources/pyside2/libpyside/pyside.h | 3 |
2 files changed, 43 insertions, 1 deletions
diff --git a/sources/pyside2/libpyside/pyside.cpp b/sources/pyside2/libpyside/pyside.cpp index 1a59c87e0..51bbb22e1 100644 --- a/sources/pyside2/libpyside/pyside.cpp +++ b/sources/pyside2/libpyside/pyside.cpp @@ -442,6 +442,11 @@ static const unsigned char qt_resource_struct[] = { 0x0,0x0,0x0,0x16,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0 }; +// Note that setting QT_LOGGING_RULES for categories used before QCoreApplication is instantiated, +// will only work on Qt 5.9.4+. On lower versions, it will appear that setting QT_LOGGING_RULES +// does not affect lcPysideQtConf in any way. +Q_LOGGING_CATEGORY(lcPySide2, "pyside2", QtWarningMsg) + bool registerInternalQtConf() { // Guard to ensure single registration. @@ -449,18 +454,49 @@ bool registerInternalQtConf() static bool registrationAttempted = false; #else static bool registrationAttempted = true; + qCDebug(lcPySide2) << "PySide2 was built without qt.conf modification support. " + "No special qt.conf behavior will be applied."; #endif static bool isRegistered = false; if (registrationAttempted) return isRegistered; registrationAttempted = true; + // Support PyInstaller case when a qt.conf file might be provided next to the generated + // PyInstaller executable. + // This will disable the internal qt.conf which points to the PySide2 subdirectory (due to the + // subdirectory not existing anymore). + QString executablePath = +#if PY_MAJOR_VERSION >= 3 + QString::fromWCharArray(Py_GetProgramFullPath()); +#else + // Python 2 unfortunately returns a char* array instead of a wchar*, which means that on + // Windows if the executable path contains unicode characters, the returned path will be + // invalid. We can't use QCoreApplication::applicationFilePath because it requires an + // existing QCoreApplication instance despite being a static method. + // This means that a qt.conf near an executable won't be picked up correctly on + // Windows + Python 2. + QString::fromLocal8Bit(Py_GetProgramFullPath()); +#endif + QString appDirPath = QFileInfo(executablePath).absolutePath(); + QString maybeQtConfPath = QDir(appDirPath).filePath(QStringLiteral("qt.conf")); + bool executableQtConfAvailable = QFileInfo::exists(maybeQtConfPath); + maybeQtConfPath = QDir::toNativeSeparators(maybeQtConfPath); + if (!executableQtConfAvailable) { + qCDebug(lcPySide2) << "No qt.conf found near executable at: " << maybeQtConfPath + << "\nTrying next candidates."; + } + // Allow disabling the usage of the internal qt.conf. This is necessary for tests to work, // because tests are executed before the package is installed, and thus the Prefix specified // in qt.conf would point to a not yet existing location. bool disableInternalQtConf = qEnvironmentVariableIntValue("PYSIDE_DISABLE_INTERNAL_QT_CONF") > 0 ? true : false; - if (disableInternalQtConf) { + if (disableInternalQtConf || executableQtConfAvailable) { + if (executableQtConfAvailable) + qCDebug(lcPySide2) << "Using qt.conf found near executable at: " << maybeQtConfPath; + if (disableInternalQtConf) + qCDebug(lcPySide2) << "Internal qt.conf usage disabled via environment variable."; registrationAttempted = true; return false; } @@ -517,6 +553,9 @@ bool registerInternalQtConf() reinterpret_cast<const unsigned char *>( rccData.constData())); + if (isRegistered) + qCDebug(lcPySide2) << "Using internal qt.conf with prefix pointing to: " << prefixPath; + return isRegistered; } diff --git a/sources/pyside2/libpyside/pyside.h b/sources/pyside2/libpyside/pyside.h index becb92208..d36965d7b 100644 --- a/sources/pyside2/libpyside/pyside.h +++ b/sources/pyside2/libpyside/pyside.h @@ -50,6 +50,7 @@ #include <QMetaType> #include <QHash> #include <QList> +#include <QLoggingCategory> struct SbkObjectType; @@ -163,6 +164,8 @@ PYSIDE_API QString pyStringToQString(PyObject *str); */ PYSIDE_API bool registerInternalQtConf(); +Q_DECLARE_LOGGING_CATEGORY(lcPySide2) + } //namespace PySide |