Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. International
  3. French
  4. Qt/QML Exposer une variable C++ au QML
Forum Updated to NodeBB v4.3 + New Features

Qt/QML Exposer une variable C++ au QML

Scheduled Pinned Locked Moved Unsolved French
1 Posts 1 Posters 598 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • K Offline
    K Offline
    Kawa7
    wrote on last edited by
    #1

    Il y a t-il un moyen d'exposer une variable C++ au QML sans avoir de risque de fuite mémoire ? J'ai reproduit le problème dans cette exemple :
    Bug.pro :

    QT += quick \
        widgets
    
    CONFIG += c++17
    
    # The following define makes your compiler emit warnings if you use
    # any Qt feature that has been marked deprecated (the exact warnings
    # depend on your compiler). Refer to the documentation for the
    # deprecated API to know how to port your code away from it.
    DEFINES += QT_DEPRECATED_WARNINGS
    
    # You can also make your code fail to compile if it uses deprecated APIs.
    # In order to do so, uncomment the following line.
    # You can also select to disable deprecated APIs only up to a certain version of Qt.
    #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
    
    SOURCES += \
            connection.cpp \
            device.cpp \
            main.cpp
    
    RESOURCES += qml.qrc
    
    # Additional import path used to resolve QML modules in Qt Creator's code model
    QML_IMPORT_PATH =
    
    # Additional import path used to resolve QML modules just for Qt Quick Designer
    QML_DESIGNER_IMPORT_PATH =
    
    # Default rules for deployment.
    qnx: target.path = /tmp/$${TARGET}/bin
    else: unix:!android: target.path = /opt/$${TARGET}/bin
    !isEmpty(target.path): INSTALLS += target
    
    HEADERS += \
        connection.h \
        device.h
    

    Device.h :

    #ifndef DEVICE_H
    #define DEVICE_H
    
    #include <QObject>
    
    class Device : public QObject
    {
        Q_OBJECT
        Q_PROPERTY(QString name READ name CONSTANT)
    
    private:
        QString m_name;
    
    public:
        explicit Device(QObject *parent = nullptr);
        Device(const Device & device);
        Device(QString name);
        QString name() const;
    };
    
    //Q_DECLARE_METATYPE(Device)
    
    #endif // DEVICE_H
    

    Device.cpp :

    #include "device.h"
    
    Device::Device(QObject *parent) : QObject(parent)
    {
        m_name = "Device name";
    }
    
    Device::Device(const Device & device) : QObject()
    {
        m_name = device.m_name;
    }
    
    Device::Device(QString name) : QObject()
    {
        m_name = name;
    }
    
    QString Device::name() const
    {
        return m_name;
    }
    

    Connection.h :

    #ifndef CONNECTION_H
    #define CONNECTION_H
    
    #include <QObject>
    #include "device.h"
    
    class Connection : public QObject
    {
        Q_OBJECT
    public:
        explicit Connection(QObject *parent = nullptr);
    
    public slots:
        void call();
    
    signals:
        void signalWithoutPointer(Device device);
        void signalWithPointer(Device * device);
    };
    
    #endif // CONNECTION_H
    

    Connection.cpp :

    #include "connection.h"
    #include <QDebug>
    
    Connection::Connection(QObject *parent) : QObject(parent){}
    
    void Connection::call()
    {
        qDebug() << "Function call emitted";
        Device device = Device("Device");
        Device * pointer = new Device("Pointeur");
        emit signalWithoutPointer(device); //undefined or converted to QVariant
        emit signalWithPointer(&device); //use after free (only if the receiver is in another thread i.e. Qt::QueuedConnection)
        emit signalWithPointer(pointer); //memory leak
    }
    

    main.cpp:

    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    #include <QQuickItem>
    
    #include "connection.h"
    #include "device.h"
    
    int main(int argc, char *argv[])
    {
        QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    
        QGuiApplication app(argc, argv);
    
        qmlRegisterSingletonType<Connection>("com.bug.connection", 1, 0, "Connection",
                                        [](QQmlEngine * engine, QJSEngine * scriptEngine) -> QObject * {
                                            Q_UNUSED(engine)
                                            Q_UNUSED(scriptEngine)
                                            Connection * connection = new Connection();
                                            return connection;
                                        });
        qmlRegisterType<Device>("com.bug.device", 1, 0, "Device");
    
        QQmlApplicationEngine engine;
        const QUrl url(QStringLiteral("qrc:/main.qml"));
        QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                         &app, [url](QObject *obj, const QUrl &objUrl) {
            if (!obj && url == objUrl)
                QCoreApplication::exit(-1);
        }, Qt::QueuedConnection);
    
        QQmlComponent component(&engine, QUrl(QStringLiteral("qrc:/main.qml")));
        component.create();
        int exec = app.exec();
        return exec;
    }
    

    main.qml :

    import QtQuick 2.12
    import QtQuick.Controls 2.12
    import QtQuick.Layouts 1.12
    import QtQuick.Window 2.12
    import com.bug.connection 1.0
    import com.bug.device 1.0
    
    Window {
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
    
        Text {
            id: text1
            text: qsTr("Default")
        }
    
        Connections {
            target: Connection
            onSignalWithoutPointer: (device) =>{
                console.log("Signal emitted without pointer : " + device)
                console.log("Device's name without pointer : " + device.name)
                text1.text = device.name
            }
            onSignalWithPointer: (device) =>{
                 console.log("Signal emitted with pointer : " + device)
                 console.log("Device's name with pointer : " + device.name)
                 text1.text = device.name
             }
        }
    
        Button {
            id: button
            x: 270
            y: 220
            text: qsTr("Button")
            onClicked: {
                console.log("clicked button")
                Connection.call()
            }
        }
    }
    
    1 Reply Last reply
    0

    • Login

    • Login or register to search.
    • First post
      Last post
    0
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Get Qt Extensions
    • Unsolved