Code Monkey home page Code Monkey logo

qmlnet-examples's Introduction

Qml.Net Build status Build status Gitter All Contributors Donate


A Qt/Qml integration with .NET

Supported platforms/runtimes:

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

First look

Elevator pitch

  • 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.

Documentation

WIP: https://qmlnet.github.io/

Getting started

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.

Examples

Checkout the examples on how to do many things with Qml.Net.

Quick overview

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)
      }
    }
}

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.
  • 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.

Running Unit Tests

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.

Contributors โœจ

Thanks goes to these wonderful people!

Michael Lamers
Michael Lamers

๐Ÿ’ป
TripleWhy
TripleWhy

๐Ÿ’ป
Max
Max

๐Ÿ’ป ๐Ÿ“– ๐Ÿ’ต
geigertom
geigertom

๐Ÿ’ป
James Davila
James Davila

๐Ÿ’ป
Andy Fillebrown
Andy Fillebrown

๐Ÿ’ป
Vadim Peretokin
Vadim Peretokin

๐Ÿ“–
Linus Juhlin
Linus Juhlin

๐Ÿ“–

qmlnet-examples's People

Contributors

ace4896 avatar aerotog avatar maxmommersteeg avatar pauldotknopf avatar triplewhy avatar vadi2 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

qmlnet-examples's Issues

How to package/release this application

How do I properly package/release this application. It outputs an executable but when I open that it looks for Main.qml so I have to copy that to the Output directory , also it opens a console.

  1. How can I package it in such a way that when I click the executable , it doesn't open a console?

    Edit: I found the answer here qmlnet/qmlnet#80

  2. How do I bunde the QML files inside the executable?

QWindowsContext: OleInitialize() failed: "COM error ...

Hello,

Every time I run the example project, or any project, I get a console window appear displaying the following error:

QWindowsContext: OleInitialize() failed: "COM error 0xffffffff80010106 RPC_E_CHANGED_MODE (Unknown error 0x080010106)"

The program continues and seems to work fine... but any idea why is this happening?

Thanks!

Off thread example?

Not sure if this is the right place for this, my apologies if it is.

I have tried to follow the photoframe example but got a bit lost...

Anyways I was wondering if you could either advise a method or provide a brief example of binding a listview to a .net model class with a list and having a separate thread / Task.Run scope which receives some remote data and loads the results onto the UI.
My need for this is receiving websocket data and displaying the results in the UI and most importantly having the UI update as new data comes in through a socket.

I got a basic version working by using your photoframe sample as inspiration.

Essentially I registered a Singleton class at startup and when it completed loading on the UI I started the websocket in a Task.Run block and stored the results in a class list property.
I can load the data into the UI if I load another page and navigate back to the page which displays the data. But I haven't been able to get the page to reload the UI control on the page as in your collections model example.

Hopefully this is formatted correctly as I'm on my phone.

System.Net.Http.HttpRequestException

at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at System.Net.Http.HttpConnectionPool.CreateConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at System.Net.Http.HttpConnectionPool.WaitForCreatedConnectionAsync(ValueTask`1 creationTask)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.DiagnosticsHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.FinishSendAsyncUnbuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
   at System.Net.Http.HttpClient.FinishGetStreamAsync(Task`1 getTask)
   at Qml.Net.Runtimes.RuntimeManager.GetUrlStream(String url, Action`1 action)
   at Qml.Net.Runtimes.RuntimeManager.DiscoverOrDownloadSuitableQtRuntime(RuntimeSearchLocation runtimeSearchLocation)
   at Features.Program.Main(String[] args) in C:\VisualStudio_Projects\home\bradley.phillips\work\qmlnet-examples\src\Features\Program.cs:line 12

How to run

I am newer in QT, How I run the demo ? I use command "dotnet publish" ,then I cd to the publish dir. command "dotnet Features.dll" but There is nothing happen. PS: I have install QT5.13 on my windows

TypeInitializationException on Linux 18.0.4

I tried the project Features on my development machine Windows 10-64 bit.
When I launch it from Visual Studio 2017, I get the following error message in the console window:
"QWindowsContext: OleInitialize() failed: "COM error 0xffffffff80010106 RPC_E_CHANGED_MODE (Unknown error 0x080010106)""
The error message appears on the line 13, using (var application = new QGuiApplication(args)).

However, this error doesn't brake the application; the application continues and works fine.

Then I tried it to on Linux 18.0.4, the one from Windows Store. I used the following publish configuration in Visual Studio:
image

When I launched the application I got TypeInitializationException:
image

Then I tried some other publish configurations, but none of them was successful.

Then I commented out the line QQuickStyle.SetStyle("Material"), but I got the same exception(of course with a different stack trace).

Then I created a "Hello World" console application that targets the same netcoreapp2.2. I wanted to be sure that I installed correctly the .netcore 2.2 on Linux. The application works fine on Linux.

Is there something I am doing wrong?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.