Exemplo n.º 1
0
PyObject*
py_guiQt_buildControl(PyObject* self, PyObject* args, PyObject* kws) {
	(void)self;
	PyObject* userAttr = NULL;
	PyQtGuiObject* parent = NULL;
	static const char *kwlist[] = {"userAttr", "parent", NULL};
	if(!PyArg_ParseTupleAndKeywords(
			args, kws, "OO:buildControl", (char**)kwlist,
			&userAttr, &parent))
		return NULL;

	if(!PyType_IsSubtype(Py_TYPE(parent), &QtGuiObject_Type)) {
		PyErr_Format(PyExc_ValueError, "guiQt.buildControl: parent must be a QtGuiObject");
		return NULL;
	}

	if(parent->root == NULL) {
		PyErr_Format(PyExc_ValueError, "guiQt.buildControl: parent.root is NULL");
		return NULL;		
	}
	
	if(parent->subjectObject == NULL) {
		PyErr_Format(PyExc_ValueError, "guiQt.buildControl: parent.subjectObject is NULL");
		return NULL;		
	}
	
	std::string controlType;
	{
		PyObject* typeClass = PyObject_CallMethod(userAttr, (char*)"getTypeClass", NULL);
		if(!typeClass) return NULL;
		PyObject* typeClassName = PyObject_GetAttrString(typeClass, "__name__");
		if(!typeClassName) { Py_DECREF(typeClass); return NULL; }
		if(!pyStr(typeClassName, controlType)) { Py_DECREF(typeClass); Py_DECREF(typeClassName); return NULL; }
		PyObject* traitsMod = getModule("Traits"); // borrowed
		if(!traitsMod) {
			PyErr_Format(PyExc_ValueError, "guiQt.buildControl: Traits module not found");
			Py_DECREF(typeClass); Py_DECREF(typeClassName);
			return NULL;
		}
		PyObject* traitsClass = PyObject_GetAttrString(traitsMod, controlType.c_str());
		if(!traitsClass) {
			PyErr_Format(PyExc_ValueError, "guiQt.buildControl: Traits.%s not found", controlType.c_str());
			Py_DECREF(typeClass); Py_DECREF(typeClassName);
			return NULL;
		}
		if(traitsClass != typeClass) {
			PyErr_Format(PyExc_ValueError, "guiQt.buildControl: Traits.%s is different class", controlType.c_str());
			Py_DECREF(typeClass); Py_DECREF(typeClassName); Py_DECREF(traitsClass);
			return NULL;
		}
		Py_DECREF(typeClass);
		Py_DECREF(typeClassName);
		Py_DECREF(traitsClass);		
	}
	ControlBuilderFunc builderFunc = getControlBuilder(controlType);
	if(!builderFunc) {
		// The current layouting engine + setupChilds() will be messed up if this fails.
		// So just provide some dummy fallback.
		printf("guiQt.buildControl: %s-widget not implemented yet, using Object-widget as fallback\n", controlType.c_str());
		builderFunc = getControlBuilder("Object");
		assert(builderFunc);
	}
	
	PyQtGuiObject* control = (PyQtGuiObject*) PyObject_CallFunction((PyObject*) &QtGuiObject_Type, NULL);
	if(!control) return NULL;
	
	assert(control->root == NULL);
	control->root = parent->root;
	Py_XINCREF(control->root);
	assert(control->parent == NULL);
	control->parent = parent;
	Py_XINCREF(control->parent);
	assert(control->attr == NULL);
	control->attr = userAttr;
	Py_XINCREF(control->attr);
	
	assert(control->subjectObject == NULL);
	control->subjectObject = PyObject_CallMethod(userAttr, (char*)"__get__", (char*)"(O)", parent->subjectObject);
	if(control->subjectObject == NULL) {
		Py_DECREF(control);
		return NULL;
	}
	
	{
		PyScopedGIUnlock gunlock;
		execInMainThread_sync([&]() {
			bool res = builderFunc(control);
			if(!res)
				// XXX: handle somehow? ...
				printf("guiQt.buildControl: warning, returned error\n");		
		});
	}
	
	// forward control
	return (PyObject*) control;
}
Exemplo n.º 2
0
void QtOneLineTextWidget::updateContent() {
	PyQtGuiObject* control = NULL;
	std::string s = "???";

	{
		PyScopedGIL gil;
	
		control = getControl();
		if(!control) return;
		
		control->updateSubjectObject();
	
		{
			PyObject* labelContent = getTextObj();
			if(!labelContent && PyErr_Occurred()) PyErr_Print();
			if(labelContent) {
				if(!pyStr(labelContent, s)) {
					if(PyErr_Occurred()) PyErr_Print();
				}
			}
		}		
	}

	WeakRef selfRefCopy(*this);
	
	// Note: We had this async before. But I think other code wants to know the actual size
	// and we only get it after we set the text.
	execInMainThread_sync([=]() {
		PyScopedGIL gil;

		ScopedRef selfRef(selfRefCopy.scoped());
		if(selfRef) {
			auto self = dynamic_cast<QtOneLineTextWidget*>(selfRef.get());
			assert(self);
			assert(self->lineEditWidget);
			
			self->lineEditWidget->setText(QString::fromStdString(s));
	
			PyScopedGIL gil;
			
			/*
			NSColor* color = backgroundColor(control);
			if(color) {
				[self setDrawsBackground:YES];
				[self setBackgroundColor:color];
			}
			*/
			
			//[self setTextColor:foregroundColor(control)];
			
			bool autosizeWidth = attrChain_bool_default(control->attr, "autosizeWidth", false);
			if(autosizeWidth) {
				QFontMetrics metrics(self->lineEditWidget->fontMetrics());
				int w = metrics.boundingRect(self->lineEditWidget->text()).width();
				w += 5; // TODO: margin size?
				self->resize(w, self->height());
				
				PyObject* res = PyObject_CallMethod((PyObject*) control, (char*)"layoutLine", NULL);
				if(!res && PyErr_Occurred()) PyErr_Print();
				Py_XDECREF(res);
			}
		}
		
		Py_DECREF(control);
	});
}