Why does getProperty(\sizePolicy) fail?

a = Slider().orientation_(\vertical)
a.getProperty(\width) // ok
a.getProperty(\sizePolicy) // error

Why does the last line error even though

a.properties.includes(\sizePolicy) // -> true

Probably here:

Side note: I don’t know Qt at all, so I haven’t any idea why this property isn’t “valid.” Nor do I know where valid properties are documented (though they probably aren’t). I could find where the error is being thrown, but that’s about all I can do here.

Edit: oh, I misread: if the property is valid, it just sets nil. It throws an error if setting the return value fails. Why that fails, I’ve no idea.

hjh

sizePolicy returns a QSizePolicy, which is not an object that is compatible or convertible to something in sclang. Is there an expectation that this would work? AFAIK this is not used in code anywhere.

I think his point is that, if \sizePolicy is not gettable, then perhaps it shouldn’t be listed as one of a View’s properties.

It’s unclear what view.properties means – if it’s meant as a list of all properties that are expected to be get- or settable, then the presence of \sizePolicy in a properties array would generate user expectation. If nobody ever tested all of them, then it’s an example of technical debt.

hjh

1 Like

Okay, a little more explanation (my initial one was a little hasty) -

  • QObject and it’s methods are internal sclang-QT implementation details, and are not really meant for use in user-facing code. QT classes exposed in sclang are abstracted over to provide reasonable sclang classes.

  • All properties, methods, and signals returned by QObject:properties and QObject:methods correspond to the properties and methods exposed by the underlying QObject - these can be referenced in the QT documentation (https://doc.qt.io/qt-5/classes.html). For example - sclang’s Button is a QcButton (see Button:*qtClass), which is a wrapper around a QPushButton, so you’ll see all of it’s properties and methods.

  • In general, these properties and methods are unusable unless sclang specifically knows how to transform a QT/c++ type to or from an sclang type. A number of common types have translations, which is how we are able to make QT calls at all - so if a property is a qreal, you’re in luck and sclang knows how to interpret this c++ value (as a Float).

  • Architecturally, the only code that should be dealing with QObject's properties and methods directly are low-level QT sclang classes for things like Views - that is, classes that derive from sclangs QObject and have a *qtClass defined. This constrained access ensures that QT details don’t leak into the general sclang ecosystem - apart from the general well-factored-code reasons, this is pragmatically important because these details can change between QT versions. For example, this happened with the WebEngine switch a few years ago - there was minimal fallout from this because we were able to adapt the existing WebView sclang API to match the API of the new QT components without any big changes to client code.

  • (This is the good part) - if there are properties or methods in the QT documentation that would be useful to access in sclang… you can add support for them pretty easily:

    1. Register the metatype here: https://github.com/supercollider/supercollider/blob/develop/QtCollider/metatype.cpp - in the template definitions and the big switch table that converts sclang types to c++ types.
    2. Add a TypeCodec for that type: https://github.com/supercollider/supercollider/blob/develop/QtCollider/type_codec.cpp

    That should be it - this is where e.g. you would add QSizePolicy if it was important to access. There’s a lot of existing value in QT that we currently cannot access purely because of some missing (and very simple) type conversion and registration code - this is a great task for anyone that wants to get their feet wet with C++ SuperCollider development and wants to add a lot of value without much effort :slight_smile:

1 Like

properties might then be deprecated and replaced with prProperties.

What I mean is, users who have been around long enough know that SC’s interfaces sometimes don’t mean what they say – properties really means “internalPropertiesNotForUsers” but it says “properties.” This is fine as long as users are experienced enough to know which methods to take seriously and which ones not to, or as long as users are satisfied with the normal ways of doing things and aren’t poking around too much. When a user comes in who is both unfamiliar with SC community folklore and inquisitive about undocumented methods, then it reveals places where we didn’t think through the interfaces carefully enough.

RFluff’s question is valid – and the answer is that view properties are not expected to be used in sclang (even though there is nothing in the interfaces to distinguish these internals-only methods from public, user-facing methods – you had asked if there was any expectation that it should work – my question is rather, how should somebody know that there is no such expectation?). Maybe a documentation issue.

There’s a lot of existing value in QT that we currently cannot access purely because of some missing (and very simple) type conversion and registration code - this is a great task for anyone that wants to get their feet wet with C++ SuperCollider development and wants to add a lot of value without much effort :slight_smile:

Agreed.

hjh

100% agree. methods is even worse, because it feels like there SHOULD be such a getter on SC objects, but this one definitely does not do what one would expect it to do.

Tbh the whole QT interop layer could do with some clean-up - but if anyone is going to put any proper energy into this, it should be to properly integrate QML rather than increasing dependence on the effectively-deprecated C++ gui classes.

It is convertible the “other way around” when you set View.resize (which is an Integer).

	resize_ { arg anInt;
		this.setProperty(\_qc_hSizePolicy, hSizePolicy[anInt-1]);
		this.setProperty(\_qc_vSizePolicy, vSizePolicy[anInt-1]);
		resize = anInt;
	}

Those are merely integer arrays used in the lookup

		hSizePolicy = [1,2,3,1,2,3,1,2,3];
		vSizePolicy = [1,1,1,2,2,2,3,3,3];

I’ve looked at QC_LANG_PRIMITIVE(QObject_SetProperty but I don’t understand from there how the _qc_hSizePolicy magic conversion to sizePolicy works. It might be something that Qt itself does.

Trying to “get them back” the same way doesn’t work though, i.e.

a.getProperty(\_qc_hSizePolicy) // -> nil

These properties - _qc_vSizePolicy and _qc_hSizePolicy - are not specified on the c++ side, they’re just integer properties on the object, that are set from sclang along. This code seems to expect them to exist, and handle them accordingly. This is a rather non-standard way of doing this, and probably should be removed.

1 Like

Ah, I failed to grep the .hpp files (only .cpp, .h didn’t find anything.)