Creating an object in C++ and utilizing it in QML

Is it possible to use a factory class in C++ to create objects that can be accessed in QML? How can I access a newly created object in QML using JavaScript?

In my C++ factory class, I have implemented the creation of an employee object, which can be of type Manager, SalesPerson, or Engineer, all derived from the base class Employee. Below is the code snippet:

class EmployeeFactory : public QObject
{
    Q_OBJECT
public:
    enum
    {
        MANAGER,
        SALES_PERSON,
        ENGINEER
    };
    explicit EmployeeFactory(QObject *parent = 0);

    Q_INVOKABLE Employee *createEmployee(int type)
    {
        if (type == MANAGER )
        {
            qDebug() << "createEmployee(): Manager created";
            return new Manager;
        }
        else if(type == SALES_PERSON)
        {
            qDebug() << "createEmployee(): SalesPerson created";
            return new SalesPerson;

        }
        else if(type == ENGINEER)
        {
            qDebug() << "createEmployee(): Engineer created";
            return new Engineer;
        }

        qDebug() << "createEmployee(): Nothing created";
        return 0;
    }


signals:

public slots:
};

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;

    EmployeeFactory * factory = new EmployeeFactory;

    qmlRegisterType<Employee>("MyModel", 1, 0, "employee");

    engine.rootContext()->setContextProperty("factory", factory);

    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    return app.exec();
}

Now, I am facing a challenge in my QML script when trying to create and access an employee object.

Window {
    visible: true

    MouseArea {
        anchors.fill: parent
        onClicked: {

            // How do I access the return value `employee` here or how
            // do I return/access employee here?
            employee e = factory.createEmployee(0) // This doesn't work and results in an Expected token ';' error

            // Once I have the employee, I would like to set its attributes like
            // e.name: "David"
        }
    }

    Text {
        text: qsTr("Hello World")
        anchors.centerIn: parent
    }
}

Answer №2

If your team members are based on QObject, you won't have to do anything special to use them in QML, as the meta system will handle it for you. The downside is that QObject can be quite large, so if you have a huge number of team members, it may not be ideal. However, for smaller teams of tens of thousands or less, it should be fine.

Since JavaScript is not a strongly typed language, instead of employee e =..., you would use

var e = factory.createEmployee(0)
. If you want to specify the type in properties, you'll need to register it as a QML type using either qmlRegisterType() or qmlRegisterUncreatableType(). The latter allows the type to be accessed and used but not created from QML.

I'm assuming you've already made the factory available as a context property.

If you prefer your team members not to be derived from QObject, you can register them with the Qt meta type system using Q_DECLARE_METATYPE(). This enables you to use them as parameters in QML. Alternatively, you could use a model to manage and expose the members as model roles, requiring implementation of something like QAbstractListModel.

When creating QObject-based objects from C++ and using them in QML, consider the object's lifetime. You can specify whether QML or C++ manages the ownership and lifetime. Be cautious of potential issues such as QML deleting objects still in use, which could lead to crashes. In more complex, dynamic scenarios, QML ownership behavior may seem cumbersome, but for typical usage, it should be acceptable.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

When transmitting JSON data from the View to the Controller in ASP.NET MVC, the received values are

I'm facing an issue with sending JSON data from an MVC View to Controller. All I seem to get in the Controller is: https://i.sstatic.net/4pKNF.png The JSON I send in Url.Action looks like this: (I create it myself by adding arrays together using .pu ...

`Storing modified PDF containing interactive form elements using integrated Chrome viewer and transferring it to a remote server`

Our current setup utilizes the default embedded Chrome PDF viewer to showcase a PDF document with interactive form fields, enabling users to conveniently fill out the form. Once completed, they can click on the download button to save the form with or with ...

Tips on how to conditionally render a button based on the presence of a link from a separate file in React

I've been working on my personal portfolio site using React and Tailwind. One challenge I'm facing is how to display the "GitHub" button for each project card only when a GitHub link is provided in my data.js file. Currently, I'm utilizing ...

What is the best way to use appendChild within an AJAX get function to manipulate the DOM

