Hi, fellow haxers, and a Happy New Haxing year to you all!
Just found this very interesting multi-target Qt bindings library for Haxe:
Seems to be a very ambitious project with an interop solution that serves the frontend application from a go-lang backend (can not say that I undestand very much of that really works). Along with bindings for Haxe, there are Dart, Flutter and Swift bindings aswell, and more seem to be planned.
The Haxe codebase seems to be autogenerated and covers most basic GUI stuff. It uses Haxe 4.2 module level functions, so itâs obviously created by a guy that has some closer insight in Haxe.
Also, the make.sh project file includes a comprehensive Haxe target report, displaying what works and what doesnât on the ALL different Haxe targets. Interestingly, --interp, jvm, java and cs status is currently âworksâ or âworks-with-warnâ while the the others have compile- or runtime errors.
When trying it out (on windows), I get --interp and jvm targets to compile, but they both give runtime error that seems to be caused in the interop message communication bus running at http://127.0.0.1:8000/.
The error message is the following: No connection could be made because the target machine actively refused it. ⊠so I guess itâs related to windows somehow not letting this interop communication through.
(Tried netsh http add iplisten 127.0.0.1:8000 but id doesnât seem to help.)
As far as I understand it, it pipes the system calls via http calls to a go backend âinterop_serverâ.
The first line in static public main() kicks off this server
// Main.hx
public static function main():Void {
final process = initProcess(); // TODO: NewQApplication
...
}
// TODO: NewQApplication
function initProcess():Process {
final process = new Process("./interop_server", []); // TODO: supply port or interop com channel info
Sys.sleep(3.); // TODO: block and check interop availability instead
return process;
}
After that, all Qt api calls seem to be called to this interop_server as http requests. Here is the complete chain:
// Main.hx main()
...
final quickWidget = NewQQuickWidget(null);
// qt.Quick.hx
function NewQQuickWidget(parent:QWidget_ITF):QQuickWidget {
Quick.initModule();
return Internal.callLocalFunction(["", "", "quick.NewQQuickWidget", "", parent]);
}
// qt.Internal.hx
public static function callLocalFunction(l:Array<Any>):Any {
final msg = haxe.Json.stringify(l);
final output:Any = haxe.Json.parse(syncCallIntoLocal(msg));
...
return convert(output);
}
// qt.Internal.hx
private static function syncCallIntoLocal(msg:String):String {
return httpRequest("syncCallIntoLocal", msg);
}
// qt.Internal.hx
private static function httpRequest(url:String, msg:String):String {
trace('request: $url');
var req = new sys.Http("http://127.0.0.1:8000/" + url);
req.setPostData(msg);
var retData:String;
req.onData = function(data) {
retData = data;
}
req.onError = function(error) {
trace('httpRequest error: $msg -> $error');
}
req.request(true);
return retData;
}
It seems to boot up a seperate instance of the mother project with sys.io.Process and then pass execution orders through it. One thing I see as potentially an issue is the license being LGPL from the main go repo witch requires dynamic linking, unless the source code is open source it self.
I agree Iâve very much wanted a multi target gui solution for Haxe too, One that has the resources I think needed to support all the edge cases and matience to build fully mature gui applications. I think go is an interesting means to achieve these types of libraries into Haxe and one of the reasons Iâve been working on a transpiler these last couple of months, meaning the library source code of another gui library written in go like fyne (11.7k stars,575 forks) in full Haxe code, except for the places that it links to c/c++ in wich case those bindings could be translated to ammer for instance. This however is a decent ways away.
Overall I think this is a great find and Iâd be interested to learn more about the current gui stacks that Haxe has gained acess to or created.
It certainly seems like a novel approach - i dont really get how it all fits together either, but seems like its creating some type of tunnel or something to a Go runtime that âdoes the stuffâ? I wonder how that actually translates to rendering the components etc.
What i dont really understand is why this is better than just using Qt directly from hxcpp? Is the point that then you can use Qt from haxe but compile the haxe to, say, C# or Java? And why is that beneficial? Because you might want to take advantage of some existing .jar or something similar?
From the parent project there is also a JS demo, which seems pretty cool / crazy⊠ie, by the looks of things a Qt app inside a browser - i wonder how that fits together⊠is it WASM or something? Certainly never seen that before (although for me after a little while the JS app hangs, but still pretty cool)
So i guess from my perspective the jury is still out, i mean, it seems pretty cool, but im still stuck on âwhy not just use hxcpp and use qt âas isââ, it also feels like there are alot of moving parts here that look to create some type of friction (ie, the windows build not working for OP and the JS version hanging for me, but maybe thats just initial teething issues)
Ian, I donât think this approach is really âbetterâ in any sense. On the contrary, there must be bottlenecks in the data transformation to/from json as far as I can see. (The developer - still donât know his/her name - mentions Haxe enum support missing, I guess this is connected to this json conversion.)
Whatâs cool about - as I see it - is (theoretical) ease of use and full compatibility on any target that can kick off the backend sys process needed. Combined with fast compiletime as Qt libraries live on the âbacksideâ and never have to be compiled/linked in. To be able to prototype an admin tool with Qt Gui run it in --interp would be ⊠very cool! Ideally, when time for release, it would be a flick of a switch to compile natively using HxQt.
PXshadow, best luck with your Haxe/Go projects! The Go/Fuse combo will be a great addition to the Haxe eco sys when that day has comeâŠ! Thank you also for highlighting the LGPL âissueâ.
The fast iteration via interp is an interesting angle, but its worth noting that the âit would be a flick of a switch to compile natively using HxQtâ (if im understanding correctly) wouldnt be the case⊠its not code that would be compatible with Qt (hxQt or code generated by hxcpp in general). ie, in the repo you dont ânewâ anything in haxe code, you do things like:
final view = NewQGraphicsView(null);
And presumably that tells a backend to perform the object creation so there is no âswitch to flipâ, you are defo locked into this way of doing things - at least thats my very basic understanding of how this works. I do think, however, you can get this backend to compile and download an actual exe (at least you can on the js example - this also hangs fyi).
All in all, i really dont have clue how this works⊠And in total honesty, i cant see myself using it anytime soon⊠it feels really complex compared to Haxe => hxcpp => Qt⊠But maybe im missing something 8.1k people arent
A similar route for Haxe users would be to build a cppia host that has Qt in it and then compile to cppia for iteration and cpp for release. However creating the necessary hxcpp bindings for Qt is probably a considerable amount of work.
creating the necessary hxcpp bindings for Qt is probably a considerable amount of work
Im not sure that would be the case, hxQt already has (limited) bindings that seem to work and an experimental haxeui-qt can also use those bindings for qt UIâs - abstracted into haxeuiâs framework ofc (image below is just using hxQt, not haxeui as i dont feel its anywhere near ready for consumption yet):
The bindings are hand crafted (and as i mentioned, quite limited component wise), and it would obviously be much nicer if they were generated somehow, but i just havent had any real time to get my teeth into this again (though im certainly going to revisit it at some point - hopefully soon).
As for iteration speed, maybe im just too used to c++ build times, but with the hxcpp compiler cache, making changes to the above project and running takes like 1 second⊠maybe thats slow to some people⊠dunno, for me thats perfectly acceptable (ive worked on c++ projects that took like 30 mins plus to do a clean build, so maybe im not a great judge of âfast compilesâ )
Ideally, when time for release, it would be a flick of a switch to compile natively using HxQt.
Yes, Qt->Go backend and Qt->native are of course completely different animals, and that flick-of-a-switch would require another abstraction layer. (Maybe a HaxeUI backend could be possible if Qt->Go will be seen to deliver more than just an interesting poc.)
A similar route for Haxe users would be to build a cppia host that has Qt in it and then compile to cppia for iteration and cpp for release.
Yes, indeed. The cppia target sadly seems to be severly underused, and a simple workflow for quickly setting up Qt GUI apps would be a great showcase to shed the light it deserves on itâŠ
A quick test using cppia and HxQt: I doesnât work because some of the extern classes (qt.core.Application for example) use native untyped cpp-code: untyped __cpp__('char *argv[] = {NULL};'); etc. (The compiler explicitly notifies this.)
Ammer could theoretically be used with the eval target, but it seems to be a fairly complicated process right now, where Haxe has to be compiled from source using plug in. Hopefully this could be simpler in the futureâŠ