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") +