- Notifications
You must be signed in to change notification settings - Fork108
Qml.Net - Qt/QML integration/support for .NET
License
qmlnet/qmlnet
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
A Qt/Qml integration with .NET
Supported platforms/runtimes:
- Runtimes:
- .NET Framework
- .NET Core
- Mono
- Operating systems
- Linux
- OSX
- Windows
- Proven in production.
- Established GUI/control framework, used in many industries, from desktop to embedded.
- Excellent community with many open-sourced controls available.
- Native rendering, done in native code. No expensive PInvoke calls for rendering/animations/etc. The only interop between .NET and Qt is the data models used to drive the GUI.
dotnet add package Qml.Netdotnet add package Qml.Net.WindowsBinariesdotnet add package Qml.Net.OSXBinariesdotnet add package Qml.Net.LinuxBinaries
Note for Linux users: Packagelibc6-dev
is required to be installed because it containslibdl.so
that is needed.
Checkout theexamples on how to do many things with Qml.Net.
Define a .NET type (POCO)
//QmlType.csusingQml.Net;usingSystem.Threading.Tasks;namespaceQmlQuickOverview{[Signal("customSignal",NetVariantType.String)]// You can define signals that Qml can listen to.publicclassQmlType{/// <summary>/// Properties are exposed to Qml./// </summary>[NotifySignal("stringPropertyChanged")]// For Qml binding/MVVM.publicstringStringProperty{get;set;}/// <summary>/// Methods can return .NET types./// The returned type can be invoked from Qml (properties/methods/events/etc)./// </summary>/// <returns></returns>publicQmlTypeCreateNetObject(){returnnewQmlType();}/// <summary>/// Qml can pass .NET types to .NET methods./// </summary>/// <param name="parameter"></param>publicvoidTestMethod(QmlTypeparameter){}/// <summary>/// Async methods can be invoked with continuations happening on Qt's main thread./// </summary>publicasyncTask<string>TestAsync(){// On the UI threadawaitTask.Run(()=>{// On the background thread});// On the UI threadreturn"async result!";}/// <summary>/// Qml can also pass Qml/C++ objects that can be invoked from .NET/// </summary>/// <param name="qObject"></param>publicvoidTestMethodWithQObject(dynamico){stringresult=o.propertyDefinedInCpp;o.methodDefinedInCpp(result);// You can also listen to signals on QObjects.varqObject=oasINetQObject;varhandler=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>publicvoidActivateCustomSignal(stringmessage){this.ActivateSignal("customSignal",message);}}}
Register your new type with Qml.
//QmlExample.csusingQml.Net;usingQml.Net.Runtimes;namespaceQmlQuickOverview{classQmlExample{staticintMain(string[]args){RuntimeManager.DiscoverOrDownloadSuitableQtRuntime();using(varapp=newQGuiApplication(args)){using(varengine=newQQmlApplicationEngine()){// Register our new type to be used in QmlQml.Net.Qml.RegisterType<QmlType>("test",1,1);engine.Load("Main.qml");returnapp.Exec();}}}}}
Use the .NET type in Qml
//Main.qmlimportQtQuick2.7importQtQuick.Controls2.0importQtQuick.Layouts1.0importtest1.1ApplicationWindow{visible:true width:640 height:480 title:qsTr("Hello World")QmlType{ id:testComponent.onCompleted:function(){// We can read/set propertiesconsole.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)varnetObject=test.createNetObject();// All properties/methods/signals can be invoked on "netObject"// We can also pass the .NET object back to .NETnetObject.testMethod(netObject)// We can invoke async tasks that have continuation on the UI threadvartask=netObject.testAsync()// And we can await the taskNet.await(task,function(result){// With the result!console.log(result)})// We can trigger signals from .NETtest.customSignal.connect(function(message){console.log("message: "+message)})test.activateCustomSignal("test message!")}functiontestHandler(message){console.log("Message - "+message)}}}
- Support for all the basic Qml types and the back-and-forth between them (
DateTime
,string
, etc). - Reading/setting properties on .NET objects.
- Invoking methods on .NET obejcts.
- Declaring and activating signals on .NET objects.
async
andawait
with support for awaiting and getting the result from Qml.- Passing dynamic javascript objects to .NET as
dynamic
. - Custom V8 type that looks like an array, but wraps a .NET
IList<T>
instance, for modification of list in Qml, and performance. - Dynamically compiled delegates for increased performance.
- Passing
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 insrc/native/Qml.Net.Tests.
They can be run directly from Visual Studio, or by using thedotnet test
command line tool.
Since the tests rely on the native QmlNet library, you have to ensure the library is in thePATH
(on Windows) or otherwise discoverable. If you are trying to run tests against the native library built from the same repository, you can put thesrc/native/output
folder into yourPATH
orLD_LIBRARY_PATH
after running thebuild.bat
orbuild.sh
script.
Thanks goes to these wonderful people!
Michael Lamers 💻 | TripleWhy 💻 | Max 💻📖💵 | geigertom 💻 | James Davila 💻 | Andy Fillebrown 💻 | Vadim Peretokin 📖 |
Linus Juhlin 📖 |
About
Qml.Net - Qt/QML integration/support for .NET