Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing QClipboard to QML

Tags:

c++

qt

qt5

qml

I am trying to make the clipboard available to some QML code.

Passing the clipboard object seems to work, but then I can't call its methods.

Here's an example of a QClipboard working fine in C++, being passed to QML, and in the debug output it still being a QClipboard object but losing its functions.

main.cpp

#include <QApplication>
#include <QClipboard>
#include <QQmlApplicationEngine>
#include <qqmlcontext.h>
#include <QtQml>


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

    QQmlApplicationEngine engine;
    engine.rootContext()->setContextProperty("clipboard", QApplication::clipboard());
    qDebug() << QApplication::clipboard()->text(); // This correctly prints the copied text
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    return app.exec();
}

main.qml

import QtQuick 2.5
import QtQuick.Controls 1.3
ApplicationWindow {
    visible: true
    MouseArea {
        acceptedButtons: Qt.MiddleButton
        anchors.fill: parent
        onClicked: {
            console.log(clipboard)
            console.log(clipboard.getText())
        }
    }
}

qml.qrc

<RCC>
    <qresource prefix="/">
        <file>main.qml</file>
    </qresource>
</RCC>

test.pro

TEMPLATE = app
VERSION = 1.0

QT += qml widgets gui
QMAKE_LFLAGS += -Wl,--as-needed

SOURCES += main.cpp
RESOURCES += qml.qrc
like image 858
LtWorf Avatar asked Oct 17 '16 17:10

LtWorf


1 Answers

QObject's functions need to be slots if you want to call them from QML. QClipboard declares no slots, so you can't call its functions directly. You can create a proxy, though:

qclipboardproxy.hpp

#ifndef QCLIPBOARDPROXY_HPP
#define QCLIPBOARDPROXY_HPP

#include <QObject>

class QClipboard;

class QClipboardProxy : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString text READ text NOTIFY textChanged)
public:
    explicit QClipboardProxy(QClipboard*);

    QString text() const;

signals:
    void textChanged();

private:
    QClipboard* clipboard;
};

#endif // QCLIPBOARDPROXY_HPP

qclipboardproxy.cpp

#include "qclipboardproxy.hpp"

#include <QClipboard>

QClipboardProxy::QClipboardProxy(QClipboard* c) : clipboard(c)
{
    connect(c, &QClipboard::dataChanged, this, QClipboardProxy::textChanged)
}

QString QClipboardProxy::text()
{
    return clipboard->text();
}

and in

main.cpp

engine.rootContext()->setContextProperty("clipboard",
    new QClipboardProxy(QGuiApplication::clipboard()));

Now you can call:

console.log(clipboard.text)

or even

someProperty: clipboard.text
like image 103
krzaq Avatar answered Sep 22 '22 07:09

krzaq