From 270d25658dd98e5fee475d9e534212f0ed373002 Mon Sep 17 00:00:00 2001 From: wmayer Date: Thu, 9 Jan 2014 23:49:41 +0100 Subject: [PATCH] + Prepare PySide to work with custom widgets --- src/Gui/WidgetFactory.cpp | 89 +++++++++++++++++++++++++++++++++++++-- src/Gui/WidgetFactory.h | 2 + 2 files changed, 87 insertions(+), 4 deletions(-) diff --git a/src/Gui/WidgetFactory.cpp b/src/Gui/WidgetFactory.cpp index a64357b42..501ba8aa9 100644 --- a/src/Gui/WidgetFactory.cpp +++ b/src/Gui/WidgetFactory.cpp @@ -72,6 +72,18 @@ PythonWrapper::PythonWrapper() { } +bool PythonWrapper::toCString(const Py::Object& pyobject, std::string& str) +{ +#if defined (HAVE_SHIBOKEN) && defined(HAVE_PYSIDE) + if (Shiboken::String::check(pyobject.ptr())) { + const char* s = Shiboken::String::toCString(pyobject.ptr()); + if (s) str = s; + return true; + } +#endif + return false; +} + QObject* PythonWrapper::toQObject(const Py::Object& pyobject) { // http://pastebin.com/JByDAF5Z @@ -358,17 +370,21 @@ Py::Object PySideUicModule::loadUi(const Py::Tuple& args) QTextStream str(&cmd); // https://github.com/lunaryorn/snippets/blob/master/qt4/designer/pyside_dynamic.py str << "from PySide import QtCore, QtGui, QtUiTools\n" + << "import FreeCADGui" << "\n" << "class UiLoader(QtUiTools.QUiLoader):\n" << " def __init__(self, baseinstance):\n" << " QtUiTools.QUiLoader.__init__(self, baseinstance)\n" << " self.baseinstance = baseinstance\n" + << " self.ui = FreeCADGui.UiLoader()\n" << "\n" << " def createWidget(self, class_name, parent=None, name=''):\n" << " if parent is None and self.baseinstance:\n" << " return self.baseinstance\n" << " else:\n" - << " widget = QtUiTools.QUiLoader.createWidget(self, class_name, parent, name)\n" + << " widget = self.ui.createWidget(class_name, parent, name)\n" + << " if not widget:\n" + << " widget = QtUiTools.QUiLoader.createWidget(self, class_name, parent, name)\n" << " if self.baseinstance:\n" << " setattr(self.baseinstance, name, widget)\n" << " return widget\n" @@ -436,6 +452,8 @@ void UiLoaderPy::init_type() behaviors().supportRepr(); behaviors().supportGetattr(); behaviors().supportSetattr(); + add_varargs_method("load",&UiLoaderPy::load,"load(string, QWidget parent=None) -> QWidget\n" + "load(QIODevice, QWidget parent=None) -> QWidget"); add_varargs_method("createWidget",&UiLoaderPy::createWidget,"createWidget()"); } @@ -455,13 +473,64 @@ Py::Object UiLoaderPy::repr() return Py::String(s_out.str()); } +Py::Object UiLoaderPy::load(const Py::Tuple& args) +{ + Gui::PythonWrapper wrap; + if (wrap.loadCoreModule()) { + std::string fn; + QFile file; + QIODevice* device = 0; + QWidget* parent = 0; + if (wrap.toCString(args[0], fn)) { + file.setFileName(QString::fromUtf8(fn.c_str())); + if (!file.open(QFile::ReadOnly)) + throw Py::RuntimeError("Cannot open file"); + device = &file; + } + else if (args[0].isString()) { + fn = (std::string)Py::String(args[0]); + file.setFileName(QString::fromUtf8(fn.c_str())); + if (!file.open(QFile::ReadOnly)) + throw Py::RuntimeError("Cannot open file"); + device = &file; + } + else { + QObject* obj = wrap.toQObject(args[0]); + device = qobject_cast(obj); + } + + if (args.size() > 1) { + QObject* obj = wrap.toQObject(args[1]); + parent = qobject_cast(obj); + } + + if (device) { + QWidget* widget = loader.load(device, parent); + if (widget) { + wrap.loadGuiModule(); + return wrap.fromQWidget(widget); + } + } + else { + throw Py::Exception("string or QIODevice expected"); + } + } + return Py::None(); +} + Py::Object UiLoaderPy::createWidget(const Py::Tuple& args) { Gui::PythonWrapper wrap; // 1st argument - std::string className = (std::string)Py::String(args[0]); - + Py::String str(args[0]); + std::string className; + if (str.isUnicode()) { + className = str.as_std_string("utf-8"); + } + else { + className = (std::string)Py::String(); + } // 2nd argument QWidget* parent = 0; if (wrap.loadCoreModule() && args.size() > 1) { @@ -473,11 +542,23 @@ Py::Object UiLoaderPy::createWidget(const Py::Tuple& args) // 3rd argument std::string objectName; if (args.size() > 2) { - objectName = (std::string)Py::String(args[2]); + Py::String str(args[2]); + if (str.isUnicode()) { + objectName = str.as_std_string("utf-8"); + } + else { + objectName = (std::string)Py::String(); + } } QWidget* widget = loader.createWidget(QString::fromAscii(className.c_str()), parent, QString::fromAscii(objectName.c_str())); + if (!widget) { + std::string err = "No such widget class '"; + err += className; + err += "'"; + throw Py::RuntimeError(err); + } wrap.loadGuiModule(); return wrap.fromQWidget(widget); } diff --git a/src/Gui/WidgetFactory.h b/src/Gui/WidgetFactory.h index 87d4f2833..83c983bd9 100644 --- a/src/Gui/WidgetFactory.h +++ b/src/Gui/WidgetFactory.h @@ -46,6 +46,7 @@ public: bool loadCoreModule(); bool loadGuiModule(); + bool toCString(const Py::Object&, std::string&); QObject* toQObject(const Py::Object&); Py::Object fromQWidget(QWidget*, const char* className=0); }; @@ -127,6 +128,7 @@ public: Py::Object repr(); Py::Object createWidget(const Py::Tuple&); + Py::Object load(const Py::Tuple&); private: static PyObject *PyMake(struct _typeobject *, PyObject *, PyObject *);