Возможно вы знаете про PySide, python биндинги к Qt. Также существует PyQt библиотека которая предоставляет аналогичную функциональность но к сожалению ограничена GPL или коммерческой версией. PySide распространяется под LGPL лицензией что даёт удобную возможность пользовать в коммерческих приложениях.
Python даёт возможность очень быстрого создания рабочих приложений и PySide как раз предоставляет такую возможность для Qt разработчиков. По моему опыту создание аналогичного функционала возможно в 1.5-2 раза быстрее чем на C++.
Часто возникает необходимость по быстрому присоединить C++ библиотеку (Qt-подобным интерфейсом) к PySide приложению, или же наоборот стоит задача использования Python скриптов в Qt(C++) приложениях. В обоих случаях нужна автоматическая поддержка API классов от Qt и возможность signal-slot соединений между Qt(C++) и Python(PySide) частями приложения. K сожалению данный вопрос практически не освещён и сделать всё и сразу рабочим довольно сложно.
Итак мы будем создавать гибридное приложение состоящее одновременно из C++ и Python частей и использующее Qt как основную GUI библиотеку.
Нам необходимы установленные Qt, Python и PySide.
Создадим следующую структуру каталогов и файлов:
Каталог hybrid содержит C++ часть приложения которая будет скомпилирована в dll/dylib/so
Katalog hybridpy содержит обёртку (wrappings) C++ части которая будет проимпортированна в Python часть приложения.
Каталог data содержит описания типов (typesystem) использованных в C++ модуле. Это Xml файл описывающий типы объектов и их особенности при представлении их как Python объектов. Болъше информации о создании typesystems вы можете найти на сайте PySide (http://www.pyside.org/docs/shiboken/contents.html).
В каталоге hybrid создаём C++(Qt) часть приложения. Создадим простейшее QMainWindow приложение: hybrid/hybrid.pro:
#ifndef MainWindow_H
#define MainWindow_H
#include <QMainWindow>
class QPushButton;
class QGraphicsView;
class QGraphicsScene;
class QPlainTextEdit;
class MainWindow : public QMainWindow { Q_OBJECT
public:
MainWindow(QWidget * parent = 0L);
virtual ~MainWindow();
signals:
void runPythonCode(QString);
private slots:
void runPythonCode();
public:
QGraphicsView * viewer;
QGraphicsScene * scene;
QPlainTextEdit * editor;
QPushButton * pb_commit;
};
#endif // MainWindow_H
hybrid/MainWindow.cpp:
#include <QtGui>
#include "MainWindow.h"
MainWindow::MainWindow(QWidget * parent):QMainWindow(parent) {
QSplitter * splitter = new QSplitter;
setCentralWidget(splitter);
QWidget * editorContent = new QWidget;
splitter->addWidget(editorContent);
QVBoxLayout * layout = new QVBoxLayout;
editorContent->setLayout(layout);
editor = new QPlainTextEdit;
layout->addWidget(editor);
pb_commit = new QPushButton(tr("Commit"));
connect(pb_commit, SIGNAL(clicked()),
this, SLOT(runPythonCode()));
layout->addWidget(pb_commit);
scene = new QGraphicsScene(this);
viewer = new QGraphicsView;
viewer->setScene(scene);
splitter->addWidget(viewer);
splitter->setSizes(QList<int>() << 400 << 600);
}
MainWindow::~MainWindow() {;}
void MainWindow::runPythonCode() { emit runPythonCode(editor->toPlainText()); }
После компиляции у нас приложение с редактором в левой панели и Canvas справа:
Можем готовить эту часть для PySide:
1. Изменим pro файл для сборки dll/dylib/so
2. Создадим обёртку для MainWindow класса
3. Пользуем Main.py вместо C main() входной функции
Изменение pro файла довольно простое: меняем TEMPLATE на lib и убираем main.cpp из списка, также поставим TARGET на корень нашего приложения (HybridApp, корень проекта) hybrid/hybrid.pro:
Резулататом будет libHybrid.dylib в папке HybridApp (корень проекта)
Теперь создадим обёртку для C++ части приложения. Сборка будет с помощью build.sh скрипта в корне проекта. (Скрипт соберёт всё: C++ часть и обёртку) build.sh:
#!/bin/sh
cd hybrid
qmake
make
cd ..
cd hybridpy
QTGUI_INC=/Library/Frameworks/QtGui.framework/Versions/4/Headers
QTCORE_INC=/Library/Frameworks/QtCore.framework/Versions/4/Headers
QTTYPESYSTEM=/usr/local/share/PySide/typesystems
generatorrunner --generatorSet=shiboken \
../data/global.h \
--include-paths=../hybrid:$QTCORE_INC:$QTGUI_INC:/usr/include \
--typesystem-paths=../data:$QTTYPESYSTEM \
--output-directory=. \
../data/typesystem.xml
qmake
make
cd ..
rm -rf PyHybrid.so
ln -s libPyHybrid.dylib PyHybrid.so
Всё создание обёртки это один вызов generatorrunner с путём к Qt headers, Qt typesystems и наш typesystem(описание типов). Затем в папке hybridpy вызов qmake и сборка python модуля. data/typesystem.xml:
Возможно для данной сборки лучше использовать cmake с которым можно автоматически найти пути к shiboken итд, но для иллюстрации какие файлы пользуются был выбран qmake проект.
Выглядит почти готовым – после запуска build.sh у нас есть python модуль с C++ частью приложения. Момент чтобы соединить обе части в Main.py: Main.py:
import sys
from PySide.QtCore import *
from PySide.QtGui import *
from PyHybrid import *
class RunScript(QObject):
def __init__(self, mainWindow):
QObject.__init__(self)
self.mainWindow = mainWindow
def runScript(self, script):
mainWindow = self.mainWindow
exec(str(script))
a = QApplication(sys.argv)
w = MainWindow()
r = RunScript(w)
w.setWindowTitle('PyHybrid')
w.resize(1000,800)
w.show()
a.connect(w, SIGNAL('runPythonCode(QString)'), r.runScript)
a.connect(a, SIGNAL('lastWindowClosed()'), a, SLOT('quit()') )
a.exec_()
После запуска этого python скрипта мы получим тоже самое окно нашего C++ приложения, но с некоторым отличием – теперь python код введённый в редакторе можно выполнить прямо в самом приложении с доступом к C++ объектам приложения.
Попробуем небольшой код:mainWindow.statusBar().show()
и у нашего приложения появился status bar.
Поменяем фон Cаnvas?
Наше небольшое приложение получило небольшую уникальную возможность: мы можем его программировать прямо во время выполнения, и это программирование не ограничивается существующим API, но мы можем создавать свои классы на Python передавать их в C++ часть где они имея общий, например QOBject/QWidget, интерфейс, могут обрабатываться и использоваться.
Применение Qt+PySide гибридизации довольно широкое – разработка игр, где часто нужна возможность подкорректировать что-либо прямо во время выполнения, скриптинги для объектов в играх. Далее с помощью PySide мы можем довольно быстро создавать новые классы, тестировать идеи и потом переносить в C++ (или же довольно быстро переносить в C++ только критические к скорости фрагменты).
Что касается приведённого выше приложения, то оно демонстрирует немного другой подход к программированию когда приложение кодится и модифицируется прямо во время выполнения. Конечно нужно сделать автоматическое сохранение всех выполненных фрагментов в файлы или весь код пропадёт после остановки приложения.
Ru: Archive: Создание Qt+PySide гибридных приложений
Возможно вы знаете про PySide, python биндинги к Qt. Также существует PyQt библиотека которая предоставляет аналогичную функциональность но к сожалению ограничена GPL или коммерческой версией. PySide распространяется под LGPL лицензией что даёт удобную возможность пользовать в коммерческих приложениях.
Python даёт возможность очень быстрого создания рабочих приложений и PySide как раз предоставляет такую возможность для Qt разработчиков. По моему опыту создание аналогичного функционала возможно в 1.5-2 раза быстрее чем на C++.
Часто возникает необходимость по быстрому присоединить C++ библиотеку (Qt-подобным интерфейсом) к PySide приложению, или же наоборот стоит задача использования Python скриптов в Qt(C++) приложениях. В обоих случаях нужна автоматическая поддержка API классов от Qt и возможность signal-slot соединений между Qt(C++) и Python(PySide) частями приложения. K сожалению данный вопрос практически не освещён и сделать всё и сразу рабочим довольно сложно.
Итак мы будем создавать гибридное приложение состоящее одновременно из C++ и Python частей и использующее Qt как основную GUI библиотеку.
Нам необходимы установленные Qt, Python и PySide.
Создадим следующую структуру каталогов и файлов:
Каталог hybrid содержит C++ часть приложения которая будет скомпилирована в dll/dylib/so
Katalog hybridpy содержит обёртку (wrappings) C++ части которая будет проимпортированна в Python часть приложения.
Каталог data содержит описания типов (typesystem) использованных в C++ модуле. Это Xml файл описывающий типы объектов и их особенности при представлении их как Python объектов. Болъше информации о создании typesystems вы можете найти на сайте PySide (http://www.pyside.org/docs/shiboken/contents.html).
В каталоге hybrid создаём C++(Qt) часть приложения. Создадим простейшее QMainWindow приложение:
hybrid/hybrid.pro:
hybrid/Main.cpp:
hybrid/MainWindow.h:
hybrid/MainWindow.cpp:
После компиляции у нас приложение с редактором в левой панели и Canvas справа:

Можем готовить эту часть для PySide:
1. Изменим pro файл для сборки dll/dylib/so
2. Создадим обёртку для MainWindow класса
3. Пользуем Main.py вместо C main() входной функции
Изменение pro файла довольно простое: меняем TEMPLATE на lib и убираем main.cpp из списка, также поставим TARGET на корень нашего приложения (HybridApp, корень проекта)
hybrid/hybrid.pro:
Резулататом будет libHybrid.dylib в папке HybridApp (корень проекта)
Теперь создадим обёртку для C++ части приложения. Сборка будет с помощью build.sh скрипта в корне проекта. (Скрипт соберёт всё: C++ часть и обёртку)
build.sh:
Всё создание обёртки это один вызов generatorrunner с путём к Qt headers, Qt typesystems и наш typesystem(описание типов). Затем в папке hybridpy вызов qmake и сборка python модуля.
data/typesystem.xml:
data/global.h:
И pro файл для сборки python модуля:
hybridpy/hybridpy.pro:
Возможно для данной сборки лучше использовать cmake с которым можно автоматически найти пути к shiboken итд, но для иллюстрации какие файлы пользуются был выбран qmake проект.
Выглядит почти готовым – после запуска build.sh у нас есть python модуль с C++ частью приложения. Момент чтобы соединить обе части в Main.py:
Main.py:
После запуска этого python скрипта мы получим тоже самое окно нашего C++ приложения, но с некоторым отличием – теперь python код введённый в редакторе можно выполнить прямо в самом приложении с доступом к C++ объектам приложения.
Попробуем небольшой код:mainWindow.statusBar().show()
и у нашего приложения появился status bar.
Поменяем фон Cаnvas?
Далее, мы можем создавать новые классы прямо во время выполнения приложения, а почему бы и нет?
Наше небольшое приложение получило небольшую уникальную возможность: мы можем его программировать прямо во время выполнения, и это программирование не ограничивается существующим API, но мы можем создавать свои классы на Python передавать их в C++ часть где они имея общий, например QOBject/QWidget, интерфейс, могут обрабатываться и использоваться.
Применение Qt+PySide гибридизации довольно широкое – разработка игр, где часто нужна возможность подкорректировать что-либо прямо во время выполнения, скриптинги для объектов в играх. Далее с помощью PySide мы можем довольно быстро создавать новые классы, тестировать идеи и потом переносить в C++ (или же довольно быстро переносить в C++ только критические к скорости фрагменты).
Что касается приведённого выше приложения, то оно демонстрирует немного другой подход к программированию когда приложение кодится и модифицируется прямо во время выполнения. Конечно нужно сделать автоматическое сохранение всех выполненных фрагментов в файлы или весь код пропадёт после остановки приложения.