Skip to content

Commit

Permalink
0000877: Move from PyQt to PySide
Browse files Browse the repository at this point in the history
  • Loading branch information
wwmayer committed Jun 21, 2013
1 parent 367a8f9 commit 1dc122d
Show file tree
Hide file tree
Showing 5 changed files with 159 additions and 56 deletions.
11 changes: 11 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,17 @@ MARK_AS_ADVANCED(FORCE FREECAD_LIBPACK_CHECKFILE6X FREECAD_LIBPACK_CHECKFILE7X)
find_package(Spnav)
endif(WIN32)

# -------------------------------- Shiboken/PySide ------------------------

find_package(Shiboken)
IF(SHIBOKEN_INCLUDE_DIR)
message("-- Shiboken has been found.")
ENDIF(SHIBOKEN_INCLUDE_DIR)
find_package(PySide)
IF(PYSIDE_INCLUDE_DIR)
message("-- PySide has been found.")
ENDIF(PYSIDE_INCLUDE_DIR)

# ------------------------------ Matplotlib ------------------------------

find_package(Matplotlib)
Expand Down
23 changes: 23 additions & 0 deletions src/Gui/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
if(WIN32)
add_definitions(-DFCGui -DQIIS_MAKEDLL)
endif(WIN32)

if (FREECAD_USE_3DCONNEXION)
add_definitions(-D_USE_3DCONNEXION_SDK)
endif(FREECAD_USE_3DCONNEXION)
Expand Down Expand Up @@ -59,6 +60,28 @@ IF(SPNAV_FOUND)
)
ENDIF(SPNAV_FOUND)

if(SHIBOKEN_INCLUDE_DIR)
add_definitions(-DHAVE_SHIBOKEN)
include_directories(
${SHIBOKEN_INCLUDE_DIR}
)
set(FreeCADGui_LIBS
${FreeCADGui_LIBS}
${SHIBOKEN_LIBRARY}
)
endif(SHIBOKEN_INCLUDE_DIR)

if(PYSIDE_INCLUDE_DIR)
add_definitions(-DHAVE_PYSIDE)
include_directories(
${PYSIDE_INCLUDE_DIR}
)
set(FreeCADGui_LIBS
${FreeCADGui_LIBS}
${PYSIDE_LIBRARY}
)
endif(PYSIDE_INCLUDE_DIR)

generate_from_xml(DocumentPy)
generate_from_xml(PythonWorkbenchPy)
generate_from_xml(ViewProviderPy)
Expand Down
76 changes: 36 additions & 40 deletions src/Gui/TaskView/TaskDialogPython.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,24 +186,22 @@ TaskWatcherPython::TaskWatcherPython(const Py::Object& o)
if (!tb && !title.isEmpty())
tb = new Gui::TaskView::TaskBox(icon, title, true, 0);
Py::List list(watcher.getAttr(std::string("widgets")));
Py::Module mainmod(PyImport_AddModule((char*)"sip"));
Py::Callable func = mainmod.getDict().getItem("unwrapinstance");
for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
Py::Tuple arguments(1);
arguments[0] = *it; //PyQt pointer
Py::Object result = func.apply(arguments);
void* ptr = PyLong_AsVoidPtr(result.ptr());
QObject* object = reinterpret_cast<QObject*>(ptr);
if (object) {
QWidget* w = qobject_cast<QWidget*>(object);
if (w) {
if (tb)
tb->groupLayout()->addWidget(w);
else
Content.push_back(w);

Gui::PythonWrapper wrap;
if (wrap.loadModule()) {
for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
QObject* object = wrap.toQObject(*it);
if (object) {
QWidget* w = qobject_cast<QWidget*>(object);
if (w) {
if (tb)
tb->groupLayout()->addWidget(w);
else
Content.push_back(w);
}
}
}
}
}
}

