示例#1
0
PyObject *
py_guiQt_main(PyObject* self) {
	(void)self;
	// This is called from Python and replaces the main() control.
	
	// It might make sense to assert that we are the main thread.
	// However, there is no good cross-platform way to do this (afaik).
	// We could use Python... For now, we just hope that Qt behaves sane.
	// Anyway, on the Python side, we should have called this
	// in the main thread.
		
	int ret = 0;
	{
		PyScopedGIUnlock giunlock;

		QtApp::prepareInit();

		// Keep it static. Noone should access it when we return
		// from here, but I like to be safe anyway.
		static QtApp app;
		
		setupMenu();

		if(!app.openMainWindow()) {
			PyScopedGIL gil;
			PyErr_SetString(PyExc_SystemError, "guiQt.main: failed to create main window");
			return NULL;			
		}
		
		{
			PyScopedGIL gil;
			PyObject* initRet = handleModuleCommand("main", "handleApplicationInit", NULL);
			if(!initRet) {
				PyErr_SetString(PyExc_SystemError, "guiQt.main: main.handleApplicationInit() error");
				return NULL;
			}
			Py_DECREF(initRet);
		}
		
		// Enter the Qt main event loop.
		ret = app.exec();
		// Note that it depends on the Qt backend whether we return here or not.
	}
	
	PyErr_SetObject(PyExc_SystemExit, PyInt_FromLong(ret));
	return NULL;
}
示例#2
0
bool QtApp::openWindow(const std::string& name) {
    assert(QThread::currentThread() == qApp->thread());

    PyScopedGIL gil;

    PyObject* rootObj = handleModuleCommand("gui", "RootObjs.__getitem__", "(s)", name.c_str());
    if(!rootObj) return false; // Python errs already handled in handleModuleCommand

    PyQtGuiObject* control = NULL;
    control = (PyQtGuiObject*) PyObject_GetAttrString(rootObj, "guiObj");
    if(!control) {
        if(PyErr_Occurred()) PyErr_Print();
        Py_DECREF(rootObj);
        return false;
    }

    if((PyObject*) control == Py_None) Py_CLEAR(control);
    if(control) {
        if(PyType_IsSubtype(Py_TYPE(control), &QtGuiObject_Type)) {
            QtBaseWidget::ScopedRef win(control->widget);
            if(win) {
                win->show();
                return true;
            }
            // continue with existing control but create new window
        }
        else {
            printf("Qt open window: existing rootObj.guiObj is of wrong type\n");
            // reset and continue with new control creation
            Py_CLEAR(control);
        }
    }

    if(!control) {
        control = (PyQtGuiObject*) PyObject_CallFunction((PyObject*) &QtGuiObject_Type, NULL);
        if(!control) {
            if(PyErr_Occurred()) PyErr_Print();
            Py_DECREF(rootObj);
            return false;
        }

        assert(control->root == NULL);
        control->root = control;
        Py_XINCREF(control->root);
        assert(control->subjectObject == NULL);
        control->subjectObject = PyObject_GetAttrString(rootObj, "obj");
        if(!control->subjectObject) {
            if(PyErr_Occurred()) PyErr_Print();
            Py_DECREF(rootObj);
            Py_DECREF(control);
            return false;
        }
    }

    if(PyObject_SetAttrString(rootObj, "guiObj", (PyObject*) control) < 0) {
        if(PyErr_Occurred()) PyErr_Print();
        Py_DECREF(rootObj);
        Py_DECREF(control);
        return false;
    }

    // check subjectObject
    {
        PyObject* subjectObject = PyObject_GetAttrString(rootObj, "obj");
        if(!subjectObject) {
            if(PyErr_Occurred()) PyErr_Print();
            // continue, maybe it doesn't matter
        }
        else {
            if(subjectObject != control->subjectObject) {
                printf("Qt open window: got new subject object\n");
                // strange, but just overtake and continue
                Py_CLEAR(control->subjectObject);
                control->subjectObject = subjectObject;
                subjectObject = NULL;
            }
        }
        Py_XDECREF(subjectObject);
    }

    QtBaseWidget* win = new QtBaseWidget(control);
    win->setAttribute(Qt::WA_DeleteOnClose);

    // set title
    {
        PyObject* title = PyObject_GetAttrString(rootObj, "title");
        std::string titleStr;
        if(!title || !pyStr(title, titleStr)) {
            if(PyErr_Occurred()) PyErr_Print();
            win->setWindowTitle(QString::fromStdString(name));
        }
        else {
            win->setWindowTitle(QString::fromStdString(titleStr));
        }
        Py_XDECREF(title);
    }

    Vec size = control->setupChilds();
    win->setMinimumSize(size.x, size.y);

    // ...

    win->show();
    control->layout();

    Py_DECREF(rootObj);
    Py_DECREF(control);
    return true;
}