Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

qmlnet/qmlnet

Open more actions menu

Repository files navigation

Qml.Net

A Qml integration with .NET

Qml.Net Build status Build status

Supported platforms/runtimes:

  • Runtimes:
    • .NET Framework
    • .NET Core
    • Mono
  • Operating systems
    • Linux
    • OSX
    • Windows

The idea

Define a .NET type (POCO)

[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>
    /// Qml can also pass Qml/C++ objects that can be invoked from .NET
    /// </summary>
    /// <param name="qObject"></param>
    public void TestMethodWithQObject(dynamic qObject)
    {
        string result = qObject.PropertyDefinedInCpp;
        qObject.MethodDefinedInCpp(result);
    }
    
    /// <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>
    /// .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.

using (var app = new QGuiApplication(r))
{
    using (var engine = new QQmlApplicationEngine())
    {
        // Register our new type to be used in Qml
        QQmlApplicationEngine.RegisterType<QmlType>("test", 1, 1);
        engine.loadFile("main.qml");
        return app.exec();
    }
}

Use the .NET type in 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)
      }
    }
}

Getting started

Step 1: Install NuGet package

dotnet add package Qml.Net

Step 2: Setup native binaries

Windows

dotnet add package Qml.Net.WindowsBinaries

The Qml.Net.WindowsBinaries contains an entire portable Qt install, for Windows (64-bit only).

OSX

dotnet add package Qml.Net.OSXBinaries

The Qml.Net.OSXBinaries contains an entire portable Qt install, for OSX (64-bit only).

Other platforms

Currently, native NuGet packages are not shipped for Linux/OSX. You have to build the QmlNet project manually.

  1. Install Qt (at least 5.9) and Qt Creator.
  2. Build and deploy src/native/QmlNet/QmlNet.pro.
  3. Massage your PATH/LD_LIBRARY_PATH/DYLD_LIBRARY_PATH to contain the path that you've deployed the native QmlNet library.

There is an on-going effort to make native Qml.Net.OSXBinaries and Qml.Net.LinuxBinaries NuGet packages. See here: (#33)

Currently implemented

  • 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 and await with support for awaiting and getting the result from Qml.
  • Passing dynamic javascript objects to .NET as dynamic.

Not implemented (but planned)

  • Compiling Qml resource files and bundling them within .NET.
  • Passing QObject types to .NET with support for interacting with signals/slots/properties on them.
  • .NET Events to signals
  • Custom V8 type that looks like an array, but wraps a .NET IList<T> instance, for modification of list in Qml, and performance.
  • General perf improvements (particularly with reflection).

About

Qml.Net - Qt/QML integration/support for .NET

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 16

Morty Proxy This is a proxified and sanitized view of the page, visit original site.