-
-
Notifications
You must be signed in to change notification settings - Fork 55
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Widget bindings should be generated - Lots of widgets are missing #63
Comments
The set of QWidgets supported by Svelte NodeGUI
Svelte NodeGUI supports all the widgets that React NodeGUI does (unless I've missed any, but I did look quite hard), plus QSvg. The full set is listed here: svelte-nodegui/src/svelte-nodegui.ts Lines 62 to 158 in 1ce01eb
The Svelte NodeGUI docs (which are incidentally just a copy-paste of the React NodeGUI docs, with some find-and-replace applied and manual code examples added) are evidently missing a large number of the supported widgets. Contributions are welcomed on that front.
I'd say 24 widgets is a good start, to be fair – for example, React Native provides 21 cross-platform core components, plus two iOS-specific ones and two Android-specific ones. We've recently merged two PRs to add extra widgets (namely <svg> and <scrollArea>), so I think that the barrier to adding new widgets from NodeGUI is also quite low. Adding support for new Qt widgets to Svelte NodeGUI
I know it's missing the point, but I might as well explain the wiring code while we're on the subject. The wiring code in that file, index.ts, corresponds to the React custom renderer APIs. You generally don't need to touch much, if anything, in those files; just copy-paste them and make the naming consistent. The only things to think about would be To add support for a Svelte NodeGUI component, the minimum is to create an React NodeGUI element following the pattern set out in the self-named files like RNComboBox.ts. The methods are:
Automating bindings
Automating generating the bindings from Qt all the way to Svelte NodeGUI would of course be the holy grail (and I'll never disregard the idea), but I'll get into the challenges involved that I think are show-stoppers to automation. We actually use automation to a certain extent on Svelte Native and React NativeScript to map NativeScript typings to JSX, but even with that successful tool, we can see that it wouldn't transfer to mapping the runtime APIs to equivalent DOM methods due to the number of exceptional cases and lack of consistency. I haven't looked into how Atul generates the NodeGUI bindings for the Qt widgets, but I wouldn't be surprised if a certain amount of it is automated. Though as there are various missing Qt APIs, maybe it is all a manual process. Mapping the Qt widget APIs to DOM methods is the ultimate goal, and sadly I don't think this is realistically possible to automate, because Qt doesn't have a consistent API for managing the element tree. For example, how would you add a child QWidget to QMainWindow? You'd need to look at the docs to determine that it's Setting attributes is also a pain. You will see various cases in RNView where the setters are not simple cases of calling What Qt needs is a consistent set of APIs for getting/setting attributes and inserting/removing widgets into a hierarchy, such as the DOM model. If that existed, then renderers like React NodeGUI wouldn't need to manually map each widget to consistent APIs. Unfortunately, unless a project like that exists and has been completed, then we're stuck doing things manually. |
Hi Jamie, first off, thank you for your very detailed response! I appreciate it.
Thanks. That's the list of widgets I had found and looked at.
Indeed, what you and Atul accomplished here is seriously impressive. I love the concept. This is no small feat, and that you two developers got this done, probably not even as full time job, really speaks to your competence. I've written similar frameworks in the past, and I know it's hard, and a lot of work. You can be very happy about your accomplishment. Respect. What I try to do is also challenging: I would like to implement a mail client on a quality and usability level on par with (or better than) Thunderbird or Outlook, for all 5 major platforms (desktop and mobile). You can probably see easily that the widget list above is not even close to sufficient for a project of this nature. I'm looking at https://doc.qt.io/qt-5/widget-classes.html , and a lot of them will be useful, but there are a number that are not yet supported and absolutely necesssary:
That's just the start, the absolute minimum. And that's just for the prototype - the final app likely will need more. It's going to take a while to map all these manually, with their entire API respective surface. I will not be able to do that, nor can I ask you to do it. Hence, my suggestion here.
Yes, I see what you mean. Thanks for the concrete example, that helps me to understand the problem. It might be possible to solve that generically, if the generator understands the types, that a
RNComboBox.ts looks very repetetive and straight-forward. Would it be a reasonable approach to create a declarative (e.g. plaintext) list of attributes per widgets, and then generate these setters and getters from that list, instead of manually writing these setters and getters? Then, as a second step, one could see whether that list could be generated from the Qt header files. The header parser would consider not only the function names, but also their parameter types. That's just an idea. What do you think? |
That sounds like a nice fit for a Qt app indeed. I've not seen any prior art on deploying NodeGUI to mobile via Qt for mobile, however, so it's uncharted territory.
True, those are missing from NodeGUI.
Indeed, the browser view alone probably has an enormous API surface. Yes, I agree that an automated process for producing bindings from Qt to NodeGUI would be ideal, though I don't have the expertise to help with that. The mapping of APIs from Qt to NodeGUI is non-trivial and I don't know how realistic it would be to automate it. You have to determine how to marshal the Qt C++ values into equivalent JS abstractions, and also have to handle the memory management. Even doing this manually when trying to add the It won't be possible to auto-generate bindings without first creating a way to marshal each and every Qt type into a Napi equivalent. This is an unrealistically large task (on the scale of building NativeScript, but for the Qt runtime instead of iOS/Android), so I think the train stops here, unfortunately.
I ran into exactly this when building a React renderer for NativeScript, and there were so many edge cases that I think if we were going to automate the mapping from NodeGUI to React NodeGUI, it would be most prudent to just automatically map as many APIs as possible, but for any case where a QObject is a param, simply write out a stub saying "this API needs to be filled in manually" to be addressed in a post-processing step. There are enough NodeGUI components still missing from React NodeGUI that there would be some benefit in writing a tool, using ts-morph, probably, to automate some of this. But there's still no way around the issue of mapping Qt to NodeGUI in an automated fashion, which unfortunately is the most important part for supporting the full Qt API surface.
I don't know exactly how Atul wrote out the getters and setters, but it may be that he started with a similar process – maybe not automated, but nonetheless quick. With multi-line text editing, the task is pretty small if you're only concerned with doing one component. For a large batch of components, something like the ts-morph idea may have some value.
Again, this comes back to the issue of needing a tool to marshal values from Qt to NodeGUI in order to be of any use. I suppose at least having the API stubs for contributors to fill in would be handy, though, so that we'd have a proper picture of how many APIs are missing. But that's a discussion to bring up with Atul as it concerns NodeGUI itself. |
Svelte NodeGUI sounds just what I need for my application.
The docs list only a number of very basic widgets.
These seem to be implemented in React NodeGUI, and Svelte NodeGUI just bridges over the React implementations.
For my real world application, I need a much larger number of Qt widgets. Without more widgets, I cannot even make a feasability study whether Svelte NodeGUI is suitable for my application, because the current set of widgets is just too small to find out whether it would work. Theoretically, I could add the widgets myself, but there are too many missing.
However, I am faced with 5 layers of abstraction:
This makes it difficult to add new widgets, because I need to understand a lot of intermediate wiring code, to add a widget. Worse, the mappings seem to be hand-written.
May I suggest a different approach? Why don't you take the Qt widget API descriptions in computer-readable form, and then use Swig or a custom-made software to generate the bindings, for NodeGUI and each of React/Vue/Svelte NodeGUI?
This would have the following advantages:
The text was updated successfully, but these errors were encountered: