+ Prepare PySide to work with custom widgets

This commit is contained in:
wmayer 2014-01-09 23:49:41 +01:00
parent d00327640a
commit 270d25658d
2 changed files with 87 additions and 4 deletions

View File

@ -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<QIODevice*>(obj);
}
if (args.size() > 1) {
QObject* obj = wrap.toQObject(args[1]);
parent = qobject_cast<QWidget*>(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);
}

View File

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