1
0
mirror of https://github.com/clementine-player/Clementine synced 2024-12-18 12:28:31 +01:00

Remove dependency on QtUiTools, remove QtUiTools bindings and port PyQt's pure python .ui file parser to use PythonQt. Change the di.fm script to use uic again.

This commit is contained in:
David Sansome 2011-05-21 19:08:38 +00:00
parent 46a411844a
commit 417bde98a0
28 changed files with 1785 additions and 490 deletions

View File

@ -25,8 +25,6 @@ set(SOURCES
generated_cpp/com_trolltech_qt_network/com_trolltech_qt_network0.cpp
generated_cpp/com_trolltech_qt_network/com_trolltech_qt_network1.cpp
generated_cpp/com_trolltech_qt_network/com_trolltech_qt_network_init.cpp
generated_cpp/com_trolltech_qt_uitools/com_trolltech_qt_uitools0.cpp
generated_cpp/com_trolltech_qt_uitools/com_trolltech_qt_uitools_init.cpp
src/gui/PythonQtScriptingConsole.cpp
src/PythonQtClassInfo.cpp
src/PythonQtClassWrapper.cpp
@ -63,7 +61,6 @@ set(HEADERS
generated_cpp/com_trolltech_qt_gui/com_trolltech_qt_gui9.h
generated_cpp/com_trolltech_qt_network/com_trolltech_qt_network0.h
generated_cpp/com_trolltech_qt_network/com_trolltech_qt_network1.h
generated_cpp/com_trolltech_qt_uitools/com_trolltech_qt_uitools0.h
src/gui/PythonQtScriptingConsole.h
src/PythonQt.h
src/PythonQtSignalReceiver.h

View File

@ -1,332 +0,0 @@
#include "com_trolltech_qt_uitools0.h"
#include <PythonQtConversion.h>
#include <PythonQtMethodInfo.h>
#include <PythonQtSignalReceiver.h>
#include <QVariant>
#include <qaction.h>
#include <qactiongroup.h>
#include <qbytearray.h>
#include <qcoreevent.h>
#include <qdir.h>
#include <qiodevice.h>
#include <qlayout.h>
#include <qlist.h>
#include <qobject.h>
#include <qstringlist.h>
#include <quiloader.h>
#include <qwidget.h>
void PythonQtShell_QUiLoader::childEvent(QChildEvent* arg__1)
{
if (_wrapper) {
PyObject* obj = PyObject_GetAttrString((PyObject*)_wrapper, "childEvent");
PyErr_Clear();
if (obj && !PythonQtSlotFunction_Check(obj)) {
static const char* argumentList[] ={"" , "QChildEvent*"};
static const PythonQtMethodInfo* methodInfo = PythonQtMethodInfo::getCachedMethodInfoFromArgumentList(2, argumentList);
void* args[2] = {NULL, (void*)&arg__1};
PyObject* result = PythonQtSignalTarget::call(obj, methodInfo, args, true);
if (result) { Py_DECREF(result); }
Py_DECREF(obj);
return;
}
}
QUiLoader::childEvent(arg__1);
}
QAction* PythonQtShell_QUiLoader::createAction(QObject* parent, const QString& name)
{
if (_wrapper) {
PyObject* obj = PyObject_GetAttrString((PyObject*)_wrapper, "createAction");
PyErr_Clear();
if (obj && !PythonQtSlotFunction_Check(obj)) {
static const char* argumentList[] ={"QAction*" , "QObject*" , "const QString&"};
static const PythonQtMethodInfo* methodInfo = PythonQtMethodInfo::getCachedMethodInfoFromArgumentList(3, argumentList);
QAction* returnValue;
void* args[3] = {NULL, (void*)&parent, (void*)&name};
PyObject* result = PythonQtSignalTarget::call(obj, methodInfo, args, true);
if (result) {
args[0] = PythonQtConv::ConvertPythonToQt(methodInfo->parameters().at(0), result, false, NULL, &returnValue);
if (args[0]!=&returnValue) {
if (args[0]==NULL) {
PythonQt::priv()->handleVirtualOverloadReturnError("createAction", methodInfo, result);
} else {
returnValue = *((QAction**)args[0]);
}
}
}
if (result) { Py_DECREF(result); }
Py_DECREF(obj);
return returnValue;
}
}
return QUiLoader::createAction(parent, name);
}
QActionGroup* PythonQtShell_QUiLoader::createActionGroup(QObject* parent, const QString& name)
{
if (_wrapper) {
PyObject* obj = PyObject_GetAttrString((PyObject*)_wrapper, "createActionGroup");
PyErr_Clear();
if (obj && !PythonQtSlotFunction_Check(obj)) {
static const char* argumentList[] ={"QActionGroup*" , "QObject*" , "const QString&"};
static const PythonQtMethodInfo* methodInfo = PythonQtMethodInfo::getCachedMethodInfoFromArgumentList(3, argumentList);
QActionGroup* returnValue;
void* args[3] = {NULL, (void*)&parent, (void*)&name};
PyObject* result = PythonQtSignalTarget::call(obj, methodInfo, args, true);
if (result) {
args[0] = PythonQtConv::ConvertPythonToQt(methodInfo->parameters().at(0), result, false, NULL, &returnValue);
if (args[0]!=&returnValue) {
if (args[0]==NULL) {
PythonQt::priv()->handleVirtualOverloadReturnError("createActionGroup", methodInfo, result);
} else {
returnValue = *((QActionGroup**)args[0]);
}
}
}
if (result) { Py_DECREF(result); }
Py_DECREF(obj);
return returnValue;
}
}
return QUiLoader::createActionGroup(parent, name);
}
QLayout* PythonQtShell_QUiLoader::createLayout(const QString& className, QObject* parent, const QString& name)
{
if (_wrapper) {
PyObject* obj = PyObject_GetAttrString((PyObject*)_wrapper, "createLayout");
PyErr_Clear();
if (obj && !PythonQtSlotFunction_Check(obj)) {
static const char* argumentList[] ={"QLayout*" , "const QString&" , "QObject*" , "const QString&"};
static const PythonQtMethodInfo* methodInfo = PythonQtMethodInfo::getCachedMethodInfoFromArgumentList(4, argumentList);
QLayout* returnValue;
void* args[4] = {NULL, (void*)&className, (void*)&parent, (void*)&name};
PyObject* result = PythonQtSignalTarget::call(obj, methodInfo, args, true);
if (result) {
args[0] = PythonQtConv::ConvertPythonToQt(methodInfo->parameters().at(0), result, false, NULL, &returnValue);
if (args[0]!=&returnValue) {
if (args[0]==NULL) {
PythonQt::priv()->handleVirtualOverloadReturnError("createLayout", methodInfo, result);
} else {
returnValue = *((QLayout**)args[0]);
}
}
}
if (result) { Py_DECREF(result); }
Py_DECREF(obj);
return returnValue;
}
}
return QUiLoader::createLayout(className, parent, name);
}
QWidget* PythonQtShell_QUiLoader::createWidget(const QString& className, QWidget* parent, const QString& name)
{
if (_wrapper) {
PyObject* obj = PyObject_GetAttrString((PyObject*)_wrapper, "createWidget");
PyErr_Clear();
if (obj && !PythonQtSlotFunction_Check(obj)) {
static const char* argumentList[] ={"QWidget*" , "const QString&" , "QWidget*" , "const QString&"};
static const PythonQtMethodInfo* methodInfo = PythonQtMethodInfo::getCachedMethodInfoFromArgumentList(4, argumentList);
QWidget* returnValue;
void* args[4] = {NULL, (void*)&className, (void*)&parent, (void*)&name};
PyObject* result = PythonQtSignalTarget::call(obj, methodInfo, args, true);
if (result) {
args[0] = PythonQtConv::ConvertPythonToQt(methodInfo->parameters().at(0), result, false, NULL, &returnValue);
if (args[0]!=&returnValue) {
if (args[0]==NULL) {
PythonQt::priv()->handleVirtualOverloadReturnError("createWidget", methodInfo, result);
} else {
returnValue = *((QWidget**)args[0]);
}
}
}
if (result) { Py_DECREF(result); }
Py_DECREF(obj);
return returnValue;
}
}
return QUiLoader::createWidget(className, parent, name);
}
void PythonQtShell_QUiLoader::customEvent(QEvent* arg__1)
{
if (_wrapper) {
PyObject* obj = PyObject_GetAttrString((PyObject*)_wrapper, "customEvent");
PyErr_Clear();
if (obj && !PythonQtSlotFunction_Check(obj)) {
static const char* argumentList[] ={"" , "QEvent*"};
static const PythonQtMethodInfo* methodInfo = PythonQtMethodInfo::getCachedMethodInfoFromArgumentList(2, argumentList);
void* args[2] = {NULL, (void*)&arg__1};
PyObject* result = PythonQtSignalTarget::call(obj, methodInfo, args, true);
if (result) { Py_DECREF(result); }
Py_DECREF(obj);
return;
}
}
QUiLoader::customEvent(arg__1);
}
bool PythonQtShell_QUiLoader::event(QEvent* arg__1)
{
if (_wrapper) {
PyObject* obj = PyObject_GetAttrString((PyObject*)_wrapper, "event");
PyErr_Clear();
if (obj && !PythonQtSlotFunction_Check(obj)) {
static const char* argumentList[] ={"bool" , "QEvent*"};
static const PythonQtMethodInfo* methodInfo = PythonQtMethodInfo::getCachedMethodInfoFromArgumentList(2, argumentList);
bool returnValue;
void* args[2] = {NULL, (void*)&arg__1};
PyObject* result = PythonQtSignalTarget::call(obj, methodInfo, args, true);
if (result) {
args[0] = PythonQtConv::ConvertPythonToQt(methodInfo->parameters().at(0), result, false, NULL, &returnValue);
if (args[0]!=&returnValue) {
if (args[0]==NULL) {
PythonQt::priv()->handleVirtualOverloadReturnError("event", methodInfo, result);
} else {
returnValue = *((bool*)args[0]);
}
}
}
if (result) { Py_DECREF(result); }
Py_DECREF(obj);
return returnValue;
}
}
return QUiLoader::event(arg__1);
}
bool PythonQtShell_QUiLoader::eventFilter(QObject* arg__1, QEvent* arg__2)
{
if (_wrapper) {
PyObject* obj = PyObject_GetAttrString((PyObject*)_wrapper, "eventFilter");
PyErr_Clear();
if (obj && !PythonQtSlotFunction_Check(obj)) {
static const char* argumentList[] ={"bool" , "QObject*" , "QEvent*"};
static const PythonQtMethodInfo* methodInfo = PythonQtMethodInfo::getCachedMethodInfoFromArgumentList(3, argumentList);
bool returnValue;
void* args[3] = {NULL, (void*)&arg__1, (void*)&arg__2};
PyObject* result = PythonQtSignalTarget::call(obj, methodInfo, args, true);
if (result) {
args[0] = PythonQtConv::ConvertPythonToQt(methodInfo->parameters().at(0), result, false, NULL, &returnValue);
if (args[0]!=&returnValue) {
if (args[0]==NULL) {
PythonQt::priv()->handleVirtualOverloadReturnError("eventFilter", methodInfo, result);
} else {
returnValue = *((bool*)args[0]);
}
}
}
if (result) { Py_DECREF(result); }
Py_DECREF(obj);
return returnValue;
}
}
return QUiLoader::eventFilter(arg__1, arg__2);
}
void PythonQtShell_QUiLoader::timerEvent(QTimerEvent* arg__1)
{
if (_wrapper) {
PyObject* obj = PyObject_GetAttrString((PyObject*)_wrapper, "timerEvent");
PyErr_Clear();
if (obj && !PythonQtSlotFunction_Check(obj)) {
static const char* argumentList[] ={"" , "QTimerEvent*"};
static const PythonQtMethodInfo* methodInfo = PythonQtMethodInfo::getCachedMethodInfoFromArgumentList(2, argumentList);
void* args[2] = {NULL, (void*)&arg__1};
PyObject* result = PythonQtSignalTarget::call(obj, methodInfo, args, true);
if (result) { Py_DECREF(result); }
Py_DECREF(obj);
return;
}
}
QUiLoader::timerEvent(arg__1);
}
QUiLoader* PythonQtWrapper_QUiLoader::new_QUiLoader(QObject* parent)
{
return new PythonQtShell_QUiLoader(parent); }
void PythonQtWrapper_QUiLoader::addPluginPath(QUiLoader* theWrappedObject, const QString& path)
{
( theWrappedObject->addPluginPath(path));
}
QStringList PythonQtWrapper_QUiLoader::availableLayouts(QUiLoader* theWrappedObject) const
{
return ( theWrappedObject->availableLayouts());
}
QStringList PythonQtWrapper_QUiLoader::availableWidgets(QUiLoader* theWrappedObject) const
{
return ( theWrappedObject->availableWidgets());
}
void PythonQtWrapper_QUiLoader::clearPluginPaths(QUiLoader* theWrappedObject)
{
( theWrappedObject->clearPluginPaths());
}
QAction* PythonQtWrapper_QUiLoader::createAction(QUiLoader* theWrappedObject, QObject* parent, const QString& name)
{
return ( ((PythonQtPublicPromoter_QUiLoader*)theWrappedObject)->promoted_createAction(parent, name));
}
QActionGroup* PythonQtWrapper_QUiLoader::createActionGroup(QUiLoader* theWrappedObject, QObject* parent, const QString& name)
{
return ( ((PythonQtPublicPromoter_QUiLoader*)theWrappedObject)->promoted_createActionGroup(parent, name));
}
QLayout* PythonQtWrapper_QUiLoader::createLayout(QUiLoader* theWrappedObject, const QString& className, QObject* parent, const QString& name)
{
return ( ((PythonQtPublicPromoter_QUiLoader*)theWrappedObject)->promoted_createLayout(className, parent, name));
}
QWidget* PythonQtWrapper_QUiLoader::createWidget(QUiLoader* theWrappedObject, const QString& className, QWidget* parent, const QString& name)
{
return ( ((PythonQtPublicPromoter_QUiLoader*)theWrappedObject)->promoted_createWidget(className, parent, name));
}
bool PythonQtWrapper_QUiLoader::isLanguageChangeEnabled(QUiLoader* theWrappedObject) const
{
return ( theWrappedObject->isLanguageChangeEnabled());
}
bool PythonQtWrapper_QUiLoader::isScriptingEnabled(QUiLoader* theWrappedObject) const
{
return ( theWrappedObject->isScriptingEnabled());
}
bool PythonQtWrapper_QUiLoader::isTranslationEnabled(QUiLoader* theWrappedObject) const
{
return ( theWrappedObject->isTranslationEnabled());
}
QWidget* PythonQtWrapper_QUiLoader::load(QUiLoader* theWrappedObject, QIODevice* device, QWidget* parentWidget)
{
return ( theWrappedObject->load(device, parentWidget));
}
QStringList PythonQtWrapper_QUiLoader::pluginPaths(QUiLoader* theWrappedObject) const
{
return ( theWrappedObject->pluginPaths());
}
void PythonQtWrapper_QUiLoader::setLanguageChangeEnabled(QUiLoader* theWrappedObject, bool enabled)
{
( theWrappedObject->setLanguageChangeEnabled(enabled));
}
void PythonQtWrapper_QUiLoader::setScriptingEnabled(QUiLoader* theWrappedObject, bool enabled)
{
( theWrappedObject->setScriptingEnabled(enabled));
}
void PythonQtWrapper_QUiLoader::setTranslationEnabled(QUiLoader* theWrappedObject, bool enabled)
{
( theWrappedObject->setTranslationEnabled(enabled));
}
void PythonQtWrapper_QUiLoader::setWorkingDirectory(QUiLoader* theWrappedObject, const QDir& dir)
{
( theWrappedObject->setWorkingDirectory(dir));
}
QDir PythonQtWrapper_QUiLoader::workingDirectory(QUiLoader* theWrappedObject) const
{
return ( theWrappedObject->workingDirectory());
}

View File

@ -1,71 +0,0 @@
#include <PythonQt.h>
#include <QObject>
#include <QVariant>
#include <qaction.h>
#include <qactiongroup.h>
#include <qbytearray.h>
#include <qcoreevent.h>
#include <qdir.h>
#include <qiodevice.h>
#include <qlayout.h>
#include <qlist.h>
#include <qobject.h>
#include <qstringlist.h>
#include <quiloader.h>
#include <qwidget.h>
class PythonQtShell_QUiLoader : public QUiLoader
{
public:
PythonQtShell_QUiLoader(QObject* parent = 0):QUiLoader(parent),_wrapper(NULL) {};
virtual void childEvent(QChildEvent* arg__1);
virtual QAction* createAction(QObject* parent = 0, const QString& name = QString());
virtual QActionGroup* createActionGroup(QObject* parent = 0, const QString& name = QString());
virtual QLayout* createLayout(const QString& className, QObject* parent = 0, const QString& name = QString());
virtual QWidget* createWidget(const QString& className, QWidget* parent = 0, const QString& name = QString());
virtual void customEvent(QEvent* arg__1);
virtual bool event(QEvent* arg__1);
virtual bool eventFilter(QObject* arg__1, QEvent* arg__2);
virtual void timerEvent(QTimerEvent* arg__1);
PythonQtInstanceWrapper* _wrapper;
};
class PythonQtPublicPromoter_QUiLoader : public QUiLoader
{ public:
inline QAction* promoted_createAction(QObject* parent = 0, const QString& name = QString()) { return QUiLoader::createAction(parent, name); }
inline QActionGroup* promoted_createActionGroup(QObject* parent = 0, const QString& name = QString()) { return QUiLoader::createActionGroup(parent, name); }
inline QLayout* promoted_createLayout(const QString& className, QObject* parent = 0, const QString& name = QString()) { return QUiLoader::createLayout(className, parent, name); }
inline QWidget* promoted_createWidget(const QString& className, QWidget* parent = 0, const QString& name = QString()) { return QUiLoader::createWidget(className, parent, name); }
};
class PythonQtWrapper_QUiLoader : public QObject
{ Q_OBJECT
public:
public slots:
QUiLoader* new_QUiLoader(QObject* parent = 0);
void delete_QUiLoader(QUiLoader* obj) { delete obj; }
void addPluginPath(QUiLoader* theWrappedObject, const QString& path);
QStringList availableLayouts(QUiLoader* theWrappedObject) const;
QStringList availableWidgets(QUiLoader* theWrappedObject) const;
void clearPluginPaths(QUiLoader* theWrappedObject);
QAction* createAction(QUiLoader* theWrappedObject, QObject* parent = 0, const QString& name = QString());
QActionGroup* createActionGroup(QUiLoader* theWrappedObject, QObject* parent = 0, const QString& name = QString());
QLayout* createLayout(QUiLoader* theWrappedObject, const QString& className, QObject* parent = 0, const QString& name = QString());
QWidget* createWidget(QUiLoader* theWrappedObject, const QString& className, QWidget* parent = 0, const QString& name = QString());
bool isLanguageChangeEnabled(QUiLoader* theWrappedObject) const;
bool isScriptingEnabled(QUiLoader* theWrappedObject) const;
bool isTranslationEnabled(QUiLoader* theWrappedObject) const;
QWidget* load(QUiLoader* theWrappedObject, QIODevice* device, QWidget* parentWidget = 0);
QStringList pluginPaths(QUiLoader* theWrappedObject) const;
void setLanguageChangeEnabled(QUiLoader* theWrappedObject, bool enabled);
void setScriptingEnabled(QUiLoader* theWrappedObject, bool enabled);
void setTranslationEnabled(QUiLoader* theWrappedObject, bool enabled);
void setWorkingDirectory(QUiLoader* theWrappedObject, const QDir& dir);
QDir workingDirectory(QUiLoader* theWrappedObject) const;
};

View File

@ -1,9 +0,0 @@
#include <PythonQt.h>
#include "com_trolltech_qt_uitools0.h"
#include "com_trolltech_qt_uitools_init.h"
void PythonQt_init_QtUiTools(PyObject* module) {
PythonQt::priv()->registerClass(&QUiLoader::staticMetaObject, "QtUiTools", PythonQtCreateObject<PythonQtWrapper_QUiLoader>, PythonQtSetInstanceWrapperOnShell<PythonQtShell_QUiLoader>, module, 0);
}

View File

@ -1,8 +0,0 @@
#ifndef COM_TROLLTECH_QT_UITOOLS_INIT_H
#define COM_TROLLTECH_QT_UITOOLS_INIT_H
#include "PythonQtSystem.h"
PYTHONQT_EXPORT void PythonQt_init_QtUiTools(PyObject* module);
#endif // COM_TROLLTECH_QT_UITOOLS_INIT_H

View File

@ -13,7 +13,7 @@ if (UNIX AND NOT APPLE)
set(LINUX 1)
endif (UNIX AND NOT APPLE)
find_package(Qt4 4.5.0 REQUIRED QtCore QtGui QtOpenGL QtSql QtNetwork QtXml QtUiTools)
find_package(Qt4 4.5.0 REQUIRED QtCore QtGui QtOpenGL QtSql QtNetwork QtXml)
if (LINUX)
option(ENABLE_DBUS "Enable D-Bus, MPRIS and native notifications. Required for DeviceKit and Wii remote support" ON)
if(ENABLE_DBUS)

View File

@ -297,7 +297,6 @@
<file>schema/schema-24.sql</file>
<file>schema/schema-25.sql</file>
<file>schema/schema-26.sql</file>
<file>pythonstartup.py</file>
<file>schema/schema-27.sql</file>
<file>schema/schema-28.sql</file>
<file>icons/22x22/network-server.png</file>
@ -325,5 +324,21 @@
<file>schema/schema-34.sql</file>
<file>icons/22x22/audio-x-generic.png</file>
<file>icons/22x22/audio-x-disabled.png</file>
<file>pythonlibs/uic/driver.py</file>
<file>pythonlibs/uic/exceptions.py</file>
<file>pythonlibs/uic/icon_cache.py</file>
<file>pythonlibs/uic/__init__.py</file>
<file>pythonlibs/uic/Loader/__init__.py</file>
<file>pythonlibs/uic/Loader/loader.py</file>
<file>pythonlibs/uic/Loader/qobjectcreator.py</file>
<file>pythonlibs/uic/objcreator.py</file>
<file>pythonlibs/uic/port_v2/ascii_upper.py</file>
<file>pythonlibs/uic/port_v2/encode_utf8.py</file>
<file>pythonlibs/uic/port_v2/__init__.py</file>
<file>pythonlibs/uic/port_v2/invoke.py</file>
<file>pythonlibs/uic/port_v2/load_plugin.py</file>
<file>pythonlibs/uic/port_v2/string_io.py</file>
<file>pythonlibs/uic/properties.py</file>
<file>pythonlibs/uic/uiparser.py</file>
</qresource>
</RCC>

View File

View File

@ -0,0 +1,21 @@
from PythonQt import QtGui, QtCore
from uic.uiparser import UIParser
from uic.Loader.qobjectcreator import LoaderCreatorPolicy
class DynamicUILoader(UIParser):
def __init__(self):
UIParser.__init__(self, QtCore, QtGui, LoaderCreatorPolicy())
def createToplevelWidget(self, classname, widgetname):
if self.toplevelInst is not None:
if not isinstance(self.toplevelInst, self.factory.findQObjectType(classname)):
raise TypeError(("Wrong base class of toplevel widget",
(type(self.toplevelInst), classname)))
return self.toplevelInst
else:
return self.factory.createQObject(classname, widgetname, ())
def loadUi(self, filename, toplevelInst = None):
self.toplevelInst = toplevelInst
return self.parse(filename)

View File

@ -0,0 +1,83 @@
import sys
try:
set()
except NameError:
from sets import Set as set
from PythonQt import QtGui
class _QtGuiWrapper(object):
def search(cls):
return getattr(QtGui, cls, None)
search = staticmethod(search)
class _ModuleWrapper(object):
def __init__(self, moduleName, classes):
self._moduleName = moduleName
self._module = None
self._classes = set(classes)
def search(self, cls):
if cls in self._classes:
if self._module is None:
self._module = __import__(self._moduleName, {}, {}, self._classes)
# Allow for namespaces.
obj = self._module
for attr in cls.split('.'):
obj = getattr(obj, attr)
return obj
else:
return None
class _CustomWidgetLoader(object):
def __init__(self):
# should it stay this way?
sys.path.append(".")
self._widgets = {}
self._modules = {}
def addCustomWidget(self, widgetClass, baseClass, module):
assert widgetClass not in self._widgets
self._widgets[widgetClass] = module
def search(self, cls):
try:
module = self._widgets[cls]
if module not in self._modules:
self._modules[module] = __import__(module, {}, {}, (cls,))
return getattr(self._modules[module], cls)
except KeyError:
pass
return None
class LoaderCreatorPolicy(object):
def createQtGuiWrapper(self):
return _QtGuiWrapper
def createModuleWrapper(self, moduleName, classes):
return _ModuleWrapper(moduleName, classes)
def createCustomWidgetLoader(self):
return _CustomWidgetLoader()
def instantiate(self, clsObject, objectName, ctor_args, is_attribute=True):
# Create a new type so setattr() can work
new_type = type("__WidgetWrapper_" + clsObject.__name__, (clsObject,), {})
return new_type(*ctor_args)
def invoke(self, rname, method, args):
return method(*args)
def getSlot(self, object, slotname):
# Rename slots that correspond to Python keyword arguments.
if slotname == 'raise':
slotname += '_'
return getattr(object, slotname)

View File

@ -0,0 +1,21 @@
__all__ = ("loadUi")
def loadUi(uifile, baseinstance=None):
"""loadUi(uifile, baseinstance=None) -> widget
Load a Qt Designer .ui file and return an instance of the user interface.
uifile is a file name or file-like object containing the .ui file.
baseinstance is an optional instance of the Qt base class. If specified
then the user interface is created in it. Otherwise a new instance of the
base class is automatically created.
"""
from uic.Loader.loader import DynamicUILoader
return DynamicUILoader().loadUi(uifile, baseinstance)
# The list of directories that are searched for widget plugins.
from uic.objcreator import widgetPluginPath

View File

@ -0,0 +1,91 @@
import sys
import logging
from uic import compileUi, loadUi
class Driver(object):
""" This encapsulates access to the pyuic functionality so that it can be
called by code that is Python v2/v3 specific.
"""
LOGGER_NAME = 'uic'
def __init__(self, opts, ui_file):
""" Initialise the object. opts is the parsed options. ui_file is the
name of the .ui file.
"""
if opts.debug:
logger = logging.getLogger(self.LOGGER_NAME)
handler = logging.StreamHandler()
handler.setFormatter(logging.Formatter("%(name)s: %(message)s"))
logger.addHandler(handler)
logger.setLevel(logging.DEBUG)
self._opts = opts
self._ui_file = ui_file
def invoke(self):
""" Invoke the action as specified by the parsed options. Returns 0 if
there was no error.
"""
if self._opts.preview:
return self._preview()
self._generate()
return 0
def _preview(self):
""" Preview the .ui file. Return the exit status to be passed back to
the parent process.
"""
from PythonQt import QtGui
app = QtGui.QApplication([self._ui_file])
widget = loadUi(self._ui_file)
widget.show()
return app.exec_()
def _generate(self):
""" Generate the Python code. """
if self._opts.output == "-":
pyfile = sys.stdout
else:
pyfile = open(self._opts.output, 'wt')
compileUi(self._ui_file, pyfile, self._opts.execute, self._opts.indent,
self._opts.pyqt3_wrapper)
def on_IOError(self, e):
""" Handle an IOError exception. """
sys.stderr.write("Error: %s: \"%s\"\n" % (e.strerror, e.filename))
def on_SyntaxError(self, e):
""" Handle a SyntaxError exception. """
sys.stderr.write("Error in input file: %s\n" % e)
def on_NoSuchWidgetError(self, e):
""" Handle a NoSuchWidgetError exception. """
if e.args[0].startswith("Q3"):
sys.stderr.write("Error: Q3Support widgets are not supported by PythonQt.\n")
else:
sys.stderr.write(str(e) + "\n")
def on_Exception(self, e):
""" Handle a generic exception. """
if logging.getLogger(self.LOGGER_NAME).level == logging.DEBUG:
import traceback
traceback.print_exception(*sys.exc_info())
else:
sys.stderr.write("An unexpected error occurred")

View File

@ -0,0 +1,9 @@
class NoSuchWidgetError(Exception):
def __str__(self):
return "Unknown Qt widget: %s" % (self.args[0],)
class UnsupportedPropertyError(Exception):
pass
class WidgetPluginError(Exception):
pass

View File

@ -0,0 +1,111 @@
"""Maintain a cache of icons.
If an icon is used more than once by a GUI then ensure that only one copy is
created.
"""
class IconCache(object):
"""A cache of icons."""
def __init__(self, object_factory, qtgui_module):
"""Initialise the cache."""
self._object_factory = object_factory
self._qtgui_module = qtgui_module
self._cache = []
def get_icon(self, iconset):
"""Return an icon described by the given iconset tag."""
iset = _IconSet(iconset)
try:
idx = self._cache.index(iset)
except ValueError:
idx = -1
if idx >= 0:
# Return the icon from the cache.
iset = self._cache[idx]
else:
# Follow uic's naming convention.
name = 'icon'
idx = len(self._cache)
if idx > 0:
name += str(idx)
icon = self._object_factory.createQObject("QIcon", name, (),
is_attribute=False)
iset.set_icon(icon, self._qtgui_module)
self._cache.append(iset)
return iset.icon
class _IconSet(object):
"""An icon set, ie. the mode and state and the pixmap used for each."""
def __init__(self, iconset):
"""Initialise the icon set from an XML tag."""
# Set the pre-Qt v4.4 fallback (ie. with no roles).
self._fallback = iconset.text.replace("\\", "\\\\")
self._use_fallback = True
# Parse the icon set.
self._roles = {}
for i in iconset:
file_name = i.text
if file_name is not None:
file_name = file_name.replace("\\", "\\\\")
self._roles[i.tag] = file_name
self._use_fallback = False
# There is no real icon yet.
self.icon = None
def set_icon(self, icon, qtgui_module):
"""Save the icon and set its attributes."""
if self._use_fallback:
icon.addFile(self._fallback)
else:
for role, pixmap in self._roles.items():
if role.endswith("off"):
mode = role[:-3]
state = qtgui_module.QIcon.Off
elif role.endswith("on"):
mode = role[:-2]
state = qtgui_module.QIcon.On
else:
continue
mode = getattr(qtgui_module.QIcon, mode.title())
if pixmap:
icon.addPixmap(qtgui_module.QPixmap(pixmap), mode, state)
else:
icon.addPixmap(qtgui_module.QPixmap(), mode, state)
self.icon = icon
def __eq__(self, other):
"""Compare two icon sets for equality."""
if not isinstance(other, type(self)):
return NotImplemented
if self._use_fallback:
if other._use_fallback:
return self._fallback == other._fallback
return False
if other._use_fallback:
return False
return self._roles == other._roles

View File

@ -0,0 +1,90 @@
import sys
import os.path
from uic.exceptions import NoSuchWidgetError, WidgetPluginError
if sys.hexversion >= 0x03000000:
from uic.port_v3.load_plugin import load_plugin
else:
from uic.port_v2.load_plugin import load_plugin
# The list of directories that are searched for widget plugins. This is
# exposed as part of the API.
widgetPluginPath = [os.path.join(os.path.dirname(__file__), 'widget-plugins')]
MATCH = True
NO_MATCH = False
MODULE = 0
CW_FILTER = 1
class QObjectCreator(object):
def __init__(self, creatorPolicy):
self._cpolicy = creatorPolicy
self._cwFilters = []
self._modules = [self._cpolicy.createQtGuiWrapper()]
# Get the optional plugins.
for plugindir in widgetPluginPath:
try:
plugins = os.listdir(plugindir)
except:
plugins = []
for filename in plugins:
if not filename.endswith('.py'):
continue
filename = os.path.join(plugindir, filename)
plugin_globals = {
"MODULE": MODULE,
"CW_FILTER": CW_FILTER,
"MATCH": MATCH,
"NO_MATCH": NO_MATCH}
plugin_locals = {}
if load_plugin(open(filename), plugin_globals, plugin_locals):
pluginType = plugin_locals["pluginType"]
if pluginType == MODULE:
modinfo = plugin_locals["moduleInformation"]()
self._modules.append(self._cpolicy.createModuleWrapper(*modinfo))
elif pluginType == CW_FILTER:
self._cwFilters.append(plugin_locals["getFilter"]())
else:
raise WidgetPluginError("Unknown plugin type of %s" % filename)
self._customWidgets = self._cpolicy.createCustomWidgetLoader()
self._modules.append(self._customWidgets)
def createQObject(self, classname, *args, **kwargs):
classType = self.findQObjectType(classname)
if classType:
return self._cpolicy.instantiate(classType, *args, **kwargs)
raise NoSuchWidgetError(classname)
def invoke(self, rname, method, args=()):
return self._cpolicy.invoke(rname, method, args)
def findQObjectType(self, classname):
for module in self._modules:
w = module.search(classname)
if w is not None:
return w
return None
def getSlot(self, obj, slotname):
return self._cpolicy.getSlot(obj, slotname)
def addCustomWidget(self, widgetClass, baseClass, module):
for cwFilter in self._cwFilters:
match, result = cwFilter(widgetClass, baseClass, module)
if match:
widgetClass, baseClass, module = result
break
self._customWidgets.addCustomWidget(widgetClass, baseClass, module)

View File

View File

@ -0,0 +1,11 @@
import string
# A translation table for converting ASCII lower case to upper case.
_ascii_trans_table = string.maketrans(string.ascii_lowercase,
string.ascii_uppercase)
# Convert a string to ASCII upper case irrespective of the current locale.
def ascii_upper(s):
return s.translate(_ascii_trans_table)

View File

@ -0,0 +1,2 @@
def encode_utf8(s):
return s.encode('UTF-8')

View File

@ -0,0 +1,26 @@
from uic.exceptions import NoSuchWidgetError
def invoke(driver):
""" Invoke the given command line driver. Return the exit status to be
passed back to the parent process.
"""
exit_status = 1
try:
exit_status = driver.invoke()
except IOError, e:
driver.on_IOError(e)
except SyntaxError, e:
driver.on_SyntaxError(e)
except NoSuchWidgetError, e:
driver.on_NoSuchWidgetError(e)
except Exception, e:
driver.on_Exception(e)
return exit_status

View File

@ -0,0 +1,17 @@
from uic.exceptions import WidgetPluginError
def load_plugin(plugin, plugin_globals, plugin_locals):
""" Load the given plugin (which is an open file). Return True if the
plugin was loaded, or False if it wanted to be ignored. Raise an exception
if there was an error.
"""
try:
exec(plugin.read(), plugin_globals, plugin_locals)
except ImportError:
return False
except Exception, e:
raise WidgetPluginError("%s: %s" % (e.__class__, str(e)))
return True

View File

@ -0,0 +1,5 @@
# Import the StringIO object.
try:
from cStringIO import StringIO
except ImportError:
from StringIO import StringIO

View File

@ -0,0 +1,442 @@
import logging
import sys
from uic.exceptions import UnsupportedPropertyError
from uic.icon_cache import IconCache
if sys.hexversion >= 0x03000000:
from uic.port_v3.ascii_upper import ascii_upper
else:
from uic.port_v2.ascii_upper import ascii_upper
logger = logging.getLogger(__name__)
DEBUG = logger.debug
QtCore = None
QtGui = None
def int_list(prop):
return [int(child.text) for child in prop]
def float_list(prop):
return [float(child.text) for child in prop]
bool_ = lambda v: v == "true"
def needsWidget(func):
func.needsWidget = True
return func
class Properties(object):
def __init__(self, factory, QtCore_mod, QtGui_mod):
global QtGui, QtCore
QtGui = QtGui_mod
QtCore = QtCore_mod
self.factory = factory
self.reset()
def reset(self):
self.buddies = []
self.delayed_props = []
self.icon_cache = IconCache(self.factory, QtGui)
def _pyEnumMember(self, cpp_name):
try:
prefix, membername = cpp_name.split("::")
DEBUG(membername)
if prefix == "Qt":
return getattr(QtCore.Qt, membername)
else:
return getattr(getattr(QtGui, prefix), membername)
except ValueError:
pass
try:
return getattr(QtCore.Qt, cpp_name)
except AttributeError:
# There seems to be a bug where this can succeed when it shouldn't.
# If so it will be picked up when the generated code is run.
return getattr(getattr(QtGui, self.wclass), cpp_name)
def _set(self, prop):
expr = [self._pyEnumMember(v) for v in prop.text.split('|')]
value = expr[0]
for v in expr[1:]:
value |= v
return value
def _enum(self, prop):
return self._pyEnumMember(prop.text)
def _number(self, prop):
return int(prop.text)
_uInt = _longLong = _uLongLong = _number
def _double(self, prop):
return float(prop.text)
def _bool(self, prop):
return prop.text == 'true'
def _stringlist(self, prop):
return [self._string(p, notr='true') for p in prop]
def _string(self, prop, notr=None):
if prop.get('notr', notr) == 'true':
return self._cstring(prop)
if prop.text is None:
return ""
return QtGui.QApplication.translate(self.uiname, prop.text, None,
QtGui.QApplication.UnicodeUTF8)
_char = _string
def _cstring(self, prop):
return str(prop.text)
def _color(self, prop):
args = int_list(prop)
# Handle the optional alpha component.
alpha = int(prop.get("alpha", "255"))
if alpha != 255:
args.append(alpha)
return QtGui.QColor(*args)
def _point(self, prop):
return QtCore.QPoint(*int_list(prop))
def _pointf(self, prop):
return QtCore.QPointF(*float_list(prop))
def _rect(self, prop):
return QtCore.QRect(*int_list(prop))
def _rectf(self, prop):
return QtCore.QRectF(*float_list(prop))
def _size(self, prop):
return QtCore.QSize(*int_list(prop))
def _sizef(self, prop):
return QtCore.QSizeF(*float_list(prop))
def _pixmap(self, prop):
if prop.text:
return QtGui.QPixmap(prop.text.replace("\\", "\\\\"))
# Don't bother to set the property if the pixmap is empty.
return None
def _iconset(self, prop):
return self.icon_cache.get_icon(prop)
def _url(self, prop):
return QtCore.QUrl(prop[0].text)
def _locale(self, prop):
lang = getattr(QtCore.QLocale, prop.attrib['language'])
country = getattr(QtCore.QLocale, prop.attrib['country'])
return QtCore.QLocale(lang, country)
def _cursor(self, prop):
return QtGui.QCursor(QtCore.Qt.CursorShape(int(prop.text)))
def _date(self, prop):
return QtCore.QDate(*int_list(prop))
def _datetime(self, prop):
args = int_list(prop)
return QtCore.QDateTime(QtCore.QDate(*args[-3:]), QtCore.QTime(*args[:-3]))
def _time(self, prop):
return QtCore.QTime(*int_list(prop))
def _gradient(self, prop):
name = 'gradient'
# Create the specific gradient.
gtype = prop.get('type', '')
if gtype == 'LinearGradient':
startx = float(prop.get('startx'))
starty = float(prop.get('starty'))
endx = float(prop.get('endx'))
endy = float(prop.get('endy'))
gradient = self.factory.createQObject('QLinearGradient', name,
(startx, starty, endx, endy), is_attribute=False)
elif gtype == 'ConicalGradient':
centralx = float(prop.get('centralx'))
centraly = float(prop.get('centraly'))
angle = float(prop.get('angle'))
gradient = self.factory.createQObject('QConicalGradient', name,
(centralx, centraly, angle), is_attribute=False)
elif gtype == 'RadialGradient':
centralx = float(prop.get('centralx'))
centraly = float(prop.get('centraly'))
radius = float(prop.get('radius'))
focalx = float(prop.get('focalx'))
focaly = float(prop.get('focaly'))
gradient = self.factory.createQObject('QRadialGradient', name,
(centralx, centraly, radius, focalx, focaly),
is_attribute=False)
else:
raise UnsupportedPropertyError(prop.tag)
# Set the common values.
spread = prop.get('spread')
if spread:
gradient.setSpread(getattr(QtGui.QGradient, spread))
cmode = prop.get('coordinatemode')
if cmode:
gradient.setCoordinateMode(getattr(QtGui.QGradient, cmode))
# Get the gradient stops.
for gstop in prop:
if gstop.tag != 'gradientstop':
raise UnsupportedPropertyError(gstop.tag)
position = float(gstop.get('position'))
color = self._color(gstop[0])
gradient.setColorAt(position, color)
return name
def _palette(self, prop):
palette = self.factory.createQObject("QPalette", "palette", (),
is_attribute=False)
for palette_elem in prop:
sub_palette = getattr(QtGui.QPalette, palette_elem.tag.title())
for role, color in enumerate(palette_elem):
if color.tag == 'color':
# Handle simple colour descriptions where the role is
# implied by the colour's position.
palette.setColor(sub_palette,
QtGui.QPalette.ColorRole(role), self._color(color))
elif color.tag == 'colorrole':
role = getattr(QtGui.QPalette, color.get('role'))
brushstyle = color[0].get('brushstyle')
if brushstyle in ('LinearGradientPattern', 'ConicalGradientPattern', 'RadialGradientPattern'):
gradient = self._gradient(color[0][0])
brush = self.factory.createQObject("QBrush", "brush",
(gradient, ), is_attribute=False)
else:
color = self._color(color[0][0])
brush = self.factory.createQObject("QBrush", "brush",
(color, ), is_attribute=False)
brushstyle = getattr(QtCore.Qt, brushstyle)
brush.setStyle(brushstyle)
palette.setBrush(sub_palette, role, brush)
else:
raise UnsupportedPropertyError(color.tag)
return palette
#@needsWidget
def _sizepolicy(self, prop, widget):
values = [int(child.text) for child in prop]
if len(values) == 2:
# Qt v4.3.0 and later.
horstretch, verstretch = values
hsizetype = getattr(QtGui.QSizePolicy, prop.get('hsizetype'))
vsizetype = getattr(QtGui.QSizePolicy, prop.get('vsizetype'))
else:
hsizetype, vsizetype, horstretch, verstretch = values
hsizetype = QtGui.QSizePolicy.Policy(hsizetype)
vsizetype = QtGui.QSizePolicy.Policy(vsizetype)
sizePolicy = self.factory.createQObject("QSizePolicy", "sizePolicy",
(hsizetype, vsizetype), is_attribute=False)
sizePolicy.setHorizontalStretch(horstretch)
sizePolicy.setVerticalStretch(verstretch)
sizePolicy.setHeightForWidth(widget.sizePolicy.hasHeightForWidth())
return sizePolicy
_sizepolicy = needsWidget(_sizepolicy)
# font needs special handling/conversion of all child elements.
_font_attributes = (("Family", str),
("PointSize", int),
("Weight", int),
("Italic", bool_),
("Underline", bool_),
("StrikeOut", bool_),
("Bold", bool_))
def _font(self, prop):
newfont = self.factory.createQObject("QFont", "font", (),
is_attribute = False)
for attr, converter in self._font_attributes:
v = prop.findtext("./%s" % (attr.lower(),))
if v is None:
continue
getattr(newfont, "set%s" % (attr,))(converter(v))
return newfont
def _cursorShape(self, prop):
return getattr(QtCore.Qt, prop.text)
def convert(self, prop, widget=None):
try:
func = getattr(self, "_" + prop[0].tag)
except AttributeError:
raise UnsupportedPropertyError(prop[0].tag)
else:
args = {}
if getattr(func, "needsWidget", False):
assert widget is not None
args["widget"] = widget
return func(prop[0], **args)
def _getChild(self, elem_tag, elem, name, default=None):
for prop in elem.findall(elem_tag):
if prop.attrib["name"] == name:
return self.convert(prop)
else:
return default
def getProperty(self, elem, name, default=None):
return self._getChild("property", elem, name, default)
def getAttribute(self, elem, name, default=None):
return self._getChild("attribute", elem, name, default)
def setProperties(self, widget, elem):
try:
self.wclass = elem.attrib["class"]
except KeyError:
pass
for prop in elem.findall("property"):
prop_name = prop.attrib["name"]
DEBUG("setting property %s" % (prop_name,))
try:
stdset = bool(int(prop.attrib["stdset"]))
except KeyError:
stdset = True
if not stdset:
self._setViaSetProperty(widget, prop)
elif hasattr(self, prop_name):
getattr(self, prop_name)(widget, prop)
else:
prop_value = self.convert(prop, widget)
if prop_value is not None:
getattr(widget, "set%s%s" % (ascii_upper(prop_name[0]), prop_name[1:]))(prop_value)
# SPECIAL PROPERTIES
# If a property has a well-known value type but needs special,
# context-dependent handling, the default behaviour can be overridden here.
# Delayed properties will be set after the whole widget tree has been
# populated.
def _delay(self, widget, prop):
prop_value = self.convert(prop)
if prop_value is not None:
prop_name = prop.attrib["name"]
self.delayed_props.append((
getattr(widget, "set%s%s" % (ascii_upper(prop_name[0]), prop_name[1:])),
prop_value))
# These properties will be set with a widget.setProperty call rather than
# calling the set<property> function.
def _setViaSetProperty(self, widget, prop):
prop_value = self.convert(prop)
if prop_value is not None:
widget.setProperty(prop.attrib["name"], prop_value)
# Ignore the property.
def _ignore(self, widget, prop):
pass
# Define properties that use the canned handlers.
currentIndex = _delay
currentRow = _delay
showDropIndicator = _setViaSetProperty
intValue = _setViaSetProperty
value = _setViaSetProperty
objectName = _ignore
leftMargin = _ignore
topMargin = _ignore
rightMargin = _ignore
bottomMargin = _ignore
horizontalSpacing = _ignore
verticalSpacing = _ignore
# buddy setting has to be done after the whole widget tree has been
# populated. We can't use delay here because we cannot get the actual
# buddy yet.
def buddy(self, widget, prop):
buddy_name = prop[0].text
if buddy_name:
self.buddies.append((widget, buddy_name))
# geometry is handled specially if set on the toplevel widget.
def geometry(self, widget, prop):
if widget.objectName == self.uiname:
geom = int_list(prop[0])
widget.resize(geom[2], geom[3])
else:
widget.setGeometry(self._rect(prop[0]))
def orientation(self, widget, prop):
# If the class is a QFrame, it's a line.
if widget.className() == "QFrame":
widget.setFrameShape(
{"Qt::Horizontal": QtGui.QFrame.HLine,
"Qt::Vertical" : QtGui.QFrame.VLine}[prop[0].text])
# In Qt Designer, lines appear to be sunken, QFormBuilder loads
# them as such, uic generates plain lines. We stick to the look in
# Qt Designer.
widget.setFrameShadow(QtGui.QFrame.Sunken)
else:
widget.setOrientation(self._enum(prop[0]))
# The isWrapping attribute of QListView is named inconsistently, it should
# be wrapping.
def isWrapping(self, widget, prop):
widget.setWrapping(self.convert(prop))
# This is a pseudo-property injected to deal with setContentsMargin()
# introduced in Qt v4.3.
def pyuicContentsMargins(self, widget, prop):
widget.setContentsMargins(*int_list(prop))
# This is a pseudo-property injected to deal with setHorizontalSpacing()
# and setVerticalSpacing() introduced in Qt v4.3.
def pyuicSpacing(self, widget, prop):
horiz, vert = int_list(prop)
if horiz == vert:
widget.setSpacing(horiz)
else:
if horiz >= 0:
widget.setHorizontalSpacing(horiz)
if vert >= 0:
widget.setVerticalSpacing(vert)

View File

@ -0,0 +1,819 @@
import sys
import logging
import os.path
import re
try:
from xml.etree.ElementTree import parse, SubElement
except ImportError:
try:
from ElementTree import parse, SubElement
except ImportError:
from elementtree.ElementTree import parse, SubElement
from uic.exceptions import NoSuchWidgetError
from uic.objcreator import QObjectCreator
from uic.properties import Properties
logger = logging.getLogger(__name__)
DEBUG = logger.debug
if sys.version_info < (2,4,0):
def reversed(seq):
for i in xrange(len(seq)-1, -1, -1):
yield seq[i]
QtCore = None
QtGui = None
def gridPosition(elem):
"""gridPosition(elem) -> tuple
Return the 4-tuple of (row, column, rowspan, colspan)
for a widget element, or an empty tuple.
"""
try:
return (int(elem.attrib["row"]),
int(elem.attrib["column"]),
int(elem.attrib.get("rowspan", 1)),
int(elem.attrib.get("colspan", 1)))
except KeyError:
return ()
class WidgetStack(list):
topwidget = None
def push(self, item):
DEBUG("push %s %s" % (item.className(),
item.objectName))
self.append(item)
if item.inherits("QWidget"):
self.topwidget = item
def popLayout(self):
layout = list.pop(self)
DEBUG("pop layout %s %s" % (layout.className(),
layout.objectName))
return layout
def popWidget(self):
widget = list.pop(self)
DEBUG("pop widget %s %s" % (widget.className(),
widget.objectName))
for item in reversed(self):
if item.inherits("QWidget"):
self.topwidget = item
break
else:
self.topwidget = None
DEBUG("new topwidget %s" % (self.topwidget,))
return widget
def peek(self):
return self[-1]
def topIsLayout(self):
return self[-1].inherits("QLayout")
class UIParser(object):
def __init__(self, QtCoreModule, QtGuiModule, creatorPolicy):
self.factory = QObjectCreator(creatorPolicy)
self.wprops = Properties(self.factory, QtCoreModule, QtGuiModule)
global QtCore, QtGui
QtCore = QtCoreModule
QtGui = QtGuiModule
self.reset()
def uniqueName(self, name):
"""UIParser.uniqueName(string) -> string
Create a unique name from a string.
>>> p = UIParser(QtCore, QtGui)
>>> p.uniqueName("foo")
'foo'
>>> p.uniqueName("foo")
'foo1'
"""
try:
suffix = self.name_suffixes[name]
except KeyError:
self.name_suffixes[name] = 0
return name
suffix += 1
self.name_suffixes[name] = suffix
return "%s%i" % (name, suffix)
def reset(self):
try: self.wprops.reset()
except AttributeError: pass
self.toplevelWidget = None
self.stack = WidgetStack()
self.name_suffixes = {}
self.defaults = {"spacing": 6, "margin": 0}
self.actions = []
self.currentActionGroup = None
self.resources = []
self.button_groups = []
self.item_nr = 0
def setupObject(self, clsname, parent, branch, is_attribute = True):
name = self.uniqueName(branch.attrib.get("name") or clsname[1:].lower())
if parent is None:
args = ()
else:
args = (parent, )
obj = self.factory.createQObject(clsname, name, args, is_attribute)
self.wprops.setProperties(obj, branch)
obj.setObjectName(name)
if is_attribute:
setattr(self.toplevelWidget, name, obj)
return obj
def createWidget(self, elem):
def widgetClass(elem):
cls = elem.attrib["class"].replace('::', '.')
if cls == "Line":
return "QFrame"
else:
return cls
self.column_counter = 0
self.row_counter = 0
self.item_nr = 0
self.itemstack = []
self.sorting_enabled = None
parent = self.stack.topwidget
for class_name in ["QToolBox", "QTabWidget", "QStackedWidget",
"QDockWidget", "QWizard"]:
if parent.inherits(class_name):
parent = None
break
self.stack.push(self.setupObject(widgetClass(elem), parent, elem))
if self.stack.topwidget.inherits("QTableWidget"):
self.stack.topwidget.setColumnCount(len(elem.findall("column")))
self.stack.topwidget.setRowCount(len(elem.findall("row")))
self.traverseWidgetTree(elem)
widget = self.stack.popWidget()
if widget.inherits("QTreeView"):
self.handleHeaderView(elem, "header", widget.header())
elif widget.inherits("QTableView"):
self.handleHeaderView(elem, "horizontalHeader",
widget.horizontalHeader())
self.handleHeaderView(elem, "verticalHeader",
widget.verticalHeader())
elif widget.inherits("QAbstractButton"):
bg_i18n = self.wprops.getAttribute(elem, "buttonGroup")
if bg_i18n is not None:
bg_name = str(bg_i18n)
for bg in self.button_groups:
if bg.objectName == bg_name:
break
else:
bg = self.factory.createQObject("QButtonGroup", bg_name,
(self.toplevelWidget, ))
bg.setObjectName(bg_name)
self.button_groups.append(bg)
bg.addButton(widget)
if self.sorting_enabled is not None:
widget.setSortingEnabled(self.sorting_enabled)
self.sorting_enabled = None
if self.stack.topIsLayout():
lay = self.stack.peek()
gp = elem.attrib["grid-position"]
if lay.inherits("QFormLayout"):
if gp[1]:
role = QtGui.QFormLayout.FieldRole
else:
role = QtGui.QFormLayout.LabelRole
lay.setWidget(gp[0], role, widget)
else:
lay.addWidget(widget, *gp)
topwidget = self.stack.topwidget
if topwidget.inherits("QToolBox"):
icon = self.wprops.getAttribute(elem, "icon")
if icon is not None:
topwidget.addItem(widget, icon, self.wprops.getAttribute(elem, "label"))
else:
topwidget.addItem(widget, self.wprops.getAttribute(elem, "label"))
tooltip = self.wprops.getAttribute(elem, "toolTip")
if tooltip is not None:
topwidget.setItemToolTip(topwidget.indexOf(widget), tooltip)
elif topwidget.inherits("QTabWidget"):
icon = self.wprops.getAttribute(elem, "icon")
if icon is not None:
topwidget.addTab(widget, icon, self.wprops.getAttribute(elem, "title"))
else:
topwidget.addTab(widget, self.wprops.getAttribute(elem, "title"))
tooltip = self.wprops.getAttribute(elem, "toolTip")
if tooltip is not None:
topwidget.setTabToolTip(topwidget.indexOf(widget), tooltip)
elif topwidget.inherits("QWizard"):
topwidget.addPage(widget)
elif topwidget.inherits("QStackedWidget"):
topwidget.addWidget(widget)
elif topwidget.inherits("QDockWidget") or topwidget.inherits("QScrollArea"):
topwidget.setWidget(widget)
elif topwidget.inherits("QMainWindow"):
if type(widget) == QtGui.QWidget:
topwidget.setCentralWidget(widget)
elif widget.inherits("QToolBar"):
tbArea = self.wprops.getAttribute(elem, "toolBarArea")
if tbArea is None:
topwidget.addToolBar(widget)
else:
if isinstance(tbArea, str) or isinstance(tbArea, unicode):
tbArea = getattr(QtCore.Qt, tbArea)
else:
tbArea = QtCore.Qt.ToolBarArea(tbArea)
topwidget.addToolBar(tbArea, widget)
tbBreak = self.wprops.getAttribute(elem, "toolBarBreak")
if tbBreak:
topwidget.insertToolBarBreak(widget)
elif widget.inherits("QMenuBar"):
topwidget.setMenuBar(widget)
elif widget.inherits("QStatusBar"):
topwidget.setStatusBar(widget)
elif widget.inherits("QDockWidget"):
dwArea = self.wprops.getAttribute(elem, "dockWidgetArea")
topwidget.addDockWidget(QtCore.Qt.DockWidgetArea(dwArea),
widget)
def handleHeaderView(self, elem, name, header):
value = self.wprops.getAttribute(elem, name + "Visible")
if value is not None:
header.setVisible(value)
value = self.wprops.getAttribute(elem, name + "CascadingSectionResizes")
if value is not None:
header.setCascadingSectionResizes(value)
value = self.wprops.getAttribute(elem, name + "DefaultSectionSize")
if value is not None:
header.setDefaultSectionSize(value)
value = self.wprops.getAttribute(elem, name + "HighlightSections")
if value is not None:
header.setHighlightSections(value)
value = self.wprops.getAttribute(elem, name + "MinimumSectionSize")
if value is not None:
header.setMinimumSectionSize(value)
value = self.wprops.getAttribute(elem, name + "ShowSortIndicator")
if value is not None:
header.setSortIndicatorShown(value)
value = self.wprops.getAttribute(elem, name + "StretchLastSection")
if value is not None:
header.setStretchLastSection(value)
def createSpacer(self, elem):
width = int(elem.findtext("property/size/width"))
height = int(elem.findtext("property/size/height"))
sizeType = self.wprops.getProperty(elem, "sizeType",
QtGui.QSizePolicy.Expanding)
policy = (QtGui.QSizePolicy.Minimum, sizeType)
if self.wprops.getProperty(elem, "orientation") == QtCore.Qt.Horizontal:
policy = policy[1], policy[0]
name = self.uniqueName("spacerItem")
spacer = self.factory.createQObject("QSpacerItem",
name, (width, height) + policy,
is_attribute=False)
if self.stack.topIsLayout():
lay = self.stack.peek()
gp = elem.attrib["grid-position"]
if lay.inherits("QFormLayout"):
if gp[1]:
role = QtGui.QFormLayout.FieldRole
else:
role = QtGui.QFormLayout.LabelRole
lay.setItem(gp[0], role, spacer)
else:
lay.addItem(spacer, *gp)
# Must keep a reference to the spacer otherwise it'll go out of scope
# and cause a crash.
setattr(self.toplevelWidget, name, spacer)
def createLayout(self, elem):
# Qt v4.3 introduced setContentsMargins() and separate values for each
# of the four margins which are specified as separate properties. This
# doesn't really fit the way we parse the tree (why aren't the values
# passed as attributes of a single property?) so we create a new
# property and inject it. However, if we find that they have all been
# specified and have the same value then we inject a different property
# that is compatible with older versions of Qt.
left = self.wprops.getProperty(elem, 'leftMargin', -1)
top = self.wprops.getProperty(elem, 'topMargin', -1)
right = self.wprops.getProperty(elem, 'rightMargin', -1)
bottom = self.wprops.getProperty(elem, 'bottomMargin', -1)
# Count the number of properties and if they had the same value.
def comp_property(m, so_far=-2, nr=0):
if m >= 0:
nr += 1
if so_far == -2:
so_far = m
elif so_far != m:
so_far = -1
return so_far, nr
margin, nr_margins = comp_property(left)
margin, nr_margins = comp_property(top, margin, nr_margins)
margin, nr_margins = comp_property(right, margin, nr_margins)
margin, nr_margins = comp_property(bottom, margin, nr_margins)
if nr_margins > 0:
if nr_margins == 4 and margin >= 0:
# We can inject the old margin property.
me = SubElement(elem, 'property', name='margin')
SubElement(me, 'number').text = str(margin)
else:
# We have to inject the new internal property.
cme = SubElement(elem, 'property', name='pyuicContentsMargins')
SubElement(cme, 'number').text = str(left)
SubElement(cme, 'number').text = str(top)
SubElement(cme, 'number').text = str(right)
SubElement(cme, 'number').text = str(bottom)
# We do the same for setHorizontalSpacing() and setVerticalSpacing().
horiz = self.wprops.getProperty(elem, 'horizontalSpacing', -1)
vert = self.wprops.getProperty(elem, 'verticalSpacing', -1)
if horiz >= 0 or vert >= 0:
# We inject the new internal property.
cme = SubElement(elem, 'property', name='pyuicSpacing')
SubElement(cme, 'number').text = str(horiz)
SubElement(cme, 'number').text = str(vert)
classname = elem.attrib["class"]
if self.stack.topIsLayout():
parent = None
else:
parent = self.stack.topwidget
if "name" not in elem.attrib:
elem.attrib["name"] = classname[1:].lower()
self.stack.push(self.setupObject(classname, parent, elem))
self.traverseWidgetTree(elem)
layout = self.stack.popLayout()
if self.stack.topIsLayout():
top_layout = self.stack.peek()
gp = elem.attrib["grid-position"]
if top_layout.inherits("QFormLayout"):
if gp[1]:
role = QtGui.QFormLayout.FieldRole
else:
role = QtGui.QFormLayout.LabelRole
top_layout.setLayout(gp[0], role, layout)
else:
self.configureLayout(elem, layout)
top_layout.addLayout(layout, *gp)
else:
self.configureLayout(elem, layout)
def configureLayout(self, elem, layout):
if layout.inherits("QGridLayout"):
self.setArray(elem, 'columnminimumwidth',
layout.setColumnMinimumWidth)
self.setArray(elem, 'rowminimumheight',
layout.setRowMinimumHeight)
self.setArray(elem, 'columnstretch', layout.setColumnStretch)
self.setArray(elem, 'rowstretch', layout.setRowStretch)
elif layout.inherits("QBoxLayout"):
self.setArray(elem, 'stretch', layout.setStretch)
def setArray(self, elem, name, setter):
array = elem.attrib.get(name)
if array:
for idx, value in enumerate(array.split(',')):
value = int(value)
if value > 0:
setter(idx, value)
def handleItem(self, elem):
if self.stack.topIsLayout():
elem[0].attrib["grid-position"] = gridPosition(elem)
self.traverseWidgetTree(elem)
else:
w = self.stack.topwidget
if w.inherits("QComboBox"):
text = self.wprops.getProperty(elem, "text")
icon = self.wprops.getProperty(elem, "icon")
if icon:
w.addItem(icon, '')
else:
w.addItem('')
w.setItemText(self.item_nr, text)
elif w.inherits("QListWidget"):
text = self.wprops.getProperty(elem, "text")
icon = self.wprops.getProperty(elem, "icon")
flags = self.wprops.getProperty(elem, "flags")
check_state = self.wprops.getProperty(elem, "checkState")
if icon or flags or check_state:
item_name = "item"
else:
item_name = None
item = self.factory.createQObject("QListWidgetItem", item_name,
(w, ), False)
if self.item_nr == 0:
self.sorting_enabled = self.factory.invoke("__sortingEnabled", w.isSortingEnabled)
w.setSortingEnabled(False)
if text:
w.item(self.item_nr).setText(text)
if icon:
item.setIcon(icon)
if flags:
item.setFlags(flags)
if check_state:
item.setCheckState(check_state)
elif w.inherits("QTreeWidget"):
if self.itemstack:
parent, _ = self.itemstack[-1]
_, nr_in_root = self.itemstack[0]
else:
parent = w
nr_in_root = self.item_nr
item = self.factory.createQObject("QTreeWidgetItem",
"item_%d" % len(self.itemstack), (parent, ), False)
if self.item_nr == 0 and not self.itemstack:
self.sorting_enabled = self.factory.invoke("__sortingEnabled", w.isSortingEnabled)
w.setSortingEnabled(False)
self.itemstack.append((item, self.item_nr))
self.item_nr = 0
# We have to access the item via the tree when setting the
# text.
titm = w.topLevelItem(nr_in_root)
for child, nr_in_parent in self.itemstack[1:]:
titm = titm.child(nr_in_parent)
column = -1
for prop in elem.findall("property"):
c_prop = self.wprops.convert(prop)
c_prop_name = prop.attrib["name"]
if c_prop_name == "text":
column += 1
if c_prop:
titm.setText(column, c_prop)
elif c_prop_name == "icon":
item.setIcon(column, c_prop)
elif c_prop_name == "flags":
item.setFlags(c_prop)
elif c_prop_name == "checkState":
item.setCheckState(column, c_prop)
self.traverseWidgetTree(elem)
_, self.item_nr = self.itemstack.pop()
elif w.inherits("QTableWidget"):
text = self.wprops.getProperty(elem, "text")
icon = self.wprops.getProperty(elem, "icon")
flags = self.wprops.getProperty(elem, "flags")
check_state = self.wprops.getProperty(elem, "checkState")
item = self.factory.createQObject("QTableWidgetItem", "item",
(), False)
if self.item_nr == 0:
self.sorting_enabled = self.factory.invoke("__sortingEnabled", w.isSortingEnabled)
w.setSortingEnabled(False)
row = int(elem.attrib["row"])
col = int(elem.attrib["column"])
if text:
w.item(row, col).setText(text)
if icon:
item.setIcon(icon)
if flags:
item.setFlags(flags)
if check_state:
item.setCheckState(check_state)
w.setItem(row, col, item)
self.item_nr += 1
def addAction(self, elem):
self.actions.append((self.stack.topwidget, elem.attrib["name"]))
def addHeader(self, elem):
w = self.stack.topwidget
if w.inherits("QTreeWidget"):
text = self.wprops.getProperty(elem, "text")
icon = self.wprops.getProperty(elem, "icon")
if text:
w.headerItem().setText(self.column_counter, text)
if icon:
w.headerItem().setIcon(self.column_counter, icon)
self.column_counter += 1
elif w.inherits("QTableWidget"):
if len(elem) == 0:
return
text = self.wprops.getProperty(elem, "text")
icon = self.wprops.getProperty(elem, "icon")
item = self.factory.createQObject("QTableWidgetItem", "item",
(), False)
if elem.tag == "column":
w.setHorizontalHeaderItem(self.column_counter, item)
if text:
w.horizontalHeaderItem(self.column_counter).setText(text)
if icon:
item.setIcon(icon)
self.column_counter += 1
elif elem.tag == "row":
w.setVerticalHeaderItem(self.row_counter, item)
if text:
w.verticalHeaderItem(self.row_counter).setText(text)
if icon:
item.setIcon(icon)
self.row_counter += 1
def createAction(self, elem):
self.setupObject("QAction", self.currentActionGroup or self.toplevelWidget,
elem)
def createActionGroup(self, elem):
action_group = self.setupObject("QActionGroup", self.toplevelWidget, elem)
self.currentActionGroup = action_group
self.traverseWidgetTree(elem)
self.currentActionGroup = None
widgetTreeItemHandlers = {
"widget" : createWidget,
"addaction" : addAction,
"layout" : createLayout,
"spacer" : createSpacer,
"item" : handleItem,
"action" : createAction,
"actiongroup": createActionGroup,
"column" : addHeader,
"row" : addHeader,
}
def traverseWidgetTree(self, elem):
for child in iter(elem):
try:
handler = self.widgetTreeItemHandlers[child.tag]
except KeyError:
continue
handler(self, child)
def createUserInterface(self, elem):
# Get the names of the class and widget.
cname = elem.attrib["class"]
wname = elem.attrib["name"]
# If there was no widget name then derive it from the class name.
if not wname:
wname = cname
if wname.startswith("Q"):
wname = wname[1:]
wname = wname[0].lower() + wname[1:]
self.toplevelWidget = self.createToplevelWidget(cname, wname)
self.toplevelWidget.setObjectName(wname)
DEBUG("toplevel widget is %s",
self.toplevelWidget.className())
self.wprops.setProperties(self.toplevelWidget, elem)
self.stack.push(self.toplevelWidget)
self.traverseWidgetTree(elem)
self.stack.popWidget()
self.addActions()
self.setBuddies()
self.setDelayedProps()
def addActions(self):
for widget, action_name in self.actions:
if action_name == "separator":
widget.addSeparator()
else:
DEBUG("add action %s to %s", action_name, widget.objectName)
action_obj = getattr(self.toplevelWidget, action_name)
if action_obj.inherits("QMenu"):
widget.addAction(action_obj.menuAction())
elif not action_obj.inherits("QActionGroup"):
widget.addAction(action_obj)
def setDelayedProps(self):
for func, args in self.wprops.delayed_props:
func(args)
def setBuddies(self):
for widget, buddy in self.wprops.buddies:
DEBUG("%s is buddy of %s", buddy, widget.objectName)
try:
widget.setBuddy(getattr(self.toplevelWidget, buddy))
except AttributeError:
DEBUG("ERROR in ui spec: %s (buddy of %s) does not exist",
buddy, widget.objectName)
def classname(self, elem):
DEBUG("uiname is %s", elem.text)
name = elem.text
if name is None:
name = ""
self.uiname = name
self.wprops.uiname = name
self.setContext(name)
def setContext(self, context):
"""
Reimplemented by a sub-class if it needs to know the translation
context.
"""
pass
def readDefaults(self, elem):
self.defaults["margin"] = int(elem.attrib["margin"])
self.defaults["spacing"] = int(elem.attrib["spacing"])
def setTaborder(self, elem):
lastwidget = None
for widget_elem in elem:
widget = getattr(self.toplevelWidget, widget_elem.text)
if lastwidget is not None:
self.toplevelWidget.setTabOrder(lastwidget, widget)
lastwidget = widget
def readResources(self, elem):
"""
Read a "resources" tag and add the module to import to the parser's
list of them.
"""
for include in elem.getiterator("include"):
loc = include.attrib.get("location")
# Assume our convention for naming the Python files generated by
# pyrcc4.
if loc and loc.endswith('.qrc'):
self.resources.append(os.path.basename(loc[:-4] + '_rc'))
def createConnections(self, elem):
def name2object(obj):
if obj == self.uiname:
return self.toplevelWidget
else:
return getattr(self.toplevelWidget, obj)
for conn in iter(elem):
name2object(conn.findtext("sender")).connect(
conn.findtext("signal"),
name2object(conn.findtext("receiver")),
conn.findtext("slot"))
def customWidgets(self, elem):
def header2module(header):
"""header2module(header) -> string
Convert paths to C++ header files to according Python modules
>>> header2module("foo/bar/baz.h")
'foo.bar.baz'
"""
if header.endswith(".h"):
header = header[:-2]
mpath = []
for part in header.split('/'):
# Ignore any empty parts or those that refer to the current
# directory.
if part not in ('', '.'):
if part == '..':
# We should allow this for Python3.
raise SyntaxError("custom widget header file name may not contain '..'.")
mpath.append(part)
return '.'.join(mpath)
for custom_widget in iter(elem):
classname = custom_widget.findtext("class")
if classname.startswith("Q3"):
raise NoSuchWidgetError(classname)
self.factory.addCustomWidget(classname,
custom_widget.findtext("extends") or "QWidget",
header2module(custom_widget.findtext("header")))
def createToplevelWidget(self, classname, widgetname):
raise NotImplementedError
# finalize will be called after the whole tree has been parsed and can be
# overridden.
def finalize(self):
pass
def parse(self, filename):
# the order in which the different branches are handled is important
# the widget tree handler relies on all custom widgets being known,
# and in order to create the connections, all widgets have to be populated
branchHandlers = (
("layoutdefault", self.readDefaults),
("class", self.classname),
("customwidgets", self.customWidgets),
("widget", self.createUserInterface),
("connections", self.createConnections),
("tabstops", self.setTaborder),
("resources", self.readResources),
)
document = parse(filename)
version = document.getroot().attrib["version"]
DEBUG("UI version is %s" % (version,))
# Right now, only version 4.0 is supported, which is used up to at
# least Qt 4.4.
assert version in ("4.0",)
for tagname, actor in branchHandlers:
elem = document.find(tagname)
if elem is not None:
actor(elem)
self.finalize()
w = self.toplevelWidget
self.reset()
return w

View File

@ -1,29 +0,0 @@
import clementine
import sys
class __ClementineLogger__:
def __init__(self, error):
self._error = error
self._buffer = ''
def write(self, data):
self._buffer = self._buffer + data
i = self._buffer.find('\n')
while i != -1:
line = self._buffer[0:i]
self._buffer = self._buffer[i+1:]
i = self._buffer.find('\n')
clementine.pythonengine.AddLogLine(line, self._error)
sys.stdout = __ClementineLogger__(False)
sys.stderr = __ClementineLogger__(True)
# Hack StackedWidget -> QStackedWidget to work around bug in PyQt 4.8.2
try:
import PyQt4.QtGui
PyQt4.QtGui.StackedWidget = PyQt4.QtGui.QStackedWidget
except:
pass

View File

@ -1,59 +1,39 @@
from servicebase import DigitallyImportedServiceBase
from PythonQt.QtCore import QEvent, QFile, QObject, QSettings
from PythonQt.QtCore import QEvent, QFile, QSettings
from PythonQt.QtGui import QComboBox, QDialog, QIcon, QLineEdit
from PythonQt.QtUiTools import QUiLoader
import uic
import os.path
class SettingsDialog(QObject):
class SettingsDialog(QDialog):
def __init__(self, parent=None):
QObject.__init__(self, parent)
QDialog.__init__(self, parent)
self.path = os.path.dirname(__file__)
# Set up the user interface
ui_filename = os.path.join(self.path, "settingsdialog.ui")
ui_file = QFile(ui_filename)
if not ui_file.open(QFile.ReadOnly):
raise IOError(ui_file)
loader = QUiLoader()
self.dialog = loader.load(ui_file)
# Get the widgets from the dialog so we can use them later
self.type = self.dialog.findChild(QComboBox, "type")
self.username = self.dialog.findChild(QLineEdit, "username")
self.password = self.dialog.findChild(QLineEdit, "password")
# Install ourselves as an event filter on the dialog so we can see when
# it gets shown
self.dialog.installEventFilter(self)
# Connect to the accepted signal so we can save settings when the user
# clicks OK
self.dialog.connect("accepted()", self.SaveSettings)
uic.loadUi(os.path.join(self.path, "settingsdialog.ui"), self)
# Set the window icon
self.dialog.setWindowIcon(QIcon(os.path.join(self.path, "icon-small.png")))
self.setWindowIcon(QIcon(os.path.join(self.path, "icon-small.png")))
def eventFilter(self, obj, event):
if obj == self.dialog:
if event.type() == QEvent.Show:
self.LoadSettings()
QObject.eventFilter(self, obj, event)
def LoadSettings(self):
def showEvent(self, event):
# Load the settings
settings = QSettings()
settings.beginGroup(DigitallyImportedServiceBase.SETTINGS_GROUP)
self.type.setCurrentIndex(int(settings.value("audio_type", 0)))
self.username.setText(settings.value("username", ""))
self.password.setText(settings.value("password", ""))
def SaveSettings(self):
QDialog.showEvent(self, event)
def accept(self):
# Save the settings
settings = QSettings()
settings.beginGroup(DigitallyImportedServiceBase.SETTINGS_GROUP)
settings.setValue("audio_type", self.type.currentIndex)
settings.setValue("username", self.username.text)
settings.setValue("password", self.password.text)
QDialog.done(self, QDialog.Accepted)

View File

@ -20,3 +20,7 @@
void ObjectDecorators::deleteLater(QObject* self) {
self->deleteLater();
}
bool ObjectDecorators::inherits(QObject* self, const char* class_name) {
return self->inherits(class_name);
}

View File

@ -25,6 +25,7 @@ class ObjectDecorators : public QObject {
public slots:
void deleteLater(QObject* self);
bool inherits(QObject* self, const char* class_name);
};
#endif // OBJECTDECORATORS_H

View File

@ -20,7 +20,6 @@
#include <com_trolltech_qt_core/com_trolltech_qt_core_init.h>
#include <com_trolltech_qt_gui/com_trolltech_qt_gui_init.h>
#include <com_trolltech_qt_network/com_trolltech_qt_network_init.h>
#include <com_trolltech_qt_uitools/com_trolltech_qt_uitools_init.h>
#include "objectdecorators.h"
#include "pythonengine.h"
@ -83,11 +82,11 @@ bool PythonEngine::EnsureInitialised() {
PythonQt_init_QtCore(0);
PythonQt_init_QtGui(0);
PythonQt_init_QtNetwork(0);
PythonQt_init_QtUiTools(0);
PythonQt* python_qt = PythonQt::self();
python_qt->installDefaultImporter();
python_qt->addDecorators(new ObjectDecorators);
python_qt->addSysPath(":/pythonlibs/");
PythonQtConv::registerMetaTypeToPythonConverter(qMetaTypeId<SongList>(),
PythonQtConvertListOfValueTypeToPythonList<SongList, Song>);