我正在尝试使剪贴板可用于某些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();
}
Run Code Online (Sandbox Code Playgroud)
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())
}
}
}
Run Code Online (Sandbox Code Playgroud)
qml.qrc
<RCC>
<qresource prefix="/">
<file>main.qml</file>
</qresource>
</RCC>
Run Code Online (Sandbox Code Playgroud)
test.pro
TEMPLATE = app
VERSION = 1.0
QT += qml widgets gui
QMAKE_LFLAGS += -Wl,--as-needed
SOURCES += main.cpp
RESOURCES += qml.qrc
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
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();
}
Run Code Online (Sandbox Code Playgroud)
并在
main.cppengine.rootContext()->setContextProperty("clipboard",
new QClipboardProxy(QGuiApplication::clipboard()));
Run Code Online (Sandbox Code Playgroud)
现在你可以打电话:
console.log(clipboard.text)
Run Code Online (Sandbox Code Playgroud)
甚至
someProperty: clipboard.text
Run Code Online (Sandbox Code Playgroud)
受到@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);
}
Run Code Online (Sandbox Code Playgroud)
注册为类型 main()
qmlRegisterType<ClipboardProxy>("Clipboard", 1, 0, "Clipboard");
Run Code Online (Sandbox Code Playgroud)
在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;
}
}
Run Code Online (Sandbox Code Playgroud)