+ Support preference pages for Python widget class

This commit is contained in:
wmayer 2015-07-16 00:10:23 +02:00
parent 62c6a61b8b
commit 3241b1ece1
3 changed files with 170 additions and 11 deletions

View File

@ -532,20 +532,31 @@ PyObject* Application::sCreateDialog(PyObject * /*self*/, PyObject *args,PyObjec
PyObject* Application::sAddPreferencePage(PyObject * /*self*/, PyObject *args,PyObject * /*kwd*/)
{
char *fn, *grp;
if (!PyArg_ParseTuple(args, "ss", &fn,&grp)) // convert args: Python->C
return NULL; // NULL triggers exception
if (PyArg_ParseTuple(args, "ss", &fn,&grp)) {
QFileInfo fi(QString::fromUtf8(fn));
if (!fi.exists()) {
PyErr_SetString(PyExc_RuntimeError, "UI file does not exist");
return 0;
}
QFileInfo fi(QString::fromUtf8(fn));
if (!fi.exists()) {
PyErr_SetString(PyExc_RuntimeError, "UI file does not exist");
return 0;
// add to the preferences dialog
new PrefPageUiProducer(fn, grp);
Py_INCREF(Py_None);
return Py_None;
}
PyErr_Clear();
PyObject* dlg;
if (PyArg_ParseTuple(args, "O!s", &PyClass_Type, &dlg, &grp)) {
// add to the preferences dialog
new PrefPagePyProducer(Py::Object(dlg), grp);
Py_INCREF(Py_None);
return Py_None;
}
// add to the preferences dialog
new PrefPageUiProducer(fn, grp);
Py_INCREF(Py_None);
return Py_None;
return 0;
}
PyObject* Application::sActivateWorkbenchHandler(PyObject * /*self*/, PyObject *args,PyObject * /*kwd*/)

View File

@ -729,6 +729,106 @@ void* PrefPageUiProducer::Produce () const
// ----------------------------------------------------
PrefPagePyProducer::PrefPagePyProducer (const Py::Object& p, const char* group)
: type(p)
{
std::string str;
Base::PyGILStateLocker lock;
if (type.hasAttr("__name__")) {
str = static_cast<std::string>(Py::String(type.getAttr("__name__")));
}
WidgetFactoryInst::instance().AddProducer(str.c_str(), this);
Gui::Dialog::DlgPreferencesImp::addPage(str, group);
}
PrefPagePyProducer::~PrefPagePyProducer ()
{
Base::PyGILStateLocker lock;
type = Py::None();
}
void* PrefPagePyProducer::Produce () const
{
Base::PyGILStateLocker lock;
Py::Callable method(type);
Py::Tuple args;
Py::Object page = method.apply(args);
return new Gui::Dialog::PreferencePagePython(page);
}
// ----------------------------------------------------
using namespace Gui::Dialog;
PreferencePagePython::PreferencePagePython(const Py::Object& p, QWidget* parent)
: PreferencePage(parent), page(p)
{
Base::PyGILStateLocker lock;
if (page.hasAttr(std::string("form"))) {
Py::Object widget(page.getAttr(std::string("form")));
Gui::PythonWrapper wrap;
if (wrap.loadCoreModule()) {
QObject* object = wrap.toQObject(widget);
if (object) {
QWidget* form = qobject_cast<QWidget*>(object);
if (form) {
this->setWindowTitle(form->windowTitle());
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(form);
setLayout(layout);
}
}
}
}
}
PreferencePagePython::~PreferencePagePython()
{
Base::PyGILStateLocker lock;
page = Py::None();
}
void PreferencePagePython::changeEvent(QEvent *e)
{
QWidget::changeEvent(e);
}
void PreferencePagePython::loadSettings()
{
Base::PyGILStateLocker lock;
try {
if (page.hasAttr(std::string("loadSettings"))) {
Py::Callable method(page.getAttr(std::string("loadSettings")));
Py::Tuple args;
method.apply(args);
}
}
catch (Py::Exception&) {
Base::PyException e; // extract the Python error text
e.ReportException();
}
}
void PreferencePagePython::saveSettings()
{
Base::PyGILStateLocker lock;
try {
if (page.hasAttr(std::string("saveSettings"))) {
Py::Callable method(page.getAttr(std::string("saveSettings")));
Py::Tuple args;
method.apply(args);
}
}
catch (Py::Exception&) {
Base::PyException e; // extract the Python error text
e.ReportException();
}
}
// ----------------------------------------------------
/* TRANSLATOR Gui::ContainerDialog */
/**

View File

@ -236,6 +236,28 @@ private:
QString fn;
};
/**
* The PrefPagePyProducer class provides the ability to create preference pages
* dynamically from a Python class.
* @author Werner Mayer
*/
class GuiExport PrefPagePyProducer : public Base::AbstractProducer
{
public:
/**
* Register a special type of preference page to the WidgetFactoryInst.
*/
PrefPagePyProducer (const Py::Object&, const char* group);
virtual ~PrefPagePyProducer ();
/**
* Creates an instance of the specified widget.
*/
virtual void* Produce () const;
private:
Py::Object type;
};
// --------------------------------------------------------------------
/**
@ -435,6 +457,32 @@ private:
QObject* mySender;
};
// ----------------------------------------------------
namespace Dialog {
/** Subclass that embeds a form from a Python class.
* \author Werner Mayer
*/
class GuiExport PreferencePagePython : public PreferencePage
{
Q_OBJECT
public:
PreferencePagePython(const Py::Object& dlg, QWidget* parent = 0);
virtual ~PreferencePagePython();
void loadSettings();
void saveSettings();
protected:
void changeEvent(QEvent *e);
private:
Py::Object page;
};
} // namespace Dialog
} // namespace Gui
#endif // GUI_WIDGETFACTORY_H