Playground sample on how to chain both qt5 tool and pyqt5 extra to use both at the same time in a waf project (#1832)

This commit is contained in:
Federico Pellegrin 2016-10-12 23:53:04 +02:00 committed by ita1024
parent 4bd13de095
commit 4d40e63fc1
15 changed files with 412 additions and 0 deletions

View File

@ -0,0 +1,2 @@
change me to see qrc dependencies!

View File

@ -0,0 +1,5 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file alias="test.txt">res/test.txt</file>
</qresource>
</RCC>

View File

@ -0,0 +1,130 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>myfirstgui</class>
<widget class="QDialog" name="myfirstgui">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>411</width>
<height>247</height>
</rect>
</property>
<property name="windowTitle">
<string>My First Gui!</string>
</property>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="geometry">
<rect>
<x>20</x>
<y>210</y>
<width>381</width>
<height>32</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Close</set>
</property>
</widget>
<widget class="QLineEdit" name="myTextInput">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>101</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QListWidget" name="listWidget">
<property name="geometry">
<rect>
<x>120</x>
<y>10</y>
<width>281</width>
<height>192</height>
</rect>
</property>
</widget>
<widget class="QPushButton" name="clearBtn">
<property name="geometry">
<rect>
<x>10</x>
<y>180</y>
<width>101</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>clear</string>
</property>
</widget>
<widget class="QPushButton" name="addBtn">
<property name="geometry">
<rect>
<x>10</x>
<y>40</y>
<width>101</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>add</string>
</property>
</widget>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>myfirstgui</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>258</x>
<y>274</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>myfirstgui</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>clearBtn</sender>
<signal>clicked()</signal>
<receiver>listWidget</receiver>
<slot>clear()</slot>
<hints>
<hint type="sourcelabel">
<x>177</x>
<y>253</y>
</hint>
<hint type="destinationlabel">
<x>177</x>
<y>174</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -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_())

View File

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

View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>208</width>
<height>113</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<widget class="QPushButton" name="test">
<property name="geometry">
<rect>
<x>40</x>
<y>30</y>
<width>83</width>
<height>26</height>
</rect>
</property>
<property name="text">
<string>Hello, world!</string>
</property>
</widget>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1 @@
tada tadam tadadam

View File

@ -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"

View File

@ -0,0 +1,16 @@
// Thomas Nagy, 2011-2016
#ifndef _FOO
#define _FOO
#include <QWidget>
class Foo : public QWidget {
Q_OBJECT
signals:
void test();
public:
Foo();
};
#endif

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="1.1" language="fr_FR">
</TS>

View File

@ -0,0 +1,26 @@
// Thomas Nagy, 2016 (ita)
#include <QApplication>
//#include <QString>
//#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();
*/
}

View File

@ -0,0 +1,7 @@
<!DOCTYPE RCC>
<RCC version="1.0">
<qresource>
<file alias="logo.svg">../../../docs/slides/presentation/gfx/waflogo.svg</file>
</qresource>
</RCC>

View File

@ -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
)

View File

@ -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)

View File

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