if (tb) Content.push_back(tb);
Expand Down Expand Up @@ -278,30 +276,28 @@ TaskDialogPython::TaskDialogPython(const Py::Object& o) : dlg(o)
}
}
else if (dlg.hasAttr(std::string("form"))) {
Py::Object f(dlg.getAttr(std::string("form")));
Py::List widgets;
if (f.isList()) {
widgets = f;
}
else {
widgets.append(f);
}
for (Py::List::iterator it = widgets.begin(); it != widgets.end(); ++it) {
Py::Module mainmod(PyImport_AddModule((char*)"sip"));
Py::Callable func = mainmod.getDict().getItem("unwrapinstance");
Py::Tuple arguments(1);
arguments[0] = *it; //PyQt pointer
Py::Object result = func.apply(arguments);
void* ptr = PyLong_AsVoidPtr(result.ptr());
QObject* object = reinterpret_cast<QObject*>(ptr);
if (object) {
QWidget* form = qobject_cast<QWidget*>(object);
if (form) {
Gui::TaskView::TaskBox* taskbox = new Gui::TaskView::TaskBox(
form->windowIcon().pixmap(32), form->windowTitle(), true, 0);
taskbox->groupLayout()->addWidget(form);
Content.push_back(taskbox);
}
Py::Object f(dlg.getAttr(std::string("form")));
Py::List widgets;
if (f.isList()) {
widgets = f;
}
else {
widgets.append(f);
}

Gui::PythonWrapper wrap;
if (wrap.loadModule()) {
for (Py::List::iterator it = widgets.begin(); it != widgets.end(); ++it) {
QObject* object = wrap.toQObject(*it);
if (object) {
QWidget* form = qobject_cast<QWidget*>(object);
if (form) {
Gui::TaskView::TaskBox* taskbox = new Gui::TaskView::TaskBox(
form->windowIcon().pixmap(32), form->windowTitle(), true, 0);
taskbox->groupLayout()->addWidget(form);
Content.push_back(taskbox);
}
}
}
}
}
Expand Down
94 changes: 78 additions & 16 deletions src/Gui/WidgetFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,20 @@

#include "PreCompiled.h"

#if 0 // disable for now
#ifdef HAVE_SHIBOKEN
# undef _POSIX_C_SOURCE
# undef _XOPEN_SOURCE
# include <basewrapper.h>
# include <sbkmodule.h>
# include <typeresolver.h>
# ifdef HAVE_PYSIDE
# include <QtCore/pyside_qtcore_python.h>
PyTypeObject** SbkPySide_QtCoreTypes=NULL;
# endif
#endif
#endif

#include <CXX/Objects.hxx>
#include <App/Application.h>
#include <Base/Console.h>
Expand All @@ -37,6 +51,64 @@
using namespace Gui;


PythonWrapper::PythonWrapper()
{
}

QObject* PythonWrapper::toQObject(const Py::Object& pyobject)
{
#if 0
// http://pastebin.com/JByDAF5Z
//#if defined (HAVE_SHIBOKEN) && defined(HAVE_PYSIDE)
PyTypeObject * type = Shiboken::SbkType<QObject>();
if (type) {
if (Shiboken::Object::checkType(pyobject.ptr())) {
SbkObject* sbkobject = reinterpret_cast<SbkObject *>(pyobject.ptr());
void* cppobject = Shiboken::Object::cppPointer(sbkobject, type);
return reinterpret_cast<QObject*>(cppobject);
}
}
#else
Py::Module mainmod(PyImport_AddModule((char*)"sip"));
Py::Callable func = mainmod.getDict().getItem("unwrapinstance");
Py::Tuple arguments(1);
arguments[0] = pyobject; //PyQt pointer
Py::Object result = func.apply(arguments);
void* ptr = PyLong_AsVoidPtr(result.ptr());
return reinterpret_cast<QObject*>(ptr);
#endif

return 0;
}

Py::Object PythonWrapper::toPython(QWidget* widget)
{
// todo: Port to PySide
Py::Module sipmod(PyImport_AddModule((char*)"sip"));
Py::Callable func = sipmod.getDict().getItem("wrapinstance");
Py::Tuple arguments(2);
arguments[0] = Py::asObject(PyLong_FromVoidPtr(widget));
Py::Module qtmod(PyImport_ImportModule((char*)"PyQt4.Qt"));
arguments[1] = qtmod.getDict().getItem("QWidget");
return func.apply(arguments);
}

bool PythonWrapper::loadModule()
{
#if 0
//#if defined (HAVE_SHIBOKEN) && defined(HAVE_PYSIDE)
if (SbkPySide_QtCoreTypes)
return true; // already loaded
Shiboken::AutoDecRef requiredModule(Shiboken::Module::import("PySide.QtCore"));
if (requiredModule.isNull())
return false;
SbkPySide_QtCoreTypes = Shiboken::Module::getTypes(requiredModule);
#endif
return true;
}

// ----------------------------------------------------

Gui::WidgetFactoryInst* Gui::WidgetFactoryInst::_pcSingleton = NULL;

WidgetFactoryInst& WidgetFactoryInst::instance()
Expand Down Expand Up @@ -232,23 +304,17 @@ Py::Object UiLoaderPy::repr()

Py::Object UiLoaderPy::createWidget(const Py::Tuple& args)
{
Py::Module sipmod(PyImport_AddModule((char*)"sip"));
Py::Module qtmod(PyImport_ImportModule((char*)"PyQt4.Qt"));
Gui::PythonWrapper wrap;

// 1st argument
std::string className = (std::string)Py::String(args[0]);

// 2nd argument
QWidget* parent = 0;
if (args.size() > 1) {
Py::Callable func = sipmod.getDict().getItem("unwrapinstance");
Py::Tuple arguments(1);
arguments[0] = args[1]; //PyQt pointer
Py::Object result = func.apply(arguments);
void* ptr = PyLong_AsVoidPtr(result.ptr());
QObject* object = reinterpret_cast<QObject*>(ptr);
if (object)
parent = qobject_cast<QWidget*>(object);
if (wrap.loadModule() && args.size() > 1) {
QObject* object = wrap.toQObject(args[1]);
if (object)
parent = qobject_cast<QWidget*>(object);
}

// 3rd argument
Expand All @@ -259,11 +325,7 @@ Py::Object UiLoaderPy::createWidget(const Py::Tuple& args)

QWidget* widget = loader.createWidget(QString::fromAscii(className.c_str()), parent,
QString::fromAscii(objectName.c_str()));
Py::Callable func = sipmod.getDict().getItem("wrapinstance");
Py::Tuple arguments(2);
arguments[0] = Py::asObject(PyLong_FromVoidPtr(widget));
arguments[1] = qtmod.getDict().getItem("QWidget");
return func.apply(arguments);
return wrap.toPython(widget);
}

// ----------------------------------------------------
Expand Down
11 changes: 11 additions & 0 deletions src/Gui/WidgetFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,17 @@ namespace Gui {
namespace Dialog{
class PreferencePage;
}

class GuiExport PythonWrapper
{
public:
PythonWrapper();
bool loadModule();

QObject* toQObject(const Py::Object&);
Py::Object toPython(QWidget*);
};

/**
* The widget factory provides methods for the dynamic creation of widgets.
* To create these widgets once they must be registered to the factory.
Expand Down

0 comments on commit 1dc122d

Please sign in to comment.