Skip to content
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

calling QML from Rust #22

Open
kirillkh opened this issue Jun 23, 2015 · 15 comments
Open

calling QML from Rust #22

kirillkh opened this issue Jun 23, 2015 · 15 comments

Comments

@kirillkh
Copy link
Contributor

Is it possible to call QML functions from Rust?

@cyndis
Copy link
Owner

cyndis commented Jun 24, 2015

The proper way to do this would be to support defining signals on the Rust side; the C++ wrapper library already supports this and the Rust side also once upon a time used to support them, but the implementation was horrible hack that mungled with internal Rust representations and was not memory safe either.

So not really right now, but it could be implemented. The hard part is making a nice and safe Rust interface for signals.

@kirillkh
Copy link
Contributor Author

Well, it seems to me a lot of functionality is missing when you can't communicate with the GUI from your rust code. My project certainly needs this.

@cyndis
Copy link
Owner

cyndis commented Jun 24, 2015

Yes, that is true. Unfortunately the time I have been able to spend on this project lately has been very low.

@flanfly
Copy link

flanfly commented Jul 6, 2015

I'd be willing to implemented it if I knew what's the problem with the current solution. Looking at the commented-out code signals are identified by their signature via string comparison and invoked using QMetaObject::activate on the C++ side. That's pretty much the same what go-qml and pyside does.

@cyndis
Copy link
Owner

cyndis commented Jul 6, 2015

There are a couple of issues, nothing really fundamental. Mostly figuring out how to present things in a safe way.

  1. How to emit a signal from code? How would the Rust code get ahold of a *mut QObject to emit a signal from. The current code in lib.rs uses PropHdr which kind of works but is horribly unsafe, since there's nothing to prevent the user from copying his data somewhere else. If the user does that, the copy will still be T: Object but it will not be inside a PropHdr.
  2. How would the Rust code get ahold of a &T where T: Object. Currently add_property consumes the object which means that only a slot can emit a signal which isn't very useful.
  3. How would signals be declared in Rust code. The Q_OBJECT macro used to work but was broken during stabilization changes before 1.0. I'm not a macro expert, though, so there might be a workaround. The macro will likely require an overhaul anyway to be able to support things like lifetime parameters. To get rid of PropHdr we might also need to change the data layout such that the user's type will contain some reference to the backing *mut QObject.

Thanks :)

@cuzbog
Copy link

cuzbog commented Oct 1, 2015

Any news on this? I need to be able to send signals from Rust in my project

@flanfly
Copy link

flanfly commented Oct 1, 2015

I extended qmlrs to allow emitting signals in Rust code as well as defining singleton type that allows QML code to call Rust functions.

The code isn't really PR-ready. I ignore thread-safety completely, the Q_OBJECT! macro is broken and I don't know if the API is usable outside of my limited use-case.

You can take a look on it here: https://github.com/das-labor/panopticon/blob/master/qt/src/controller.rs

@filcuc
Copy link

filcuc commented Apr 28, 2016

Hi everyone, i'm the author of the DOtherSide C++ library that basically implements a C layer for creating bindings to the Qml layer. I developed the DQml and NimQml bindings. Maybe we can work together by porting your C++ code to my library. In this way we can arrive at a common implementation for Nim, D and Rust. Furthermore i find it stupid to rewrite the C++ part. Btw the DOtherSide project already support creation of singletons, custom types, signals, slots. You should just call the C functions for having the work done. :)

@filcuc
Copy link

filcuc commented Apr 28, 2016

@colms
Copy link

colms commented Apr 30, 2016

Do you think it's possible to have safe Rust code work with your OtherSide implementation?

@filcuc
Copy link

filcuc commented Apr 30, 2016

It depends on what do you mean with safe. I'm not a rust expert and i just
slightly know the language but i don't think that it's possible to call C
functions outside unsafe blocks.
Given that, my library tries to be as safe as possible, for example right
now i'm preventing accessing QObjects instantiated by someone different
than the binded language.
If you want to do such kind of things do that in QML. Regarding the thread
safety my library doesn't do any assumption: it's up to the binded language
to decide how to handle
threading (keeping in mind that anything that mess with the UI should be
done by the UI thread [ that should be the main thread]).

2016-04-30 11:28 GMT+02:00 colms notifications@github.com:

Do you think it's possible to have safe Rust code work with your C++
implementation?


You are receiving this because you commented.
Reply to this email directly or view it on GitHub
#22 (comment)

Filippo Cucchetto

@florianjacob
Copy link
Collaborator

@filcuc I was intending to rewrite qmlrs based on libqmlbind, see #22 for the discussion. I was not aware that there is a competitor to libqmlbind, though.

Is there any documentation for DOtherSide, especially on how it can be used from a library author's point of view? I can't find any, so it's hard for me to spot the differences between DOtherSide and libqmlbind. Or could you compare DOtherSide to libqmlbind?

(libqmlbind's documentation can be found at https://seanchas116.github.io/libqmlbind/)

In any case, I'll list DOtherSide as an alternative to libqmlbind: seanchas116/libqmlbind#40

@florianjacob
Copy link
Collaborator

@colms A safe Rust interface will be possible regardless of the underlying backend library. 😄 That's the main job of qmlrs if you take the C wrapper away - creating a safe rust interface without exposing the unsafeness of the used C functions. 😉

@filcuc
Copy link

filcuc commented May 10, 2016

@florianjacob @colms as long as the C library is "safe" :D

@florianjacob
Probably i cant' convince you in anyway in adopting my library over libqmlbind since you seems to be a strong contributor but i'll try to answer to your questions:

Is there any documentation for DOtherSide?
how it can be used from a library author's point of view

We've two complete bindings in place DQml and NimQml. The logic is more or less the same in both bindings. I think that there's no better example that a full binding for a different language.
The library aim to be small and expose only the needed stuff for making full databound applications. So it doesn't expose any QObject* that wasn't created by the bindings. All the api's are in 1 single file of 150 lines.

Or could you compare DOtherSide to libqmlbind?

From the outside they're very similar if not identical. Both are

  • portable. At the time of writing the DOtherSide is automatically packaged for Windows and Linux but it has already been built successfully for Mac by some users.
  • small
  • use similar conventions _create (_new) _delete (_release)

On the other hand i don't know the internals but i can guess that they both works the same more or less.

For the rest the DOtheSide library:

  • Already support QAbstractItemModels
  • Support QML Singletons
  • Support instantions of custom QObjects defined in the binded language from QML. So you can create custom QML types.
  • Proved to work with two different languages and by improving the underlying library all the bindings could benefit and improve. Rust could be a further prove that the design works
  • DOtherSide was started before libqmlbind

@vandenoever
Copy link

Support for QAbstractItemModels in qmlrs would be very welcome. It can be emulated a bit by populating a ListModel via JavaScript that calls into Rust.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants