@@ -1,53 +1,53 | |||||
1 |
|
1 | |||
2 | Version 1.1 ChangeLog: |
|
2 | Version 1.1 ChangeLog: | |
3 |
|
3 | |||
4 | florianlink | 2008-09-01 |
|
4 | florianlink | 2008-09-01 | |
5 | - merged in features/fixes from the MeVisLab repository: |
|
5 | - merged in features/fixes from the MeVisLab repository: | |
6 | - added createModuleFromFile/createModuleFromScript/createUniqueModule |
|
6 | - added createModuleFromFile/createModuleFromScript/createUniqueModule | |
7 | - switched object destruction to use QPointer and lazy wrapper removal to avoid expensive objectDestroyed signal connections |
|
7 | - switched object destruction to use QPointer and lazy wrapper removal to avoid expensive objectDestroyed signal connections | |
8 | - added hash() support for PythnQtWrapper object |
|
8 | - added hash() support for PythonQtWrapper object | |
9 | - added support for signal to python function connections where the function has less arguments than the emitted signal |
|
9 | - added support for signal to python function connections where the function has less arguments than the emitted signal | |
10 | - added setQObject[NoLonger]WrappedCallback API to support external reference counting on QObjects that are exposed to PythonQt |
|
10 | - added setQObject[NoLonger]WrappedCallback API to support external reference counting on QObjects that are exposed to PythonQt | |
11 | - implemented flush on std redirect to support python logging framework |
|
11 | - implemented flush on std redirect to support python logging framework | |
12 | - improved QVariant printing and fixed print error on MacX |
|
12 | - improved QVariant printing and fixed print error on MacX | |
13 |
|
13 | |||
14 | ezust | 2008-29-08 |
|
14 | ezust | 2008-29-08 | |
15 | - Added CHANGELOG |
|
15 | - Added CHANGELOG | |
16 | - Bumped version to 1.1 |
|
16 | - Bumped version to 1.1 | |
17 | - Added PythonQtObjectPtr conversion ctor and operator=(const QVariant&) |
|
17 | - Added PythonQtObjectPtr conversion ctor and operator=(const QVariant&) | |
18 | - added examples/CPPPyWrapperExample |
|
18 | - added examples/CPPPyWrapperExample | |
19 |
|
19 | |||
20 | florianlink | 2007-11-15 08:38:24 -0800 (Thu, 15 Nov 2007) |
|
20 | florianlink | 2007-11-15 08:38:24 -0800 (Thu, 15 Nov 2007) | |
21 | - added support for mapping Python lists to QList<AnyPtr*> lists on slot calls |
|
21 | - added support for mapping Python lists to QList<AnyPtr*> lists on slot calls | |
22 | - added support for QList<AnyPtr*> return values and signal signatures |
|
22 | - added support for QList<AnyPtr*> return values and signal signatures | |
23 | - changed binary output to lib as well, so that the setting of PATH can be avoided |
|
23 | - changed binary output to lib as well, so that the setting of PATH can be avoided | |
24 | - changed profiles to use a new common.prf to facilitate global settings |
|
24 | - changed profiles to use a new common.prf to facilitate global settings | |
25 | - improved docs |
|
25 | - improved docs | |
26 | - added _d extension for debug build (see common.prf) |
|
26 | - added _d extension for debug build (see common.prf) | |
27 | - added $$PWD, which is important if the file is included from somewhere else (which we do in mevis) |
|
27 | - added $$PWD, which is important if the file is included from somewhere else (which we do in mevis) | |
28 | - added softspace support (implemented by Andre Kramer) |
|
28 | - added softspace support (implemented by Andre Kramer) | |
29 | - updated windows documentation and variables which need to be set |
|
29 | - updated windows documentation and variables which need to be set | |
30 | - changed to use only PYTHON_PATH on Windows |
|
30 | - changed to use only PYTHON_PATH on Windows | |
31 | - added more build docs |
|
31 | - added more build docs | |
32 | - changed date conversion from/to strings to ISODate |
|
32 | - changed date conversion from/to strings to ISODate | |
33 | - fixed return argument initialization to NULL |
|
33 | - fixed return argument initialization to NULL | |
34 | - added mevis doc |
|
34 | - added mevis doc | |
35 | - fixed handling of unknown reference types |
|
35 | - fixed handling of unknown reference types | |
36 | - made lookupObject public |
|
36 | - made lookupObject public | |
37 | - added overload calls to introspection |
|
37 | - added overload calls to introspection | |
38 |
|
38 | |||
39 | marcusbarann | 2007-11-08 06:15:55 -0800 (Thu, 08 Nov 2007) |
|
39 | marcusbarann | 2007-11-08 06:15:55 -0800 (Thu, 08 Nov 2007) | |
40 | - Added PythonQt.pro, cleaned up build system |
|
40 | - Added PythonQt.pro, cleaned up build system | |
41 |
|
41 | |||
42 | akramer | 2007-10-17 08:02:25 -0700 (Wed, 17 Oct 2007) |
|
42 | akramer | 2007-10-17 08:02:25 -0700 (Wed, 17 Oct 2007) | |
43 | - external variant was missing the "config += qtestlib" needed for using the Qt unit test framework. |
|
43 | - external variant was missing the "config += qtestlib" needed for using the Qt unit test framework. | |
44 | - provide relative path to Gui extension lib |
|
44 | - provide relative path to Gui extension lib | |
45 | - added a sentence about using the Windows installer version of Python |
|
45 | - added a sentence about using the Windows installer version of Python | |
46 | - Fix for converting QByteArray values that include 0 chars. |
|
46 | - Fix for converting QByteArray values that include 0 chars. | |
47 | They are still converted to/from Python strings but using |
|
47 | They are still converted to/from Python strings but using | |
48 | size of contents rather than string 0 (null) termination. |
|
48 | size of contents rather than string 0 (null) termination. | |
49 | - bug fix for getMTimeOfSource when PythonQt::importInterface() is null |
|
49 | - bug fix for getMTimeOfSource when PythonQt::importInterface() is null | |
50 | - Linux external build improvements |
|
50 | - Linux external build improvements | |
51 |
|
51 | |||
52 | 2007-01-30 00:11:25 -0800 (Tue, 30 Jan 2007) | 1 line |
|
52 | 2007-01-30 00:11:25 -0800 (Tue, 30 Jan 2007) | 1 line | |
53 | - Released version 1.0 |
|
53 | - Released version 1.0 |
@@ -1,34 +1,35 | |||||
1 | #include <PythonQt.h> |
|
1 | #include <PythonQt.h> | |
2 | #include <QtGui> |
|
2 | #include <QtGui> | |
3 | int main (int argc, char* argv[]) { |
|
3 | int main (int argc, char* argv[]) { | |
4 | QApplication app(argc, argv); |
|
4 | QApplication app(argc, argv); | |
5 | PythonQt::init(); |
|
5 | PythonQt::init(); | |
6 | PythonQtObjectPtr mainModule = PythonQt::self()->getMainModule(); |
|
6 | PythonQtObjectPtr mainModule = PythonQt::self()->getMainModule(); | |
7 | Q_ASSERT(!mainModule.isNull()); |
|
7 | Q_ASSERT(!mainModule.isNull()); | |
8 | { |
|
8 | { | |
9 | // evaluate a python file embedded in executable as resource: |
|
9 | // evaluate a python file embedded in executable as resource: | |
10 | mainModule.evalFile(":eyed3tagger.py"); |
|
10 | mainModule.evalFile(":eyed3tagger.py"); | |
|
11 | // create an object, hold onto its reference | |||
11 | PythonQtObjectPtr tag = mainModule.evalScript("EyeD3Tagger()\n", Py_eval_input); |
|
12 | PythonQtObjectPtr tag = mainModule.evalScript("EyeD3Tagger()\n", Py_eval_input); | |
12 | Q_ASSERT(!tag.isNull()); |
|
13 | Q_ASSERT(!tag.isNull()); | |
13 | tag.call("setFileName", QVariantList() << "t.mp3"); |
|
14 | tag.call("setFileName", QVariantList() << "t.mp3"); | |
14 | QVariant fn = tag.call("fileName", QVariantList()); |
|
15 | QVariant fn = tag.call("fileName", QVariantList()); | |
15 | Q_ASSERT(fn.toString() == QString("t.mp3")); |
|
16 | Q_ASSERT(fn.toString() == QString("t.mp3")); | |
|
17 | // tag goes out of scope, reference count decremented. | |||
16 | } |
|
18 | } | |
17 | qDebug() << "test1"; |
|
19 | qDebug() << "test1"; | |
18 | { // alternative using import and loading it as a real module from sys.path |
|
20 | { // alternative using import and loading it as a real module from sys.path | |
19 | // import sys first |
|
21 | // import sys first | |
20 | mainModule.evalScript(QString("import sys\n")); |
|
22 | mainModule.evalScript(QString("import sys\n")); | |
21 | // append the current directory to the sys.path |
|
23 | // append the current directory to the sys.path | |
22 | mainModule.evalScript(QString("sys.path.append('%1')\n").arg(QDir::currentPath())); |
|
24 | mainModule.evalScript(QString("sys.path.append('%1')\n").arg(QDir::currentPath())); | |
23 |
|
||||
24 | mainModule.evalScript("import eyed3tagger\n"); |
|
25 | mainModule.evalScript("import eyed3tagger\n"); | |
25 | PythonQtObjectPtr tag = mainModule.evalScript("eyed3tagger.EyeD3Tagger()\n", Py_eval_input); |
|
26 | PythonQtObjectPtr tag = mainModule.evalScript("eyed3tagger.EyeD3Tagger()\n", Py_eval_input); | |
26 | Q_ASSERT(!tag.isNull()); |
|
27 | Q_ASSERT(!tag.isNull()); | |
27 | tag.call("setFileName", QVariantList() << "t.mp3"); |
|
28 | tag.call("setFileName", QVariantList() << "t.mp3"); | |
28 | QVariant fn = tag.call("fileName", QVariantList()); |
|
29 | QVariant fn = tag.call("fileName", QVariantList()); | |
29 | Q_ASSERT(fn.toString() == QString("t.mp3")); |
|
30 | Q_ASSERT(fn.toString() == QString("t.mp3")); | |
30 | } |
|
31 | } | |
31 |
|
32 | |||
32 | qDebug() << "finished"; |
|
33 | qDebug() << "finished"; | |
33 | return 0; |
|
34 | return 0; | |
34 | } |
|
35 | } |
@@ -1,9 +1,7 | |||||
1 |
|
|
1 | This example shows how to add user defined Python classes | |
2 | embedded Python mainModule. |
|
2 | to the embedded Python mainModule. | |
|
3 | ||||
3 | It also shows how to create objects in Python, |
|
4 | It also shows how to create objects in Python, | |
4 | hold onto reference counted smart pointers to them from |
|
5 | hold onto reference counted smart pointers to them from | |
5 | a Qt application, and invoke methods on them via |
|
6 | a Qt application, and invoke methods on them via | |
6 | the PythonQtObjectPtr interface. |
|
7 | the PythonQtObjectPtr interface. | |
7 |
|
||||
8 |
|
||||
9 |
|
@@ -1,26 +1,27 | |||||
1 | from PythonQt import * |
|
1 | from PythonQt import * | |
2 |
|
2 | |||
3 | # set the title of the group box, accessing the title property |
|
3 | # set the title of the group box, accessing the title property | |
4 | box.title = 'PythonQt Example' |
|
4 | box.title = 'PythonQt Example' | |
5 |
|
5 | |||
6 | # set the html content of the QTextBrowser |
|
6 | # set the html content of the QTextBrowser | |
7 | box.browser.html = 'Hello <b>Qt</b>!' |
|
7 | box.browser.html = 'Hello <b>Qt</b>!' | |
8 |
|
8 | |||
9 | # set the title of the button |
|
9 | # set the title of the button | |
10 | box.button1.text = 'Append Text' |
|
10 | box.button1.text = 'Append Text' | |
11 |
|
11 | |||
12 | # set the text of the line edit |
|
12 | # set the text of the line edit | |
13 | box.edit.text = '42' |
|
13 | box.edit.text = '42' | |
14 |
|
14 | |||
15 | # define our own python method that appends the text from the line edit |
|
15 | # define our own python method that appends the text from the line edit | |
16 | # to the text browser |
|
16 | # to the text browser | |
17 | def appendLine(): |
|
17 | def appendLine(): | |
18 | box.browser.append(box.edit.text) |
|
18 | box.browser.append(box.edit.text) | |
19 |
|
19 | |||
20 | # connect the button's clicked signal to our python method |
|
20 | # connect the button's clicked signal to our python method | |
21 | box.button1.connect('clicked()', appendLine) |
|
21 | box.button1.connect('clicked()', appendLine) | |
22 | # connect the lineedit's returnPressed signal to our python method |
|
22 | # connect the lineedit's returnPressed signal to our python method | |
23 | box.edit.connect('returnPressed()', appendLine) |
|
23 | box.edit.connect('returnPressed()', appendLine) | |
24 |
|
24 | |||
25 | # show the window |
|
25 | # show the window | |
26 | box.show() |
|
26 | box.show() | |
|
27 |
@@ -1,90 +1,101 | |||||
1 | /* |
|
1 | /* | |
2 | * |
|
2 | * | |
3 | * Copyright (C) 2006 MeVis Research GmbH All Rights Reserved. |
|
3 | * Copyright (C) 2006 MeVis Research GmbH All Rights Reserved. | |
4 | * |
|
4 | * | |
5 | * This library is free software; you can redistribute it and/or |
|
5 | * This library is free software; you can redistribute it and/or | |
6 | * modify it under the terms of the GNU Lesser General Public |
|
6 | * modify it under the terms of the GNU Lesser General Public | |
7 | * License as published by the Free Software Foundation; either |
|
7 | * License as published by the Free Software Foundation; either | |
8 | * version 2.1 of the License, or (at your option) any later version. |
|
8 | * version 2.1 of the License, or (at your option) any later version. | |
9 | * |
|
9 | * | |
10 | * This library is distributed in the hope that it will be useful, |
|
10 | * This library is distributed in the hope that it will be useful, | |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | * Lesser General Public License for more details. |
|
13 | * Lesser General Public License for more details. | |
14 | * |
|
14 | * | |
15 | * Further, this software is distributed without any warranty that it is |
|
15 | * Further, this software is distributed without any warranty that it is | |
16 | * free of the rightful claim of any third person regarding infringement |
|
16 | * free of the rightful claim of any third person regarding infringement | |
17 | * or the like. Any license provided herein, whether implied or |
|
17 | * or the like. Any license provided herein, whether implied or | |
18 | * otherwise, applies only to this software file. Patent licenses, if |
|
18 | * otherwise, applies only to this software file. Patent licenses, if | |
19 | * any, provided herein do not apply to combinations of this program with |
|
19 | * any, provided herein do not apply to combinations of this program with | |
20 | * other software, or any other product whatsoever. |
|
20 | * other software, or any other product whatsoever. | |
21 | * |
|
21 | * | |
22 | * You should have received a copy of the GNU Lesser General Public |
|
22 | * You should have received a copy of the GNU Lesser General Public | |
23 | * License along with this library; if not, write to the Free Software |
|
23 | * License along with this library; if not, write to the Free Software | |
24 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
24 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
25 | * |
|
25 | * | |
26 | * Contact information: MeVis Research GmbH, Universitaetsallee 29, |
|
26 | * Contact information: MeVis Research GmbH, Universitaetsallee 29, | |
27 | * 28359 Bremen, Germany or: |
|
27 | * 28359 Bremen, Germany or: | |
28 | * |
|
28 | * | |
29 | * http://www.mevis.de |
|
29 | * http://www.mevis.de | |
30 | * |
|
30 | * | |
31 | */ |
|
31 | */ | |
32 |
|
32 | |||
33 | //---------------------------------------------------------------------------------- |
|
33 | //---------------------------------------------------------------------------------- | |
34 | /*! |
|
34 | /*! | |
35 | // \file PythonQtTests.cpp |
|
35 | // \file PythonQtTests.cpp | |
36 | // \author Florian Link |
|
36 | // \author Florian Link | |
37 | // \author Last changed by $Author: florian $ |
|
37 | // \author Last changed by $Author: florian $ | |
38 | // \date 2006-05 |
|
38 | // \date 2006-05 | |
39 | */ |
|
39 | */ | |
40 | //---------------------------------------------------------------------------------- |
|
40 | //---------------------------------------------------------------------------------- | |
41 |
|
41 | |||
42 | #include "PythonQt.h" |
|
42 | #include "PythonQt.h" | |
43 | #include <QApplication> |
|
43 | #include <QApplication> | |
44 | #include <QTextBrowser> |
|
44 | #include <QTextBrowser> | |
45 | #include <QLayout> |
|
45 | #include <QLayout> | |
46 | #include <QGroupBox> |
|
46 | #include <QGroupBox> | |
47 | #include <QPushButton> |
|
47 | #include <QPushButton> | |
48 | #include <QLineEdit> |
|
48 | #include <QLineEdit> | |
49 |
|
49 | |||
50 | int main( int argc, char **argv ) |
|
50 | int main( int argc, char **argv ) | |
51 | { |
|
51 | { | |
52 | QApplication qapp(argc, argv); |
|
52 | QApplication qapp(argc, argv); | |
53 |
|
53 | |||
54 | // init PythonQt and Python |
|
54 | // init PythonQt and Python | |
55 | PythonQt::init(); |
|
55 | PythonQt::init(); | |
56 |
|
56 | |||
57 | // get the __main__ python module |
|
57 | // get the __main__ python module | |
58 | PythonQtObjectPtr mainModule = PythonQt::self()->getMainModule(); |
|
58 | PythonQtObjectPtr mainModule = PythonQt::self()->getMainModule(); | |
59 |
|
59 | |||
60 | // evaluate a simple python script and receive the result a qvariant: |
|
60 | // evaluate a simple python script and receive the result a qvariant: | |
61 | QVariant result = mainModule.evalScript("19*2+4", Py_eval_input); |
|
61 | QVariant result = mainModule.evalScript("19*2+4", Py_eval_input); | |
62 |
|
62 | |||
|
63 | // Create object from python, hold onto reference in C++: | |||
|
64 | PythonQtObjectPtr tag = mainModule.evalScript("EyeD3Tagger()\n", Py_eval_input); | |||
|
65 | Q_ASSERT(!tag.isNull()); | |||
|
66 | ||||
|
67 | // call python methods from C++ | |||
|
68 | tag.call("setFileName", QVariantList() << "t.mp3"); | |||
|
69 | QVariant fn = tag.call("fileName", QVariantList()); | |||
|
70 | Q_ASSERT(fn.toString() == QString("t.mp3")); | |||
|
71 | ||||
63 | // create a small Qt GUI |
|
72 | // create a small Qt GUI | |
64 | QVBoxLayout* vbox = new QVBoxLayout; |
|
73 | QVBoxLayout* vbox = new QVBoxLayout; | |
65 | QGroupBox* box = new QGroupBox; |
|
74 | QGroupBox* box = new QGroupBox; | |
66 | QTextBrowser* browser = new QTextBrowser(box); |
|
75 | QTextBrowser* browser = new QTextBrowser(box); | |
67 | QLineEdit* edit = new QLineEdit(box); |
|
76 | QLineEdit* edit = new QLineEdit(box); | |
68 | QPushButton* button = new QPushButton(box); |
|
77 | QPushButton* button = new QPushButton(box); | |
69 | button->setObjectName("button1"); |
|
78 | button->setObjectName("button1"); | |
70 | edit->setObjectName("edit"); |
|
79 | edit->setObjectName("edit"); | |
71 | browser->setObjectName("browser"); |
|
80 | browser->setObjectName("browser"); | |
72 | vbox->addWidget(browser); |
|
81 | vbox->addWidget(browser); | |
73 | vbox->addWidget(edit); |
|
82 | vbox->addWidget(edit); | |
74 | vbox->addWidget(button); |
|
83 | vbox->addWidget(button); | |
75 | box->setLayout(vbox); |
|
84 | box->setLayout(vbox); | |
76 |
|
85 | |||
77 | // make the groupbox to the python under the name "box" |
|
86 | // make the groupbox to the python under the name "box" | |
78 | mainModule.addObject("box", box); |
|
87 | mainModule.addObject("box", box); | |
79 |
|
88 | |||
80 | // evaluate the python script which is defined in the resources |
|
89 | // evaluate the python script which is defined in the resources | |
81 | mainModule.evalFile(":GettingStarted.py"); |
|
90 | mainModule.evalFile(":GettingStarted.py"); | |
82 |
|
91 | |||
83 | // define a python method that appends the passed text to the browser |
|
92 | // define a python method that appends the passed text to the browser | |
84 | mainModule.evalScript("def appendText(text):\n box.browser.append(text)"); |
|
93 | mainModule.evalScript("def appendText(text):\n box.browser.append(text)"); | |
85 | // shows how to call the method with a text that will be append to the browser |
|
94 | // shows how to call the method with a text that will be append to the browser | |
86 | mainModule.call("appendText", QVariantList() << "The ultimate answer is "); |
|
95 | mainModule.call("appendText", QVariantList() << "The ultimate answer is "); | |
87 |
|
96 | |||
|
97 | ||||
|
98 | ||||
88 |
|
|
99 | return qapp.exec(); | |
89 | } |
|
100 | } | |
90 |
|
101 |
@@ -1,462 +1,466 | |||||
1 | #ifndef _PYTHONQTDOC_H |
|
1 | #ifndef _PYTHONQTDOC_H | |
2 | #define _PYTHONQTDOC_H |
|
2 | #define _PYTHONQTDOC_H | |
3 |
|
3 | |||
4 | /* |
|
4 | /* | |
5 | * |
|
5 | * | |
6 | * Copyright (C) 2006 MeVis Research GmbH All Rights Reserved. |
|
6 | * Copyright (C) 2006 MeVis Research GmbH All Rights Reserved. | |
7 | * |
|
7 | * | |
8 | * This library is free software; you can redistribute it and/or |
|
8 | * This library is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU Lesser General Public |
|
9 | * modify it under the terms of the GNU Lesser General Public | |
10 | * License as published by the Free Software Foundation; either |
|
10 | * License as published by the Free Software Foundation; either | |
11 | * version 2.1 of the License, or (at your option) any later version. |
|
11 | * version 2.1 of the License, or (at your option) any later version. | |
12 | * |
|
12 | * | |
13 | * This library is distributed in the hope that it will be useful, |
|
13 | * This library is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 | * Lesser General Public License for more details. |
|
16 | * Lesser General Public License for more details. | |
17 | * |
|
17 | * | |
18 | * Further, this software is distributed without any warranty that it is |
|
18 | * Further, this software is distributed without any warranty that it is | |
19 | * free of the rightful claim of any third person regarding infringement |
|
19 | * free of the rightful claim of any third person regarding infringement | |
20 | * or the like. Any license provided herein, whether implied or |
|
20 | * or the like. Any license provided herein, whether implied or | |
21 | * otherwise, applies only to this software file. Patent licenses, if |
|
21 | * otherwise, applies only to this software file. Patent licenses, if | |
22 | * any, provided herein do not apply to combinations of this program with |
|
22 | * any, provided herein do not apply to combinations of this program with | |
23 | * other software, or any other product whatsoever. |
|
23 | * other software, or any other product whatsoever. | |
24 | * |
|
24 | * | |
25 | * You should have received a copy of the GNU Lesser General Public |
|
25 | * You should have received a copy of the GNU Lesser General Public | |
26 | * License along with this library; if not, write to the Free Software |
|
26 | * License along with this library; if not, write to the Free Software | |
27 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
27 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
28 | * |
|
28 | * | |
29 | * Contact information: MeVis Research GmbH, Universitaetsallee 29, |
|
29 | * Contact information: MeVis Research GmbH, Universitaetsallee 29, | |
30 | * 28359 Bremen, Germany or: |
|
30 | * 28359 Bremen, Germany or: | |
31 | * |
|
31 | * | |
32 | * http://www.mevis.de |
|
32 | * http://www.mevis.de | |
33 | * |
|
33 | * | |
34 | */ |
|
34 | */ | |
35 |
|
35 | |||
36 | //---------------------------------------------------------------------------------- |
|
36 | //---------------------------------------------------------------------------------- | |
37 | /*! |
|
37 | /*! | |
38 | // \file PythonQtDoc.h |
|
38 | // \file PythonQtDoc.h | |
39 | // \author Florian Link |
|
39 | // \author Florian Link | |
40 | // \author Last changed by $Author: florian $ |
|
40 | // \author Last changed by $Author: florian $ | |
41 | // \date 2006-10 |
|
41 | // \date 2006-10 | |
42 | */ |
|
42 | */ | |
43 | //---------------------------------------------------------------------------------- |
|
43 | //---------------------------------------------------------------------------------- | |
44 |
|
44 | |||
45 | /*! |
|
45 | /*! | |
46 | \if USE_GLOBAL_DOXYGEN_DOC |
|
46 | \if USE_GLOBAL_DOXYGEN_DOC | |
47 | \page PythonQtPage PythonQt Overview |
|
47 | \page PythonQtPage PythonQt Overview | |
48 | \else |
|
48 | \else | |
49 | \mainpage PythonQt Overview |
|
49 | \mainpage PythonQt Overview | |
50 | \endif |
|
50 | \endif | |
51 |
|
51 | |||
52 | \section Introduction |
|
52 | \section Introduction | |
53 |
|
53 | |||
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.trolltech.com). | |
55 |
It offers an easy way to embed |
|
55 | It offers an easy way to embed the Python scripting language into | |
56 | your Qt applications. It makes heavy use of the QMetaObject system and thus requires Qt4.x. |
|
56 | your Qt applications. It makes heavy use of the QMetaObject system and thus requires Qt4.x. | |
57 |
|
57 | |||
58 | In contrast to <a href="http://www.riverbankcomputing.co.uk/pyqt/">PyQt</a> , PythonQt is \b not a complete |
|
58 | In contrast to <a href="http://www.riverbankcomputing.co.uk/pyqt/">PyQt</a> , PythonQt is \b not a complete | |
59 | Python wrapper around the complete Qt functionality. So if you are looking for a way to |
|
59 | Python wrapper around the complete Qt functionality. So if you are looking for a way to | |
60 | write complete applications in Python using the Qt GUI, you should use PyQt. |
|
60 | write complete applications in Python using the Qt GUI, you should use PyQt. | |
61 |
|
61 | |||
62 |
If you are looking for a simple way to embed |
|
62 | If you are looking for a simple way to embed Python objects into your C++/Qt Application | |
63 | and to script parts of your application via Python, PythonQt is the way to go! |
|
63 | and to script parts of your application via Python, PythonQt is the way to go! | |
64 |
|
64 | |||
65 |
PythonQt is a stable library that was developed to make the |
|
65 | PythonQt is a stable library that was developed to make the | |
|
66 | Image Processing and Visualization platform MeVisLab (http://www.mevislab.de) | |||
66 | scriptable from Python. |
|
67 | scriptable from Python. | |
67 |
|
68 | |||
68 | \section Licensing |
|
69 | \section Licensing | |
69 |
|
70 | |||
70 | PythonQt is distributed under the LGPL license. |
|
71 | PythonQt is distributed under the LGPL license. | |
71 |
|
72 | |||
72 | \section Download |
|
73 | \section Download | |
73 |
|
74 | |||
74 | PythonQt is hosted on SourceForge at http://sourceforge.net/projects/pythonqt , you can access it via SVN |
|
75 | PythonQt is hosted on SourceForge at http://sourceforge.net/projects/pythonqt , you can access it via SVN | |
75 | or download a tarball. |
|
76 | or download a tarball. | |
76 |
|
77 | |||
77 | \section Features |
|
78 | \section Features | |
78 |
|
79 | |||
|
80 | - Easy wrapping of Python objects from C++ with smart, reference-counting PythonQtObjectPtr. | |||
|
81 | - Convenient conversions to/from QVariant for PythonQtObjectPtr. | |||
79 | - Access all \b slots, \b properties, children and registered enums of any QObject derived class from Python |
|
82 | - Access all \b slots, \b properties, children and registered enums of any QObject derived class from Python | |
80 | - Connecting Qt Signals to Python functions (both from within Python and from C++) |
|
83 | - Connecting Qt Signals to Python functions (both from within Python and from C++) | |
81 |
- Wrapping of C++ objects (which are not derived from QObject) via PythonQtC |
|
84 | - Wrapping of C++ objects (which are not derived from QObject) via PythonQtCppWrapperFactory | |
82 | - Extending C++ and QObject derived classes with additional slots, static methods and constructors (see Decorators) |
|
85 | - Extending C++ and QObject derived classes with additional slots, static methods and constructors (see Decorators) | |
83 | - StdOut/Err redirection to Qt signals instead of cout |
|
86 | - StdOut/Err redirection to Qt signals instead of cout | |
84 | - Interface for creating your own \c import replacement, so that Python scripts can be e.g. signed/verified before they are executed (PythonQtImportInterface) |
|
87 | - Interface for creating your own \c import replacement, so that Python scripts can be e.g. signed/verified before they are executed (PythonQtImportFileInterface) | |
85 | - Mapping of plain-old-datatypes and ALL QVariant types to and from Python |
|
88 | - Mapping of plain-old-datatypes and ALL QVariant types to and from Python | |
86 | - Support for wrapping of user QVariant types which are registerd via QMetaType |
|
89 | - Support for wrapping of user QVariant types which are registerd via QMetaType | |
87 | - Support for Qt namespace (with all enumerators) |
|
90 | - Support for Qt namespace (with all enumerators) | |
88 | - All PythonQt wrapped objects support the dir() statement, so that you can see easily which attributes a QObject, CPP object or QVariant has |
|
91 | - All PythonQt wrapped objects support the dir() statement, so that you can see easily which attributes a QObject, CPP object or QVariant has | |
89 | - No preprocessing/wrapping tool needs to be started, PythonQt can script any QObject without prior knowledge about it (except for the MetaObject information from the \b moc) |
|
92 | - No preprocessing/wrapping tool needs to be started, PythonQt can script any QObject without prior knowledge about it (except for the MetaObject information from the \b moc) | |
90 |
|
93 | |||
91 | \section Non-Features |
|
94 | \section Non-Features | |
92 |
|
95 | |||
93 | Features that PythonQt does NOT support (and will not support): |
|
96 | Features that PythonQt does NOT support (and will not support): | |
94 |
|
97 | |||
95 | - you can not derive from QObjects inside of Python, this would require wrapper generation like PyQt does |
|
98 | - you can not derive from QObjects inside of Python, this would require wrapper generation like PyQt does | |
96 |
- you can only script QObject derived classes, for normal C++ classes you need to create a PythonQtC |
|
99 | - you can only script QObject derived classes, for normal C++ classes you need to create a PythonQtCppWrapperFactory and adequate wrapper classes or add decorator slots | |
97 | - you can not access normal member functions of QObjects, only slots and properties, because the \b moc does not store normal member functions in the MetaObject system |
|
100 | - you can not access normal member functions of QObjects, only slots and properties, because the \b moc does not store normal member functions in the MetaObject system | |
98 |
|
101 | |||
99 | \section Interface |
|
102 | \section Interface | |
100 |
|
103 | |||
101 | The main interface to PythonQt is the PythonQt singleton. |
|
104 | The main interface to PythonQt is the PythonQt singleton. | |
102 | PythonQt needs to be initialized via PythonQt::init() once. |
|
105 | PythonQt needs to be initialized via PythonQt::init() once. | |
103 | Afterwards you communicate with the singleton via PythonQt::self(). |
|
106 | Afterwards you communicate with the singleton via PythonQt::self(). | |
104 | PythonQt offers a default binding for the complete QWidget set, which |
|
107 | PythonQt offers a default binding for the complete QWidget set, which | |
105 | needs to be enabled via PythonQtGui::init(). |
|
108 | needs to be enabled via PythonQtGui::init(). | |
106 |
|
109 | |||
107 |
|
110 | |||
108 | \section Datatype Datatype Mapping |
|
111 | \section Datatype Datatype Mapping | |
109 |
|
112 | |||
110 | The following table shows the mapping between Python and Qt objects: |
|
113 | The following table shows the mapping between Python and Qt objects: | |
111 | <table> |
|
114 | <table> | |
112 | <tr><th>Qt/C++</th><th>Python</th></tr> |
|
115 | <tr><th>Qt/C++</th><th>Python</th></tr> | |
113 | <tr><td>bool</td><td>bool</td></tr> |
|
116 | <tr><td>bool</td><td>bool</td></tr> | |
114 | <tr><td>double</td><td>float</td></tr> |
|
117 | <tr><td>double</td><td>float</td></tr> | |
115 | <tr><td>float</td><td>float</td></tr> |
|
118 | <tr><td>float</td><td>float</td></tr> | |
116 | <tr><td>char/uchar,int/uint,short,ushort,QChar</td><td>integer</td></tr> |
|
119 | <tr><td>char/uchar,int/uint,short,ushort,QChar</td><td>integer</td></tr> | |
117 | <tr><td>long</td><td>integer</td></tr> |
|
120 | <tr><td>long</td><td>integer</td></tr> | |
118 | <tr><td>ulong,longlong,ulonglong</td><td>long</td></tr> |
|
121 | <tr><td>ulong,longlong,ulonglong</td><td>long</td></tr> | |
119 | <tr><td>QString</td><td>unicode string</td></tr> |
|
122 | <tr><td>QString</td><td>unicode string</td></tr> | |
120 | <tr><td>QByteArray</td><td>str</td></tr> |
|
123 | <tr><td>QByteArray</td><td>str</td></tr> | |
121 | <tr><td>char*</td><td>str</td></tr> |
|
124 | <tr><td>char*</td><td>str</td></tr> | |
122 | <tr><td>QStringList</td><td>tuple of unicode strings</td></tr> |
|
125 | <tr><td>QStringList</td><td>tuple of unicode strings</td></tr> | |
123 | <tr><td>QVariantList</td><td>tuple of objects</td></tr> |
|
126 | <tr><td>QVariantList</td><td>tuple of objects</td></tr> | |
124 | <tr><td>QVariantMap</td><td>dict of objects</td></tr> |
|
127 | <tr><td>QVariantMap</td><td>dict of objects</td></tr> | |
125 | <tr><td>QVariant</td><td>depends on type, see below</td></tr> |
|
128 | <tr><td>QVariant</td><td>depends on type, see below</td></tr> | |
126 | <tr><td>QSize, QRect and all other standard Qt QVariants</td><td>variant wrapper that supports complete API of the respective Qt classes</td></tr> |
|
129 | <tr><td>QSize, QRect and all other standard Qt QVariants</td><td>variant wrapper that supports complete API of the respective Qt classes</td></tr> | |
127 | <tr><td>OwnRegisteredMetaType</td><td>variant wrapper, optionally with a wrapper provided by addVariantWrapper()</td></tr> |
|
130 | <tr><td>OwnRegisteredMetaType</td><td>variant wrapper, optionally with a wrapper provided by addVariantWrapper()</td></tr> | |
128 | <tr><td>EnumType</td><td>integer (all enums that are known via the moc and the Qt namespace are supported)</td></tr> |
|
131 | <tr><td>EnumType</td><td>integer (all enums that are known via the moc and the Qt namespace are supported)</td></tr> | |
129 | <tr><td>QObject (and derived classes)</td><td>QObject wrapper</td></tr> |
|
132 | <tr><td>QObject (and derived classes)</td><td>QObject wrapper</td></tr> | |
130 |
<tr><td>C++ object</td><td>CPP wrapper, either wrapped via PythonQtC |
|
133 | <tr><td>C++ object</td><td>CPP wrapper, either wrapped via PythonQtCppWrapperFactory or just decorated with decorators</td></tr> | |
131 | <tr><td>PyObject</td><td>PyObject</td></tr> |
|
134 | <tr><td>PyObject</td><td>PyObject</td></tr> | |
132 | </table> |
|
135 | </table> | |
133 |
|
136 | |||
134 | PyObject is passed as simple pointer, which allows to pass/return any Python Object directly to/from |
|
137 | PyObject is passed as simple pointer, which allows to pass/return any Python Object directly to/from | |
135 | a Qt slot. |
|
138 | a Qt slot. | |
136 | QVariants are mapped recursively as given above, e.g. a dictionary can |
|
139 | QVariants are mapped recursively as given above, e.g. a dictionary can | |
137 | contain lists of dictionaries of doubles. |
|
140 | contain lists of dictionaries of doubles. | |
138 | For example a QVariant of type "String" is mapped to a python unicode string. |
|
141 | For example a QVariant of type "String" is mapped to a python unicode string. | |
139 | All Qt QVariant types are implemented, PythonQt supports the complete Qt API for these object. |
|
142 | All Qt QVariant types are implemented, PythonQt supports the complete Qt API for these object. | |
140 |
|
143 | |||
141 | \section QObject QObject Wrapping |
|
144 | \section QObject QObject Wrapping | |
142 |
|
145 | |||
143 | All classes derived from QObject are automatically wrapped with a python wrapper class |
|
146 | All classes derived from QObject are automatically wrapped with a python wrapper class | |
144 | when they become visible to the Python interpreter. This can happen via |
|
147 | when they become visible to the Python interpreter. This can happen via | |
145 | - the PythonQt::addObject() method |
|
148 | - the PythonQt::addObject() method | |
146 | - when a Qt \b slot returns a QObject derived object to python |
|
149 | - when a Qt \b slot returns a QObject derived object to python | |
147 | - when a Qt \b signal contains a QObject and is connected to a python function |
|
150 | - when a Qt \b signal contains a QObject and is connected to a python function | |
148 |
|
151 | |||
149 | It is important that you call PythonQt::registerClass() for any QObject derived class |
|
152 | It is important that you call PythonQt::registerClass() for any QObject derived class | |
150 | that may become visible to Python, except when you add it via PythonQt::addObject(). |
|
153 | that may become visible to Python, except when you add it via PythonQt::addObject(). | |
151 | This will register the complete parent hierachy of the registered class, so that |
|
154 | This will register the complete parent hierachy of the registered class, so that | |
152 | when you register e.g. a QPushButton, QWidget will be registered as well (and all intermediate |
|
155 | when you register e.g. a QPushButton, QWidget will be registered as well (and all intermediate | |
153 | parents). |
|
156 | parents). | |
154 |
|
157 | |||
155 | From Python, you can talk to the returned QObjects in a natural way by calling |
|
158 | From Python, you can talk to the returned QObjects in a natural way by calling | |
156 | their slots and receiving the return values. You can also read/write all |
|
159 | their slots and receiving the return values. You can also read/write all | |
157 | properties of the objects as if they where normal python properties. |
|
160 | properties of the objects as if they where normal python properties. | |
158 |
|
161 | |||
159 | In addition to this, the wrapped objects support |
|
162 | In addition to this, the wrapped objects support | |
160 | - className() - returns a string that reprents the classname of the QObject |
|
163 | - className() - returns a string that reprents the classname of the QObject | |
161 | - help() - shows all properties, slots, enums, decorator slots and constructors of the object, in a printable form |
|
164 | - help() - shows all properties, slots, enums, decorator slots and constructors of the object, in a printable form | |
162 | - connect(signal, function) - connect the signal of the given object to a python function |
|
165 | - connect(signal, function) - connect the signal of the given object to a python function | |
163 | - connect(signal, qobject, slot) - connect the signal of the given object to a slot of another QObject |
|
166 | - connect(signal, qobject, slot) - connect the signal of the given object to a slot of another QObject | |
164 | - disconnect(signal, function) - disconnect the signal of the given object from a python function |
|
167 | - disconnect(signal, function) - disconnect the signal of the given object from a python function | |
165 | - disconnect(signal, qobject, slot) - disconnect the signal of the given object from a slot of another QObject |
|
168 | - disconnect(signal, qobject, slot) - disconnect the signal of the given object from a slot of another QObject | |
166 | - children() - returns the children of the object |
|
169 | - children() - returns the children of the object | |
167 | - setParent(QObject) - set the parent |
|
170 | - setParent(QObject) - set the parent | |
168 | - QObject* parent() - get the parent |
|
171 | - QObject* parent() - get the parent | |
169 |
|
172 | |||
170 | The below example shows how to connect signals in Python: |
|
173 | The below example shows how to connect signals in Python: | |
171 |
|
174 | |||
172 | \code |
|
175 | \code | |
173 | # define a signal handler function |
|
176 | # define a signal handler function | |
174 | def someFunction(flag): |
|
177 | def someFunction(flag): | |
175 | print flag |
|
178 | print flag | |
176 |
|
179 | |||
177 | # button1 is a QPushButton that has been added to Python via addObject() |
|
180 | # button1 is a QPushButton that has been added to Python via addObject() | |
178 | # connect the clicked signal to a python function: |
|
181 | # connect the clicked signal to a python function: | |
179 | button1.connect("clicked(bool)", someFunction) |
|
182 | button1.connect("clicked(bool)", someFunction) | |
180 |
|
183 | |||
181 | \endcode |
|
184 | \endcode | |
182 |
|
185 | |||
183 | \section CPP CPP Wrapping |
|
186 | \section CPP CPP Wrapping | |
184 |
|
187 | |||
185 |
You can create dedicated wrapper QObject for any C++ class. This is done by deriving from PythonQtC |
|
188 | You can create dedicated wrapper QObject for any C++ class. This is done by deriving from PythonQtCppWrapperFactory | |
186 | and adding your factory via addWrapperFactory(). Whenever PythonQt encounters a CPP pointer (e.g. on a slot or signal) |
|
189 | and adding your factory via addWrapperFactory(). | |
|
190 | Whenever PythonQt encounters a CPP pointer (e.g. on a slot or signal) | |||
187 | and it does not known it as a QObject derived class, it will create a generic CPP wrapper. So even unknown C++ objects |
|
191 | and it does not known it as a QObject derived class, it will create a generic CPP wrapper. So even unknown C++ objects | |
188 | can be passed through Python. If the wrapper factory supports the CPP class, a QObject wrapper will be created for each |
|
192 | can be passed through Python. If the wrapper factory supports the CPP class, a QObject wrapper will be created for each | |
189 | instance that enters Python. An alternative to a complete wrapper via the wrapper factory are decorators, see \ref Decorators |
|
193 | instance that enters Python. An alternative to a complete wrapper via the wrapper factory are decorators, see \ref Decorators | |
190 |
|
194 | |||
191 | \section MetaObject Meta Object/Class access |
|
195 | \section MetaObject Meta Object/Class access | |
192 |
|
196 | |||
193 | For each known CPP class, QObject derived class and QVariant type, PythonQt provides a Meta class. These meta classes are visible |
|
197 | For each known CPP class, QObject derived class and QVariant type, PythonQt provides a Meta class. These meta classes are visible | |
194 | inside of the "PythonQt" python module. |
|
198 | inside of the "PythonQt" python module. | |
195 |
|
199 | |||
196 | A Meta class supports: |
|
200 | A Meta class supports: | |
197 |
|
201 | |||
198 | - access to all declared enum values |
|
202 | - access to all declared enum values | |
199 | - constructors |
|
203 | - constructors | |
200 | - static decorator slots |
|
204 | - static decorator slots | |
201 | - help() and className() |
|
205 | - help() and className() | |
202 |
|
206 | |||
203 | From within Python, you can import the module "PythonQt" to access these meta objects and the Qt namespace. |
|
207 | From within Python, you can import the module "PythonQt" to access these meta objects and the Qt namespace. | |
204 |
|
208 | |||
205 | \code |
|
209 | \code | |
206 | from PythonQt import * |
|
210 | from PythonQt import * | |
207 |
|
211 | |||
208 | # namespace access: |
|
212 | # namespace access: | |
209 | print Qt.AlignLeft |
|
213 | print Qt.AlignLeft | |
210 |
|
214 | |||
211 | # constructors |
|
215 | # constructors | |
212 | a = QSize(12,13) |
|
216 | a = QSize(12,13) | |
213 | b = QFont() |
|
217 | b = QFont() | |
214 |
|
218 | |||
215 | # static method |
|
219 | # static method | |
216 | QDate.currentDate() |
|
220 | QDate.currentDate() | |
217 |
|
221 | |||
218 | # enum value |
|
222 | # enum value | |
219 | QFont.UltraCondensed |
|
223 | QFont.UltraCondensed | |
220 |
|
224 | |||
221 | \endcode |
|
225 | \endcode | |
222 |
|
226 | |||
223 | \section Decorators Decorator slots |
|
227 | \section Decorators Decorator slots | |
224 |
|
228 | |||
225 | PythonQt introduces a new generic approach to extend any wrapped QObject or CPP object with |
|
229 | PythonQt introduces a new generic approach to extend any wrapped QObject or CPP object with | |
226 |
|
230 | |||
227 | - constructors |
|
231 | - constructors | |
228 | - destructors (for CPP objects) |
|
232 | - destructors (for CPP objects) | |
229 | - additional slots |
|
233 | - additional slots | |
230 | - static slots (callable on both the Meta object and the instances) |
|
234 | - static slots (callable on both the Meta object and the instances) | |
231 |
|
235 | |||
232 | The idea behind decorators is that we wanted to make it as easy as possible to extend |
|
236 | The idea behind decorators is that we wanted to make it as easy as possible to extend | |
233 | wrapped objects. Since we already have an implementation for invoking any Qt Slot from |
|
237 | wrapped objects. Since we already have an implementation for invoking any Qt Slot from | |
234 | Python, it looked promising to use this approach for the extension of wrapped objects as well. |
|
238 | Python, it looked promising to use this approach for the extension of wrapped objects as well. | |
235 | This avoids that the PythonQt user needs to care about how Python arguments are mapped from/to |
|
239 | This avoids that the PythonQt user needs to care about how Python arguments are mapped from/to | |
236 | Qt when he wants to create static methods, constructors and additional member functions. |
|
240 | Qt when he wants to create static methods, constructors and additional member functions. | |
237 |
|
241 | |||
238 | The basic idea about decorators is to create a QObject derived class that implements slots |
|
242 | The basic idea about decorators is to create a QObject derived class that implements slots | |
239 | which take one of the above roles (e.g. constructor, destructor etc.) via a naming convention. |
|
243 | which take one of the above roles (e.g. constructor, destructor etc.) via a naming convention. | |
240 | These slots are then assigned to other classes via the naming convention. |
|
244 | These slots are then assigned to other classes via the naming convention. | |
241 |
|
245 | |||
242 | - QVariant new_SomeClassName(...) - defines a constructor for "SomeClassName" that returns a QVariant |
|
246 | - QVariant new_SomeClassName(...) - defines a constructor for "SomeClassName" that returns a QVariant | |
243 | - SomeClassName* new_SomeClassName(...) - defines a constructor for "SomeClassName" that returns a new object of type SomeClassName (where SomeClassName can be any CPP class, not just QObject classes) |
|
247 | - SomeClassName* new_SomeClassName(...) - defines a constructor for "SomeClassName" that returns a new object of type SomeClassName (where SomeClassName can be any CPP class, not just QObject classes) | |
244 | - void delete_SomeClassName(SomeClassName* o) - defines a destructor, which should delete the passed in object o |
|
248 | - void delete_SomeClassName(SomeClassName* o) - defines a destructor, which should delete the passed in object o | |
245 | - anything static_SomeClassName_someMethodName(...) - defines a static method that is callable on instances and the meta class |
|
249 | - anything static_SomeClassName_someMethodName(...) - defines a static method that is callable on instances and the meta class | |
246 | - anything someMethodName(SomeClassName* o, ...) - defines a slot that will be available on SomeClassName instances (and derived instances). When such a slot is called the first argument is the pointer to the instance and the rest of the arguments can be used to make a call on the instance. |
|
250 | - anything someMethodName(SomeClassName* o, ...) - defines a slot that will be available on SomeClassName instances (and derived instances). When such a slot is called the first argument is the pointer to the instance and the rest of the arguments can be used to make a call on the instance. | |
247 |
|
251 | |||
248 | The below example shows all kinds of decorators in action: |
|
252 | The below example shows all kinds of decorators in action: | |
249 |
|
253 | |||
250 | \code |
|
254 | \code | |
251 |
|
255 | |||
252 | // an example CPP object |
|
256 | // an example CPP object | |
253 | class YourCPPObject { |
|
257 | class YourCPPObject { | |
254 | public: |
|
258 | public: | |
255 | YourCPPObject(int arg1, float arg2) { a = arg1; b = arg2; } |
|
259 | YourCPPObject(int arg1, float arg2) { a = arg1; b = arg2; } | |
256 |
|
260 | |||
257 | float doSomething(int arg1) { return arg1*a*b; }; |
|
261 | float doSomething(int arg1) { return arg1*a*b; }; | |
258 |
|
262 | |||
259 | private: |
|
263 | private: | |
260 |
|
264 | |||
261 | int a; |
|
265 | int a; | |
262 | float b; |
|
266 | float b; | |
263 | }; |
|
267 | }; | |
264 |
|
268 | |||
265 | // an example decorator |
|
269 | // an example decorator | |
266 | class ExampleDecorator : public QObject |
|
270 | class ExampleDecorator : public QObject | |
267 | { |
|
271 | { | |
268 | Q_OBJECT |
|
272 | Q_OBJECT | |
269 |
|
273 | |||
270 | public slots: |
|
274 | public slots: | |
271 | // add a constructor to QSize variant that takes a QPoint |
|
275 | // add a constructor to QSize variant that takes a QPoint | |
272 | QVariant new_QSize(const QPoint& p) { return QSize(p.x(), p.y()); } |
|
276 | QVariant new_QSize(const QPoint& p) { return QSize(p.x(), p.y()); } | |
273 |
|
277 | |||
274 | // add a constructor for QPushButton that takes a text and a parent widget |
|
278 | // add a constructor for QPushButton that takes a text and a parent widget | |
275 | QPushButton* new_QPushButton(const QString& text, QWidget* parent=NULL) { return new QPushButton(text, parent); } |
|
279 | QPushButton* new_QPushButton(const QString& text, QWidget* parent=NULL) { return new QPushButton(text, parent); } | |
276 |
|
280 | |||
277 | // add a constructor for a CPP object |
|
281 | // add a constructor for a CPP object | |
278 | YourCPPObject* new_YourCPPObject(int arg1, float arg2) { return new YourCPPObject(arg1, arg2); } |
|
282 | YourCPPObject* new_YourCPPObject(int arg1, float arg2) { return new YourCPPObject(arg1, arg2); } | |
279 |
|
283 | |||
280 | // add a destructor for a CPP object |
|
284 | // add a destructor for a CPP object | |
281 | void delete_YourCPPObject(YourCPPObject* obj) { delete obj; } |
|
285 | void delete_YourCPPObject(YourCPPObject* obj) { delete obj; } | |
282 |
|
286 | |||
283 | // add a static method to QWidget |
|
287 | // add a static method to QWidget | |
284 | QWidget* static_QWidget_mouseGrabber() { return QWidget::mouseGrabber(); } |
|
288 | QWidget* static_QWidget_mouseGrabber() { return QWidget::mouseGrabber(); } | |
285 |
|
289 | |||
286 | // add an additional slot to QWidget (make move() callable, which is not declared as a slot in QWidget) |
|
290 | // add an additional slot to QWidget (make move() callable, which is not declared as a slot in QWidget) | |
287 | void move(QWidget* w, const QPoint& p) { w->move(p); } |
|
291 | void move(QWidget* w, const QPoint& p) { w->move(p); } | |
288 |
|
292 | |||
289 | // add an additional slot to QWidget, overloading the above move method |
|
293 | // add an additional slot to QWidget, overloading the above move method | |
290 | void move(QWidget* w, int x, int y) { w->move(x,y); } |
|
294 | void move(QWidget* w, int x, int y) { w->move(x,y); } | |
291 |
|
295 | |||
292 | // add a method to your own CPP object |
|
296 | // add a method to your own CPP object | |
293 | int doSomething(YourCPPObject* obj, int arg1) { return obj->doSomething(arg1); } |
|
297 | int doSomething(YourCPPObject* obj, int arg1) { return obj->doSomething(arg1); } | |
294 | }; |
|
298 | }; | |
295 |
|
299 | |||
296 | ... |
|
300 | ... | |
297 |
|
301 | |||
298 | PythonQt::self()->addDecorators(new ExampleDecorator()); |
|
302 | PythonQt::self()->addDecorators(new ExampleDecorator()); | |
299 | PythonQt::self()->registerClass(&QPushButton::staticMetaObject); |
|
303 | PythonQt::self()->registerClass(&QPushButton::staticMetaObject); | |
300 | PythonQt::self()->registerCPPClassNames(QStringList() << "YourCPPObject"); |
|
304 | PythonQt::self()->registerCPPClassNames(QStringList() << "YourCPPObject"); | |
301 |
|
305 | |||
302 | \endcode |
|
306 | \endcode | |
303 |
|
307 | |||
304 | After you have registered an instance of the above ExampleDecorator, you can do the following from Python |
|
308 | After you have registered an instance of the above ExampleDecorator, you can do the following from Python | |
305 | (all these calls are mapped to the above decorator slots): |
|
309 | (all these calls are mapped to the above decorator slots): | |
306 |
|
310 | |||
307 | \code |
|
311 | \code | |
308 | from PythonQt import * |
|
312 | from PythonQt import * | |
309 |
|
313 | |||
310 | # call our new constructor of QSize |
|
314 | # call our new constructor of QSize | |
311 | size = QSize(QPoint(1,2)); |
|
315 | size = QSize(QPoint(1,2)); | |
312 |
|
316 | |||
313 | # call our new QPushButton constructor |
|
317 | # call our new QPushButton constructor | |
314 | button = QPushButton("sometext"); |
|
318 | button = QPushButton("sometext"); | |
315 |
|
319 | |||
316 | # call the move slot (overload1) |
|
320 | # call the move slot (overload1) | |
317 | button.move(QPoint(0,0)) |
|
321 | button.move(QPoint(0,0)) | |
318 |
|
322 | |||
319 | # call the move slot (overload2) |
|
323 | # call the move slot (overload2) | |
320 | button.move(0,0) |
|
324 | button.move(0,0) | |
321 |
|
325 | |||
322 | # call the static method |
|
326 | # call the static method | |
323 | grabber = QWidget.mouseWrapper(); |
|
327 | grabber = QWidget.mouseWrapper(); | |
324 |
|
328 | |||
325 | # create a CPP object via constructor |
|
329 | # create a CPP object via constructor | |
326 | yourCpp = YourCPPObject(1,11.5) |
|
330 | yourCpp = YourCPPObject(1,11.5) | |
327 |
|
331 | |||
328 | # call the wrapped method on CPP object |
|
332 | # call the wrapped method on CPP object | |
329 | print yourCpp.doSomething(1); |
|
333 | print yourCpp.doSomething(1); | |
330 |
|
334 | |||
331 | # destructor will be called: |
|
335 | # destructor will be called: | |
332 | yourCpp = None |
|
336 | yourCpp = None | |
333 |
|
337 | |||
334 | \endcode |
|
338 | \endcode | |
335 |
|
339 | |||
336 | \section Building |
|
340 | \section Building | |
337 |
|
341 | |||
338 | 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 or 2.5 on Windows, Linux and MacOS X. | |
339 | To compile PythonQt, you will need a python developer installation which includes Python's header files and |
|
343 | To compile PythonQt, you will need a python developer installation which includes Python's header files and | |
340 | the python2x.[lib | dll | so | dynlib]. |
|
344 | the python2x.[lib | dll | so | dynlib]. | |
341 | The build scripts a currently set to use Python 2.5. |
|
345 | The build scripts a currently set to use Python 2.5. | |
342 | You may need to tweak the \b build/python.prf file to set the correct Python includes and libs on your system. |
|
346 | You may need to tweak the \b build/python.prf file to set the correct Python includes and libs on your system. | |
343 |
|
347 | |||
344 | \subsection Windows |
|
348 | \subsection Windows | |
345 |
|
349 | |||
346 | On Windows, the (non-source) Python Windows installer can be used. |
|
350 | On Windows, the (non-source) Python Windows installer can be used. | |
347 | Make sure that you use the same compiler, the current Python distribution is built |
|
351 | Make sure that you use the same compiler, the current Python distribution is built | |
348 | with Visual Studio 2003. If you want to use another compiler, you will need to build |
|
352 | with Visual Studio 2003. If you want to use another compiler, you will need to build | |
349 | Python yourself, using your compiler. |
|
353 | Python yourself, using your compiler. | |
350 |
|
354 | |||
351 | To build PythonQt, you need to set the environment variable \b PYTHON_PATH to point to the root |
|
355 | To build PythonQt, you need to set the environment variable \b PYTHON_PATH to point to the root | |
352 | dir of the python installation and \b PYTHON_LIB to point to |
|
356 | dir of the python installation and \b PYTHON_LIB to point to | |
353 | the directory where the python lib file is located. |
|
357 | the directory where the python lib file is located. | |
354 |
|
358 | |||
355 | When using the prebuild Python installer, this will be: |
|
359 | When using the prebuild Python installer, this will be: | |
356 |
|
360 | |||
357 | \code |
|
361 | \code | |
358 | > set PYTHON_PATH = c:\Python25 |
|
362 | > set PYTHON_PATH = c:\Python25 | |
359 | > set PYTHON_LIB = c:\Python25\libs |
|
363 | > set PYTHON_LIB = c:\Python25\libs | |
360 | \endcode |
|
364 | \endcode | |
361 |
|
365 | |||
362 | When using the python sources, this will be something like: |
|
366 | When using the python sources, this will be something like: | |
363 |
|
367 | |||
364 | \code |
|
368 | \code | |
365 | > set PYTHON_PATH = c:\yourDir\Python-2.5.1\ |
|
369 | > set PYTHON_PATH = c:\yourDir\Python-2.5.1\ | |
366 | > set PYTHON_LIB = c:\yourDir\Python-2.5.1\PCbuild8\Win32 |
|
370 | > set PYTHON_LIB = c:\yourDir\Python-2.5.1\PCbuild8\Win32 | |
367 | \endcode |
|
371 | \endcode | |
368 |
|
372 | |||
369 | To build all, do the following (after setting the above variables): |
|
373 | To build all, do the following (after setting the above variables): | |
370 |
|
374 | |||
371 | \code |
|
375 | \code | |
372 | > cd PythonQtRoot |
|
376 | > cd PythonQtRoot | |
373 | > vcvars32 |
|
377 | > vcvars32 | |
374 | > qmake |
|
378 | > qmake | |
375 | > nmake |
|
379 | > nmake | |
376 | \endcode |
|
380 | \endcode | |
377 |
|
381 | |||
378 | This should build everything. If Python can not be linked or include files can not be found, |
|
382 | This should build everything. If Python can not be linked or include files can not be found, | |
379 | you probably need to tweak \b build/python.prf |
|
383 | you probably need to tweak \b build/python.prf | |
380 |
|
384 | |||
381 | The tests and examples are located in PythonQt/lib. |
|
385 | The tests and examples are located in PythonQt/lib. | |
382 |
|
386 | |||
383 | \subsection Linux |
|
387 | \subsection Linux | |
384 |
|
388 | |||
385 | On Linux, you need to install a Python-dev package. |
|
389 | On Linux, you need to install a Python-dev package. | |
386 | If Python can not be linked or include files can not be found, |
|
390 | If Python can not be linked or include files can not be found, | |
387 | you probably need to tweak \b build/python.prf |
|
391 | you probably need to tweak \b build/python.prf | |
388 |
|
392 | |||
389 | To build PythonQt, just do a: |
|
393 | To build PythonQt, just do a: | |
390 |
|
394 | |||
391 | \code |
|
395 | \code | |
392 | > cd PythonQtRoot |
|
396 | > cd PythonQtRoot | |
393 | > qmake |
|
397 | > qmake | |
394 | > make all |
|
398 | > make all | |
395 | \endcode |
|
399 | \endcode | |
396 |
|
400 | |||
397 | The tests and examples are located in PythonQt/lib. |
|
401 | The tests and examples are located in PythonQt/lib. | |
398 | You should add PythonQt/lib to your LD_LIBRARY_PATH so that the runtime |
|
402 | You should add PythonQt/lib to your LD_LIBRARY_PATH so that the runtime | |
399 | linker can find the *.so files. |
|
403 | linker can find the *.so files. | |
400 |
|
404 | |||
401 | \subsection MacOsX |
|
405 | \subsection MacOsX | |
402 |
|
406 | |||
403 | On Mac, Python is installed as a Framework, so you should not need to install it. |
|
407 | On Mac, Python is installed as a Framework, so you should not need to install it. | |
404 | To build PythonQt, just do a: |
|
408 | To build PythonQt, just do a: | |
405 |
|
409 | |||
406 | \code |
|
410 | \code | |
407 | > cd PythonQtRoot |
|
411 | > cd PythonQtRoot | |
408 | > qmake |
|
412 | > qmake | |
409 | > make all |
|
413 | > make all | |
410 | \endcode |
|
414 | \endcode | |
411 |
|
415 | |||
412 | \section Tests |
|
416 | \section Tests | |
413 |
|
417 | |||
414 | There is a unit test that tests most features of PythonQt, see the \b tests subdirectory for details. |
|
418 | There is a unit test that tests most features of PythonQt, see the \b tests subdirectory for details. | |
415 |
|
419 | |||
416 | \section Examples |
|
420 | \section Examples | |
417 |
|
421 | |||
418 | Examples are available in the \b examples directory. The PyScriptingConsole implements a simple |
|
422 | Examples are available in the \b examples directory. The PyScriptingConsole implements a simple | |
419 | interactive scripting console that shows how to script a simple application. |
|
423 | interactive scripting console that shows how to script a simple application. | |
420 |
|
424 | |||
421 | The following shows how to integrate PythonQt into you Qt application: |
|
425 | The following shows how to integrate PythonQt into you Qt application: | |
422 |
|
426 | |||
423 | \code |
|
427 | \code | |
424 | #include "PythonQt.h" |
|
428 | #include "PythonQt.h" | |
425 | #include <QApplication> |
|
429 | #include <QApplication> | |
426 | ... |
|
430 | ... | |
427 |
|
431 | |||
428 | int main( int argc, char **argv ) |
|
432 | int main( int argc, char **argv ) | |
429 | { |
|
433 | { | |
430 |
|
434 | |||
431 | QApplication qapp(argc, argv); |
|
435 | QApplication qapp(argc, argv); | |
432 |
|
436 | |||
433 | // init PythonQt and Python itself |
|
437 | // init PythonQt and Python itself | |
434 | PythonQt::init(PythonQt::IgnoreSiteModule | PythonQt::RedirectStdOut); |
|
438 | PythonQt::init(PythonQt::IgnoreSiteModule | PythonQt::RedirectStdOut); | |
435 |
|
439 | |||
436 | // get a smart pointer to the __main__ module of the Python interpreter |
|
440 | // get a smart pointer to the __main__ module of the Python interpreter | |
437 | PythonQtObjectPtr mainContext = PythonQt::self()->getMainModule(); |
|
441 | PythonQtObjectPtr mainContext = PythonQt::self()->getMainModule(); | |
438 |
|
442 | |||
439 | // add a QObject as variable of name "example" to the namespace of the __main__ module |
|
443 | // add a QObject as variable of name "example" to the namespace of the __main__ module | |
440 | PyExampleObject example; |
|
444 | PyExampleObject example; | |
441 | PythonQt::self()->addObject(mainContext, "example", &example); |
|
445 | PythonQt::self()->addObject(mainContext, "example", &example); | |
442 |
|
446 | |||
443 | // register all other QObjects that you want to script and that are returned by your API |
|
447 | // register all other QObjects that you want to script and that are returned by your API | |
444 | PythonQt::self()->registerClass(&QMainWindow::staticMetaObject); |
|
448 | PythonQt::self()->registerClass(&QMainWindow::staticMetaObject); | |
445 | PythonQt::self()->registerClass(&QPushButton::staticMetaObject); |
|
449 | PythonQt::self()->registerClass(&QPushButton::staticMetaObject); | |
446 | ... |
|
450 | ... | |
447 |
|
451 | |||
448 | // do something |
|
452 | // do something | |
449 | PythonQt::self()->runScript(mainContext, "print example\n"); |
|
453 | PythonQt::self()->runScript(mainContext, "print example\n"); | |
450 | PythonQt::self()->runScript(mainContext, "def multiply(a,b):\n return a*b;\n"); |
|
454 | PythonQt::self()->runScript(mainContext, "def multiply(a,b):\n return a*b;\n"); | |
451 | QVariantList args; |
|
455 | QVariantList args; | |
452 | args << 42 << 47; |
|
456 | args << 42 << 47; | |
453 | QVariant result = PythonQt::self()->call(mainContext,"multiply", args); |
|
457 | QVariant result = PythonQt::self()->call(mainContext,"multiply", args); | |
454 | ... |
|
458 | ... | |
455 | \endcode |
|
459 | \endcode | |
456 |
|
460 | |||
457 |
|
461 | |||
458 | \section TODOs |
|
462 | \section TODOs | |
459 |
|
463 | |||
460 | - add more information on how to distribute an application that uses PythonQt, including the Python distribution |
|
464 | - add more information on how to distribute an application that uses PythonQt, including the Python distribution | |
461 |
|
465 | |||
462 | */ |
|
466 | */ |
@@ -1,68 +1,69 | |||||
1 | #ifndef _PYTHONQTIMPORTFILEINTERFACE_H |
|
1 | #ifndef _PYTHONQTIMPORTFILEINTERFACE_H | |
2 | #define _PYTHONQTIMPORTFILEINTERFACE_H |
|
2 | #define _PYTHONQTIMPORTFILEINTERFACE_H | |
3 |
|
3 | |||
4 | /* |
|
4 | /* | |
5 | * |
|
5 | * | |
6 | * Copyright (C) 2006 MeVis Research GmbH All Rights Reserved. |
|
6 | * Copyright (C) 2006 MeVis Research GmbH All Rights Reserved. | |
7 | * |
|
7 | * | |
8 | * This library is free software; you can redistribute it and/or |
|
8 | * This library is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU Lesser General Public |
|
9 | * modify it under the terms of the GNU Lesser General Public | |
10 | * License as published by the Free Software Foundation; either |
|
10 | * License as published by the Free Software Foundation; either | |
11 | * version 2.1 of the License, or (at your option) any later version. |
|
11 | * version 2.1 of the License, or (at your option) any later version. | |
12 | * |
|
12 | * | |
13 | * This library is distributed in the hope that it will be useful, |
|
13 | * This library is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 | * Lesser General Public License for more details. |
|
16 | * Lesser General Public License for more details. | |
17 | * |
|
17 | * | |
18 | * Further, this software is distributed without any warranty that it is |
|
18 | * Further, this software is distributed without any warranty that it is | |
19 | * free of the rightful claim of any third person regarding infringement |
|
19 | * free of the rightful claim of any third person regarding infringement | |
20 | * or the like. Any license provided herein, whether implied or |
|
20 | * or the like. Any license provided herein, whether implied or | |
21 | * otherwise, applies only to this software file. Patent licenses, if |
|
21 | * otherwise, applies only to this software file. Patent licenses, if | |
22 | * any, provided herein do not apply to combinations of this program with |
|
22 | * any, provided herein do not apply to combinations of this program with | |
23 | * other software, or any other product whatsoever. |
|
23 | * other software, or any other product whatsoever. | |
24 | * |
|
24 | * | |
25 | * You should have received a copy of the GNU Lesser General Public |
|
25 | * You should have received a copy of the GNU Lesser General Public | |
26 | * License along with this library; if not, write to the Free Software |
|
26 | * License along with this library; if not, write to the Free Software | |
27 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
27 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
28 | * |
|
28 | * | |
29 | * Contact information: MeVis Research GmbH, Universitaetsallee 29, |
|
29 | * Contact information: MeVis Research GmbH, Universitaetsallee 29, | |
30 | * 28359 Bremen, Germany or: |
|
30 | * 28359 Bremen, Germany or: | |
31 | * |
|
31 | * | |
32 | * http://www.mevis.de |
|
32 | * http://www.mevis.de | |
33 | * |
|
33 | * | |
34 | */ |
|
34 | */ | |
35 |
|
35 | |||
36 | //---------------------------------------------------------------------------------- |
|
36 | //---------------------------------------------------------------------------------- | |
37 | /*! |
|
37 | /*! | |
38 | // \file PythonQtImportFileInterface.h |
|
38 | // \file PythonQtImportFileInterface.h | |
39 | // \author Florian Link |
|
39 | // \author Florian Link | |
40 | // \author Last changed by $Author: florian $ |
|
40 | // \author Last changed by $Author: florian $ | |
41 | // \date 2006-05 |
|
41 | // \date 2006-05 | |
42 | */ |
|
42 | */ | |
43 | //---------------------------------------------------------------------------------- |
|
43 | //---------------------------------------------------------------------------------- | |
44 |
|
44 | |||
45 | #include <QDateTime> |
|
45 | #include <QDateTime> | |
46 | #include <QString> |
|
46 | #include <QString> | |
47 | #include <QByteArray> |
|
47 | #include <QByteArray> | |
48 |
|
48 | |||
49 |
//! |
|
49 | //! Defines an abstract interface to file access for the Python import statement. | |
|
50 | //! see PythonQt::setImporter() | |||
50 | class PythonQtImportFileInterface { |
|
51 | class PythonQtImportFileInterface { | |
51 |
|
52 | |||
52 | public: |
|
53 | public: | |
53 | //! read the given file as byte array, without doing any linefeed translations |
|
54 | //! read the given file as byte array, without doing any linefeed translations | |
54 | virtual QByteArray readFileAsBytes(const QString& filename) = 0; |
|
55 | virtual QByteArray readFileAsBytes(const QString& filename) = 0; | |
55 |
|
56 | |||
56 | //! read a source file, expects a readable Python text file with translated line feeds. |
|
57 | //! read a source file, expects a readable Python text file with translated line feeds. | |
57 | //! If the file can not be load OR it can not be verified, ok is set to false |
|
58 | //! If the file can not be load OR it can not be verified, ok is set to false | |
58 | virtual QByteArray readSourceFile(const QString& filename, bool& ok) = 0; |
|
59 | virtual QByteArray readSourceFile(const QString& filename, bool& ok) = 0; | |
59 |
|
60 | |||
60 | //! returns if the file exists |
|
61 | //! returns if the file exists | |
61 | virtual bool exists(const QString& filename) = 0; |
|
62 | virtual bool exists(const QString& filename) = 0; | |
62 |
|
63 | |||
63 | //! get the last modified data of a file |
|
64 | //! get the last modified data of a file | |
64 | virtual QDateTime lastModifiedDate(const QString& filename) = 0; |
|
65 | virtual QDateTime lastModifiedDate(const QString& filename) = 0; | |
65 |
|
66 | |||
66 | }; |
|
67 | }; | |
67 |
|
68 | |||
68 | #endif No newline at end of file |
|
69 | #endif |
General Comments 0
You need to be logged in to leave comments.
Login now