I've been working on a code function where I try to append a list item (li) into the HTML received in 'msg', but it's not functioning properly. Any ideas why? function handleFileSelect(evt) { var files = evt.target.files; $(&ap ...

Using Jquery Chosen Plugin to Dynamically Populate One Chosen Selection Based on Another

Good evening to all, please excuse any errors in my English. I have successfully integrated a jQuery Chosen plugin with my 'estado' field (or province). My goal is to populate another jQuery Chosen plugin with the cities corresponding to that s ...

Customizing the SDL Output in a C++ Command Prompt Window

Is there a way to display the output of COUT in the cmd window while using SDL? If it is possible, can someone explain how to achieve this? ...

What distinguishes res.send from app.post?

I'm just starting to learn about express and HTTP. I've heard that the express library has app.get, app.post, and res.send methods. From what I gather, app.get is used for GET requests and app.post is used for POST requests. How does res.send fit ...

The module in the relative path cannot be located by Node.js

Node.js is giving me some trouble with exporting and importing classes from multiple files. In one file, I have two classes that I'm exporting using the following code: module.exports = {TrigInter, Hilbert}; However, when I try to import these classe ...

Refresh a row in real-time by utilizing a modal with JavaScript or jQuery

Is there a way to dynamically edit and update a previously submitted row (category name) in a table? I am able to edit a row by clicking on an edit button and displaying a modal with the current value. However, I am facing a challenge when trying to submit ...

Sending data from a bespoke server to components within NextJS

My custom server in NextJS is set up as outlined here for personalized routing. server.js: app.prepare() .then(() => { createServer((req, res) => { const parsedUrl = parse(req.url, true) const { pathname, query } = parsedUrl ...

Opening a window using Javascript with a PHP Ajax response

I'm attempting to use echo in a controller to return the content below in an AJAX response: $url = url('/expert-profile-view')."/".$request->ticket_id."/".$key->user_id; $url = "<a onclick='window.open('$url','m ...

Ways to customize the appearance of a unique component

I'm faced with a challenge where I need to make edits to a component that is not editable: import * as React from 'react' import styled from '@emotion/styled' import FlexRow from '../../layouts/FlexRow' const RowContaine ...

The SCORM content is not establishing a connection with the Learning Management System

Despite initializing, the SCORM package is failing to communicate with the LMS and throwing an error: No SCORM implementation found. Below is my folder structure: -index.php -player.php -course/SCORM-course (directory) -wrap.js -SCORM_2004_APIWrapper.js ...

The attempt to create the module Application was unsuccessful because of an error stating that the module 'Application' is not accessible

While attempting to utilize fiddle from http://jsfiddle.net/animaxf/uXbn6/4779/, I encountered an issue. When forking the fiddle, it functions correctly. However, when copying and creating a new application (as seen at: http://jsfiddle.net/rishi007bansod/a ...

Scaling a mesh and BufferGeometry vertices using THREE.OBJLoader

Utilizing the THREE.OBJLoader, I successfully loaded a 3D model into my scene. Subsequently, I have the necessity to scale it by 10 and then extract its vertices position. I am aware that the THREE.OBJLoader provides a BufferGeometry, allowing me to acce ...

Storing Mongoose records with null sub-document collections leads to a duplicate key constraint violation

I have encountered an issue with two mongoose schemas that I am working with. var productSchema = new Schema({ name: { type: String, required: true, unique: true }, ... }); ... var categorySchema = new Schema({ ... products: [ProductSchema ...

An intuitive approach to adding a CheckBox control within a GridView using JavaScript and SPAN elements

Struggling to calculate the total quantity from the gridview for checked row checkboxes? Having trouble accessing the checkbox control in your JavaScript? Below is the code snippet you provided, but it's not returning anything. <table cellspaci ...

I've noticed the cookie named (_op_aixPageId) on multiple websites - can someone please explain what it is

Hello, our team recently conducted a scan of our website to ensure PCI compliance and discovered an unsecured cookie associated with our domain called (_op_aixPageId). Despite searching through our entire code base, we were unable to find any references ...

Certain CSS styles for components are missing from the current build

After building my Vue/Nuxt app, I noticed that certain component styles are not being applied. In the DEVELOPMENT environment, the styles appear as expected. However, once deployed, they seem to disappear. All other component styles render properly. Dev ...

What is the process for removing a range of keys from indexeddb?

I need help deleting keys that start with tracklist/RANDOM_STRING and 'songBook/RANDOM_String'. I attempted to do this using IDBKeyRange but I am struggling to understand how it works. The documentation I referred to was somewhat confusing: Mdn ...