Skip to content

Commit 79aa21d

Browse files
author
florianlink
committed
- removed warnings
- fixed some memory leaks (only on cleanup) - fixed bad QString usage as %s argument - added PythonQtQFileImporter, which implements a default importer using QFile - added PythonQt::self()->installDefaultImporter() to enable the new default importer - modified example to make use of new importer - removed ugly goto, which was copied from original zip import git-svn-id: http://svn.code.sf.net/p/pythonqt/code/trunk@43 ea8d5007-eb21-0410-b261-ccb3ea6e24a9
1 parent 83b6943 commit 79aa21d

20 files changed

+271
-154
lines changed

examples/CPPPyWrapperExample/CPPPyWrapperExample.cpp

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#include <PythonQt.h>
22
#include <QtGui>
3-
#include "QFileImportInterface.h"
43

54
int main (int argc, char* argv[]) {
65
QApplication app(argc, argv);
@@ -19,11 +18,10 @@ int main (int argc, char* argv[]) {
1918
Q_ASSERT(fn.toString() == QString("t.mp3"));
2019
// tag goes out of scope, reference count decremented.
2120
}
22-
qDebug() << "test1";
23-
/*
2421
{
2522
// Allow the python system path to recognize QFile paths in the sys.path
26-
QFileImportInterface qfii;
23+
//QFileImportInterface qfii;
24+
PythonQt::self()->setImporter(NULL);
2725
// append the Qt resource root directory to the sys.path
2826
mainModule.evalScript("sys.path.append(':')\n");
2927
mainModule.evalScript("import eyed3tagger\n");
@@ -33,7 +31,6 @@ int main (int argc, char* argv[]) {
3331
QVariant fn = tag.call("fileName", QVariantList());
3432
Q_ASSERT(fn.toString() == QString("t.mp3"));
3533
}
36-
qDebug() << "test2"; */
3734
{ // alternative using import and loading it as a real module from sys.path
3835
// import sys first
3936
mainModule.evalScript(QString("sys.path.append('%1')\n").arg(QDir::currentPath()));

examples/CPPPyWrapperExample/CPPPyWrapperExample.pro

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ CONFIG += debug
22
VPATH +=
33
INCLUDEPATH += . $$(PYTHONQT_ROOT)/src /usr/include/python2.5
44

5-
SOURCES += CPPPyWrapperExample.cpp QFileImportInterface.cpp
6-
HEADERS += QFileImportInterface.h
5+
SOURCES += CPPPyWrapperExample.cpp
76

7+
mac { CONFIG -= app_bundle }
88

9-
LIBS += -L$$(PYTHONQT_ROOT)/lib -lPythonQt -lutil
9+
LIBS += -L$$(PYTHONQT_ROOT)/lib -lPythonQt_d -lutil
1010

1111
RESOURCES += CPPPyWrapperExample.qrc

examples/CPPPyWrapperExample/QFileImportInterface.cpp

-42
This file was deleted.

examples/CPPPyWrapperExample/QFileImportInterface.h

-20
This file was deleted.

src/PythonQt.cpp

+27-9
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
#include "PythonQtCppWrapperFactory.h"
5050
#include "PythonQtVariants.h"
5151
#include "PythonQtStdDecorators.h"
52+
#include "PythonQtQFileImporter.h"
5253
#include <pydebug.h>
5354

5455
PythonQt* PythonQt::_self = NULL;
@@ -163,6 +164,14 @@ PythonQt::~PythonQt() {
163164
}
164165

165166
PythonQtPrivate::~PythonQtPrivate() {
167+
delete _defaultImporter;
168+
_defaultImporter = NULL;
169+
{
170+
QHashIterator<QByteArray, PythonQtSlotInfo *> i(_knownQtDecoratorSlots);
171+
while (i.hasNext()) {
172+
delete i.next().value();
173+
}
174+
}
166175
{
167176
QHashIterator<QByteArray, PythonQtClassInfo *> i(_knownQtClasses);
168177
while (i.hasNext()) {
@@ -184,13 +193,25 @@ PythonQtPrivate::~PythonQtPrivate() {
184193
{
185194
QHashIterator<QByteArray, PythonQtSlotInfo *> i(_constructorSlots);
186195
while (i.hasNext()) {
187-
delete i.next().value();
196+
PythonQtSlotInfo* cur = i.next().value();
197+
while(cur->nextInfo()) {
198+
PythonQtSlotInfo* next = cur->nextInfo();
199+
delete cur;
200+
cur = next;
201+
}
202+
delete cur;
188203
}
189204
}
190205
{
191206
QHashIterator<QByteArray, PythonQtSlotInfo *> i(_destructorSlots);
192207
while (i.hasNext()) {
193-
delete i.next().value();
208+
PythonQtSlotInfo* cur = i.next().value();
209+
while(cur->nextInfo()) {
210+
PythonQtSlotInfo* next = cur->nextInfo();
211+
delete cur;
212+
cur = next;
213+
}
214+
delete cur;
194215
}
195216
}
196217
PythonQtConv::global_valueStorage.clear();
@@ -204,7 +225,7 @@ PythonQtPrivate::~PythonQtPrivate() {
204225

205226
PythonQtImportFileInterface* PythonQt::importInterface()
206227
{
207-
return _self->_p->_importInterface;
228+
return _self->_p->_importInterface?_self->_p->_importInterface:_self->_p->_defaultImporter;
208229
}
209230

210231
void PythonQt::registerClass(const QMetaObject* metaobject)
@@ -760,12 +781,8 @@ void PythonQt::registerQObjectClassNames(const QStringList& names)
760781

761782
void PythonQt::setImporter(PythonQtImportFileInterface* importInterface)
762783
{
763-
static bool first = true;
764-
if (first) {
765-
first = false;
766-
_p->_importInterface = importInterface;
767-
PythonQtImport::init();
768-
}
784+
PythonQtImport::init();
785+
_p->_importInterface = importInterface;
769786
}
770787

771788
void PythonQt::setImporterIgnorePaths(const QStringList& paths)
@@ -797,6 +814,7 @@ const QList<PythonQtConstructorHandler*>& PythonQt::constructorHandlers()
797814
PythonQtPrivate::PythonQtPrivate()
798815
{
799816
_importInterface = NULL;
817+
_defaultImporter = new PythonQtQFileImporter;
800818
_noLongerWrappedCB = NULL;
801819
_wrappedCB = NULL;
802820
}

src/PythonQt.h

+19-1
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ class PythonQtSignalReceiver;
6565
class PythonQtImportFileInterface;
6666
class PythonQtCppWrapperFactory;
6767
class PythonQtConstructorHandler;
68+
class PythonQtQFileImporter;
6869

6970
typedef void PythonQtQObjectWrappedCB(QObject* object);
7071
typedef void PythonQtQObjectNoLongerWrappedCB(QObject* object);
@@ -278,9 +279,23 @@ class PYTHONQT_EXPORT PythonQt : public QObject {
278279

279280
//! replace the internal import implementation and use the supplied interface to load files (both py and pyc files)
280281
//! (this method should be called directly after initialization of init() and before calling overwriteSysPath().
281-
//! It can only be called once, further calls will be ignored silently. (ownership stays with caller)
282+
//! On the first call to this method, it will install a generic PythonQt importer in Pythons "path_hooks".
283+
//! This is not reversible, so even setting setImporter(NULL) afterwards will
284+
//! keep the custom PythonQt importer with a QFile default import interface.
285+
//! Subsequent python import calls will make use of the passed importInterface
286+
//! which forwards all import calls to the given \c importInterface.
287+
//! Passing NULL will install a default QFile importer.
288+
//! (\c importInterface ownership stays with caller)
282289
void setImporter(PythonQtImportFileInterface* importInterface);
283290

291+
//! this installs the default QFile importer (which effectively does a setImporter(NULL))
292+
//! (without calling setImporter or installDefaultImporter at least once, the default python import
293+
//! mechanism is in place)
294+
//! the default importer allows to import files from anywhere QFile can read from,
295+
//! including the Qt resource system using ":". Keep in mind that you need to extend
296+
//! "sys.path" with ":" to be able to import from the Qt resources.
297+
void installDefaultImporter() { setImporter(NULL); }
298+
284299
//! set paths that the importer should ignore
285300
void setImporterIgnorePaths(const QStringList& paths);
286301

@@ -442,6 +457,9 @@ class PythonQtPrivate : public QObject {
442457
//! the importer interface (if set)
443458
PythonQtImportFileInterface* _importInterface;
444459

460+
//! the default importer
461+
PythonQtQFileImporter* _defaultImporter;
462+
445463
PythonQtQObjectNoLongerWrappedCB* _noLongerWrappedCB;
446464
PythonQtQObjectWrappedCB* _wrappedCB;
447465

src/PythonQtConversion.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -588,7 +588,7 @@ QString PythonQtConv::PyObjGetString(PyObject* val, bool strict, bool& ok) {
588588
return r;
589589
}
590590

591-
QByteArray PythonQtConv::PyObjGetBytes(PyObject* val, bool strict, bool& ok) {
591+
QByteArray PythonQtConv::PyObjGetBytes(PyObject* val, bool /*strict*/, bool& ok) {
592592
QByteArray r;
593593
ok = true;
594594
if (val->ob_type == &PyString_Type) {
@@ -980,7 +980,7 @@ PyObject* PythonQtConv::ConvertQListWithPointersToPython(QList<void*>* list, con
980980
return result;
981981
}
982982

983-
bool PythonQtConv::ConvertPythonListToQListOfType(PyObject* obj, QList<void*>* list, const QByteArray& type, bool strict)
983+
bool PythonQtConv::ConvertPythonListToQListOfType(PyObject* obj, QList<void*>* list, const QByteArray& type, bool /*strict*/)
984984
{
985985
bool result = false;
986986
if (PySequence_Check(obj)) {

src/PythonQtDoc.h

+2-6
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
5252
\section Introduction
5353
54-
\b PythonQt is a dynamic Python (http://www.python.org) binding for Qt (http://www.trolltech.com).
54+
\b PythonQt is a dynamic Python (http://www.python.org) binding for Qt (http://www.qtsoftware.com).
5555
It offers an easy way to embed the Python scripting language into
5656
your Qt applications. It makes heavy use of the QMetaObject system and thus requires Qt4.x.
5757
@@ -339,7 +339,7 @@ yourCpp = None
339339
340340
\section Building
341341
342-
PythonQt requires at least Qt 4.2.2 (or higher) and Python 2.3, 2.4 or 2.5 on Windows, Linux and MacOS X.
342+
PythonQt requires at least Qt 4.2.2 (or higher) and Python 2.3, 2.4, 2.5 or 2.6 on Windows, Linux and MacOS X. It has not yet been tested with Python 3.x, but it should only require minor changes.
343343
To compile PythonQt, you will need a python developer installation which includes Python's header files and
344344
the python2x.[lib | dll | so | dynlib].
345345
The build scripts a currently set to use Python 2.5.
@@ -459,8 +459,4 @@ the python2x.[lib | dll | so | dynlib].
459459
\endcode
460460
461461
462-
\section TODOs
463-
464-
- add more information on how to distribute an application that uses PythonQt, including the Python distribution
465-
466462
*/

src/PythonQtImportFileInterface.h

+3
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@
5151
class PythonQtImportFileInterface {
5252

5353
public:
54+
// get rid of warnings
55+
virtual ~PythonQtImportFileInterface() {}
56+
5457
//! read the given file as byte array, without doing any linefeed translations
5558
virtual QByteArray readFileAsBytes(const QString& filename) = 0;
5659

0 commit comments

Comments
 (0)