diff --git a/playground/qt5-and-pyqt5/pyqt5/res/test.txt b/playground/qt5-and-pyqt5/pyqt5/res/test.txt
new file mode 100644
index 00000000..9b227d91
--- /dev/null
+++ b/playground/qt5-and-pyqt5/pyqt5/res/test.txt
@@ -0,0 +1,2 @@
+change me to see qrc dependencies!
+
diff --git a/playground/qt5-and-pyqt5/pyqt5/sampleRes.qrc b/playground/qt5-and-pyqt5/pyqt5/sampleRes.qrc
new file mode 100644
index 00000000..687c5100
--- /dev/null
+++ b/playground/qt5-and-pyqt5/pyqt5/sampleRes.qrc
@@ -0,0 +1,5 @@
+
+
+ res/test.txt
+
+
diff --git a/playground/qt5-and-pyqt5/pyqt5/src/firstgui.ui b/playground/qt5-and-pyqt5/pyqt5/src/firstgui.ui
new file mode 100644
index 00000000..cb7f9d30
--- /dev/null
+++ b/playground/qt5-and-pyqt5/pyqt5/src/firstgui.ui
@@ -0,0 +1,130 @@
+
+
+ myfirstgui
+
+
+
+ 0
+ 0
+ 411
+ 247
+
+
+
+ My First Gui!
+
+
+
+
+ 20
+ 210
+ 381
+ 32
+
+
+
+ Qt::Horizontal
+
+
+ QDialogButtonBox::Close
+
+
+
+
+
+ 10
+ 10
+ 101
+ 21
+
+
+
+
+
+
+ 120
+ 10
+ 281
+ 192
+
+
+
+
+
+
+ 10
+ 180
+ 101
+ 23
+
+
+
+ clear
+
+
+
+
+
+ 10
+ 40
+ 101
+ 23
+
+
+
+ add
+
+
+
+
+
+
+ buttonBox
+ accepted()
+ myfirstgui
+ accept()
+
+
+ 258
+ 274
+
+
+ 157
+ 274
+
+
+
+
+ buttonBox
+ rejected()
+ myfirstgui
+ reject()
+
+
+ 316
+ 260
+
+
+ 286
+ 274
+
+
+
+
+ clearBtn
+ clicked()
+ listWidget
+ clear()
+
+
+ 177
+ 253
+
+
+ 177
+ 174
+
+
+
+
+
diff --git a/playground/qt5-and-pyqt5/pyqt5/src/sample.py b/playground/qt5-and-pyqt5/pyqt5/src/sample.py
new file mode 100644
index 00000000..80335e7c
--- /dev/null
+++ b/playground/qt5-and-pyqt5/pyqt5/src/sample.py
@@ -0,0 +1,24 @@
+import sys
+from PyQt5 import QtCore, QtGui, QtWidgets
+from firstgui import Ui_myfirstgui
+
+class MyFirstGuiProgram(Ui_myfirstgui):
+ def __init__(self, dialog):
+ Ui_myfirstgui.__init__(self)
+ self.setupUi(dialog)
+
+ # Connect "add" button with a custom function (addInputTextToListbox)
+ self.addBtn.clicked.connect(self.addInputTextToListbox)
+
+ def addInputTextToListbox(self):
+ txt = self.myTextInput.text()
+ self.listWidget.addItem(txt)
+
+if __name__ == '__main__':
+ app = QtWidgets.QApplication(sys.argv)
+ dialog = QtWidgets.QDialog()
+
+ prog = MyFirstGuiProgram(dialog)
+
+ dialog.show()
+ sys.exit(app.exec_())
diff --git a/playground/qt5-and-pyqt5/pyqt5/wscript b/playground/qt5-and-pyqt5/pyqt5/wscript
new file mode 100644
index 00000000..8a5379be
--- /dev/null
+++ b/playground/qt5-and-pyqt5/pyqt5/wscript
@@ -0,0 +1,29 @@
+#! /usr/bin/env python
+# encoding: utf-8#
+# Federico Pellegrin, 2016 (fedepell)
+
+"""
+Python QT5 helper tools example:
+converts QT5 Designer tools files (UI and QRC) into python files with
+the appropriate tools (pyqt5 and pyside2 searched) and manages their
+python compilation and installation using standard python waf Tool
+
+"""
+def options(opt):
+ # Load also python to demonstrate mixed calls
+ opt.load('python pyqt5')
+
+def configure(conf):
+ # Load also python to demonstrate mixed calls
+ conf.load('python pyqt5')
+ conf.check_python_version((2,7,4))
+
+def build(bld):
+ # Demostrates mixed usage of py and pyqt5 module, and tests also install_path and install_from
+ # (since generated files go into build it has to be reset inside the pyqt5 tool)
+ bld(features="py pyqt5", source="src/sample.py src/firstgui.ui", install_path="${PREFIX}/play/", install_from="src/")
+
+ # Simple usage on a resource file. If a file referenced inside the resource changes it will be rebuilt
+ # as the qrc XML is parsed and dependencies are calculated
+ bld(features="pyqt5", source="sampleRes.qrc")
+
diff --git a/playground/qt5-and-pyqt5/qt5/but.ui b/playground/qt5-and-pyqt5/qt5/but.ui
new file mode 100644
index 00000000..40c8c4f2
--- /dev/null
+++ b/playground/qt5-and-pyqt5/qt5/but.ui
@@ -0,0 +1,32 @@
+
+
+ Form
+
+
+
+ 0
+ 0
+ 208
+ 113
+
+
+
+ Form
+
+
+
+
+ 40
+ 30
+ 83
+ 26
+
+
+
+ Hello, world!
+
+
+
+
+
+
diff --git a/playground/qt5-and-pyqt5/qt5/data/some.txt b/playground/qt5-and-pyqt5/qt5/data/some.txt
new file mode 100644
index 00000000..3c58ea34
--- /dev/null
+++ b/playground/qt5-and-pyqt5/qt5/data/some.txt
@@ -0,0 +1 @@
+tada tadam tadadam
diff --git a/playground/qt5-and-pyqt5/qt5/foo.cpp b/playground/qt5-and-pyqt5/qt5/foo.cpp
new file mode 100644
index 00000000..ab5620d6
--- /dev/null
+++ b/playground/qt5-and-pyqt5/qt5/foo.cpp
@@ -0,0 +1,21 @@
+// Thomas Nagy, 2011-2016
+
+#include "foo.h"
+
+Foo::Foo() : QWidget(NULL) {
+
+}
+
+class Bar_private : public QWidget {
+ Q_OBJECT
+ signals:
+ void test();
+ public:
+ Bar_private();
+};
+
+Bar_private::Bar_private() : QWidget(NULL) {
+}
+
+#include "foo.moc"
+
diff --git a/playground/qt5-and-pyqt5/qt5/foo.h b/playground/qt5-and-pyqt5/qt5/foo.h
new file mode 100644
index 00000000..e05b3e99
--- /dev/null
+++ b/playground/qt5-and-pyqt5/qt5/foo.h
@@ -0,0 +1,16 @@
+// Thomas Nagy, 2011-2016
+
+#ifndef _FOO
+#define _FOO
+
+#include
+
+class Foo : public QWidget {
+ Q_OBJECT
+ signals:
+ void test();
+ public:
+ Foo();
+};
+
+#endif
diff --git a/playground/qt5-and-pyqt5/qt5/linguist/fr.ts b/playground/qt5-and-pyqt5/qt5/linguist/fr.ts
new file mode 100644
index 00000000..415c174a
--- /dev/null
+++ b/playground/qt5-and-pyqt5/qt5/linguist/fr.ts
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/playground/qt5-and-pyqt5/qt5/main.cpp b/playground/qt5-and-pyqt5/qt5/main.cpp
new file mode 100644
index 00000000..4f407c6c
--- /dev/null
+++ b/playground/qt5-and-pyqt5/qt5/main.cpp
@@ -0,0 +1,26 @@
+// Thomas Nagy, 2016 (ita)
+
+#include
+//#include
+//#include "mainwindow.h"
+#include "ui_but.h"
+
+int main(int argc, char **argv)
+{
+ Q_INIT_RESOURCE(res);
+ QApplication app(argc, argv);
+ QWidget window;
+ Ui::Form ui;
+ ui.setupUi(&window);
+ window.show();
+ return app.exec();
+/*
+ MainWindow window;
+ if (argc == 2)
+ window.openFile(argv[1]);
+ else
+ window.openFile(":/files/bubbles.svg");
+ window.show();
+ return app.exec();
+*/
+}
diff --git a/playground/qt5-and-pyqt5/qt5/res.qrc b/playground/qt5-and-pyqt5/qt5/res.qrc
new file mode 100644
index 00000000..4cd17c4c
--- /dev/null
+++ b/playground/qt5-and-pyqt5/qt5/res.qrc
@@ -0,0 +1,7 @@
+
+
+
+ ../../../docs/slides/presentation/gfx/waflogo.svg
+
+
+
diff --git a/playground/qt5-and-pyqt5/qt5/wscript b/playground/qt5-and-pyqt5/qt5/wscript
new file mode 100644
index 00000000..5ab374c9
--- /dev/null
+++ b/playground/qt5-and-pyqt5/qt5/wscript
@@ -0,0 +1,34 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# Thomas Nagy, 2016 (ita)
+
+VERSION='0.0.1'
+APPNAME='qt5_test'
+
+top = '.'
+out = 'build'
+
+def options(opt):
+ opt.load('compiler_cxx qt5')
+
+def configure(conf):
+ conf.load('compiler_cxx qt5')
+ #conf.env.append_value('CXXFLAGS', ['-g']) # test
+
+def build(bld):
+ # According to the Qt5 documentation:
+ # Qt classes in foo.h -> declare foo.h as a header to be processed by moc
+ # add the resulting moc_foo.cpp to the source files
+ # Qt classes in foo.cpp -> include foo.moc at the end of foo.cpp
+ #
+ bld(
+ features = 'qt5 cxx cxxprogram',
+ use = 'QT5CORE QT5GUI QT5SVG QT5WIDGETS',
+ source = 'main.cpp res.qrc but.ui foo.cpp',
+ moc = 'foo.h',
+ target = 'window',
+ includes = '.',
+ lang = bld.path.ant_glob('linguist/*.ts'),
+ langname = 'somefile', # include the .qm files from somefile.qrc
+ )
+
diff --git a/playground/qt5-and-pyqt5/qtchainer/qtchainer.py b/playground/qt5-and-pyqt5/qtchainer/qtchainer.py
new file mode 100644
index 00000000..55d4c08b
--- /dev/null
+++ b/playground/qt5-and-pyqt5/qtchainer/qtchainer.py
@@ -0,0 +1,53 @@
+#!/usr/bin/env python
+# encoding: utf-8
+# Federico Pellegrin, 2016 (fedepell)
+
+#
+# Example extra that chains to either qt5 or pyqt5 for QRC/UI files as
+# just one handler for an extension can be natively defined. The extra
+# has to be loaded after qt5 and pyqt5 and files need to have explicitly
+# set the feature they want to use.
+#
+
+import os
+from waflib.Tools import python
+from waflib.Tools import cxx
+from waflib.extras import pyqt5
+from waflib.Tools import qt5
+from waflib import Task
+from waflib.TaskGen import extension
+from waflib import Logs
+
+
+EXT_RCC = ['.qrc']
+"""
+File extension for the resource (.qrc) files
+"""
+
+EXT_UI = ['.ui']
+"""
+File extension for the user interface (.ui) files
+"""
+
+
+@extension(*EXT_RCC)
+def create_chain_task(self, node):
+ "Creates rcc and py task for ``.qrc`` files"
+ if 'qt5' in self.features:
+ qt5.create_rcc_task(self, node)
+ elif 'pyqt5' in self.features:
+ pyqt5.create_pyrcc_task(self, node)
+ else:
+ Logs.warn("No feature explicitly defined for '%s'",node)
+
+
+@extension(*EXT_UI)
+def create_chain_task(self, node):
+ "Create uic tasks and py for user interface ``.ui`` definition files"
+ if 'qt5' in self.features:
+ qt5.create_uic_task(self, node)
+ elif 'pyqt5' in self.features:
+ pyqt5.create_pyuic_task(self, node)
+ else:
+ Logs.warn("No feature explicitly defined for '%s'",node)
+
diff --git a/playground/qt5-and-pyqt5/wscript b/playground/qt5-and-pyqt5/wscript
new file mode 100644
index 00000000..cd679ea9
--- /dev/null
+++ b/playground/qt5-and-pyqt5/wscript
@@ -0,0 +1,28 @@
+#! /usr/bin/env python
+# encoding: utf-8#
+# Federico Pellegrin, 2016 (fedepell)
+
+# Simple example with custom local extra tool to be able to use at the same
+# time both qt5 and Python qt5. Both have a handler to some extensions
+# (qrc/ui) so the last one loaded will overwrite the previous one.
+# The small extra tool will just override the handler and pass to the
+# correct one as needed. Must be loaded after qt5 and pyqt5.
+#
+
+def options(opt):
+ # Load what needed for qt5 and pyqt5 and chainer as *last* so it
+ # will chain to the proper one depending on feature
+ opt.load('compiler_cxx qt5 python pyqt5')
+ opt.load('qtchainer', tooldir='qtchainer')
+
+def configure(conf):
+ conf.load('compiler_cxx qt5 python pyqt5 qtchainer')
+ conf.check_python_version((2,7,4))
+
+def build(bld):
+ # Build both pyqt5 and qt5.
+ # - qt5 is from demos/qt5, just a reference to waflogo.svg has been
+ # fixed as the directory is not one level deeper in this playground
+ # - pyqt5 is from playground/pyqt5
+ bld.recurse("pyqt5 qt5")
+