2016-10-17 85 views
1

我正在嘗試使剪貼板可用於某些QML代碼。將QClipboard傳遞給QML

傳遞剪貼板對象似乎工作,但我不能調用它的方法。

下面是一個QClipboard在C++中正常工作的例子,被傳遞給QML,在調試輸出中它仍然是一個QClipboard對象,但是失去了它的功能。

的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 

回答

3

QObject的功能必須插槽,如果你想從QML調用它們。 QClipboard聲明沒有插槽,所以你不能直接調用它的函數。你可以創建一個代理,但:

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

main.cpp

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

現在,您可以撥打:

console.log(clipboard.text) 

甚至

someProperty: clipboard.text 
+1

你甚至可以在代理上創建文本屬性並獲得綁定的工作。我會提出一個編輯 –

+2

標記這個作爲答案,因爲它解釋了爲什麼它不直接工作。 – LtWorf

2

通過@ krzaq的解決方案的啓發,你甚至可以使代理一個QML實例化的類型

class ClipboardProxy : public QObject 
{ 
    Q_OBJECT 
    Q_PROPERTY(QString text READ dataText WRITE setDataText NOTIFY dataChanged) 
    Q_PROPERTY(QString selectionText READ selectionText WRITE setSelectionText NOTIFY selectionChanged) 
public: 
    explicit ClipboardProxy(QObject *parent = 0); 

    void setDataText(const QString &text); 
    QString dataText() const; 

    void setSelectionText(const QString &text); 
    QString selectionText() const; 

signals: 
    void dataChanged(); 
    void selectionChanged(); 
}; 

ClipboardProxy::ClipboardProxy(QObject *parent) 
    : QObject(parent) 
{ 
    QClipboard *clipboard = QGuiApplication::clipboard(); 
    connect(clipboard, &QClipboard::dataChanged, 
      this, ClipboardProxy::dataChanged); 
    connect(clipboard, &QClipboard::selectionChanged, 
      this, ClipboardProxy::selectionChanged); 
} 

void ClipboardProxy::setDataText(const QString &text) 
{ 
    QGuiApplication::clipboard()->setText(text, QClipboard::Clipboard); 
} 

QString ClipboardProxy::dataText() const 
{ 
    return QGuiApplication::clipboard()->text(QClipboard::Clipboard); 
} 

void ClipboardProxy::setSelectionText(const QString &text) 
{ 
    QGuiApplication::clipboard()->setText(text, QClipboard::Selection); 
} 

QString ClipboardProxy::selectionText() const 
{ 
    return QGuiApplication::clipboard()->text(QClipboard::Selection); 
} 

註冊爲main()

qmlRegisterType<ClipboardProxy>("Clipboard", 1, 0, "Clipboard"); 

作爲QML中的一種類型使用

import QtQuick 2.4 
import Clipboard 1.0 

Column { 
    Clipboard { 
     id: clipboard 

     onDataChanged: console.log("Clipboard data changed"); 
     onSelectionChanged: console.log("Clipboard selection changed"); 
    } 
    Text { 
     text: clipboard.text 
    } 
    TextInput { 
     onEditingFinished: clipboard.text = text; 
    } 
}