A Qt/Qml integration with .NET
Supported platforms/runtimes:
WIP: https://qmlnet.github.io/
dotnet add package Qml.Net dotnet add package Qml.Net.WindowsBinaries dotnet add package Qml.Net.OSXBinaries dotnet add package Qml.Net.LinuxBinaries
Note for Linux users: Package libc6-dev
is required to be installed because it contains libdl.so
that is needed.
Checkout the examples on how to do many things with Qml.Net.
Define a .NET type (POCO)
//QmlType.cs using Qml.Net; using System.Threading.Tasks; namespace QmlQuickOverview { [Signal("customSignal", NetVariantType.String)] // You can define signals that Qml can listen to. public class QmlType { /// <summary> /// Properties are exposed to Qml. /// </summary> [NotifySignal("stringPropertyChanged")] // For Qml binding/MVVM. public string StringProperty { get; set; } /// <summary> /// Methods can return .NET types. /// The returned type can be invoked from Qml (properties/methods/events/etc). /// </summary> /// <returns></returns> public QmlType CreateNetObject() { return new QmlType(); } /// <summary> /// Qml can pass .NET types to .NET methods. /// </summary> /// <param name="parameter"></param> public void TestMethod(QmlType parameter) { } /// <summary> /// Async methods can be invoked with continuations happening on Qt's main thread. /// </summary> public async Task<string> TestAsync() { // On the UI thread await Task.Run(() => { // On the background thread }); // On the UI thread return "async result!"; } /// <summary> /// Qml can also pass Qml/C++ objects that can be invoked from .NET /// </summary> /// <param name="qObject"></param> public void TestMethodWithQObject(dynamic o) { string result = o.propertyDefinedInCpp; o.methodDefinedInCpp(result); // You can also listen to signals on QObjects. var qObject = o as INetQObject; var handler = qObject.AttachSignal("signalName", parameters => { // parameters is a list of arguements passed to the signal. }); handler.Dispose(); // When you are done listening to signal. // You can also listen to when a property changes (notify signal). handler = qObject.AttachNotifySignal("property", parameters => { // parameters is a list of arguements passed to the signal. }); handler.Dispose(); // When you are done listening to signal. } /// <summary> /// .NET can activate signals to send notifications to Qml. /// </summary> public void ActivateCustomSignal(string message) { this.ActivateSignal("customSignal", message); } } }
Register your new type with Qml.
//QmlExample.cs using Qml.Net; using Qml.Net.Runtimes; namespace QmlQuickOverview { class QmlExample { static int Main(string[] args) { RuntimeManager.DiscoverOrDownloadSuitableQtRuntime(); using (var app = new QGuiApplication(args)) { using (var engine = new QQmlApplicationEngine()) { // Register our new type to be used in Qml Qml.Net.Qml.RegisterType<QmlType>("test", 1, 1); engine.Load("Main.qml"); return app.Exec(); } } } } }
Use the .NET type in Qml
//Main.qml import QtQuick 2.7 import QtQuick.Controls 2.0 import QtQuick.Layouts 1.0 import test 1.1 ApplicationWindow { visible: true width: 640 height: 480 title: qsTr("Hello World") QmlType { id: test Component.onCompleted: function() { // We can read/set properties console.log(test.stringProperty) test.stringPropertyChanged.connect(function() { console.log("The property was changed!") }) test.stringProperty = "New value!" // We can return .NET types (even ones not registered with Qml) var netObject = test.createNetObject(); // All properties/methods/signals can be invoked on "netObject" // We can also pass the .NET object back to .NET netObject.testMethod(netObject) // We can invoke async tasks that have continuation on the UI thread var task = netObject.testAsync() // And we can await the task Net.await(task, function(result) { // With the result! console.log(result) }) // We can trigger signals from .NET test.customSignal.connect(function(message) { console.log("message: " + message) }) test.activateCustomSignal("test message!") } function testHandler(message) { console.log("Message - " + message) } } }
DateTime
, string
, etc).async
and await
with support for awaiting and getting the result from Qml.dynamic
.IList<T>
instance, for modification of list in Qml, and performance.QObject
types to .NET with support for interacting with signals/slots/properties on them.There aren't really any important features missing that are needed for prime-time. This product is currently used on embedded devices in the medical industry.
The unit tests can be found in src/native/Qml.Net.Tests.
They can be run directly from Visual Studio, or by using the dotnet test
command line tool.
Since the tests rely on the native QmlNet library, you have to ensure the library is in the PATH
(on Windows) or otherwise discoverable. If you are trying to run tests against the native library built from the same repository, you can put the src/native/output
folder into your PATH
or LD_LIBRARY_PATH
after running the build.bat
or build.sh
script.
Thanks goes to these wonderful people!
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4