实现效果:

代码链接: https://github.com/gongjianbo/MyTestCode/tree/master/Qml/TestQml_20221125_CopyPaste

1.图片拖入

QML 中提供了 DropArea 类型来处理拖放,使用 containsDrag 属性判断是否有拖拽动作,使用 dropped(DragEvent drop) 信号处理拖拽的释放动作,此信号带一个 DragEvent 参数,可以从中获取拖放的内容。如果拖放的是文件,可以通过 DragEvent 的 urls 属性取文件路径列表,再将路径设置给 Image source。

    DropArea {
        id: drop_area
        anchors.fill: parent
        onDropped: (drop)=>{
            console.log("drop hasUrls:", drop.hasUrls)
            if (drop.hasUrls) {
                drop_image.source = drop.urls[0] //这里只取了一个文件url
    Image {
        id: drop_image
        anchors.fill: parent
        //按比例缩放
        fillMode: Image.PreserveAspectFit
        //异步加载
        asynchronous: true

考虑到 QML 中缺少对路径有效性的判断,以及拖入时我们可能需要执行复制、转码、缩放等操作,所以需要写一个 C++ 的工具类来处理。

2.图片拖出

拖出可以参考 QML drag 相关的示例,即 MouseArea + Drag 附加属性来完成。主要就是设置 Drag 的 supportedActions 拖拽支持的操作和 mimeData 拖拽内容。

    //onLoading 正在加载图片
    property bool onLoading: drop_image.status === Image.Loading
    Image {
        id: drop_image
        anchors.fill: parent
    Item {
        id: drag_item
        Drag.active: mouse_area.drag.active
        //imageSource是拖拽时的图标
        //这里有个问题,图片是原始大小,而且没看到有设置大小或者缩放的接口
        //可以在拖入的时候就生成一个
        //Drag.imageSource: drop_image.source
        //hotSpot是鼠标与imageSource的偏移距离
        Drag.hotSpot.x: 5
        Drag.hotSpot.y: 5
        //拖拽类型默认Drag.Internal动画是拖动Item
        //Drag.Automatic动画是拖动imageSource,结束后才移动Item
        Drag.dragType: Drag.Automatic
        //拖拽拷贝文件,默认好像是移动了文件
        Drag.supportedActions: Qt.CopyAction
        //mimeData是拖拽的内容
        Drag.mimeData: {
            "text/uri-list": drop_image.source
    MouseArea {
        id: mouse_area
        anchors.fill: parent
        //加载好图片后允许拖出
        drag.target: (!onLoading && drop_image.frameCount > 0) ? drag_item : null

3.剪贴板操作

QML 似乎没有引入剪切板的类,所以得自己封装后注册到 QML。界面上使用一个 FocusScope 捕获焦点,然后处理按键消息。

    FocusScope {
        id: focus_scope
        Keys.enabled: true
        //用release的话,按键释放顺序不能保证
        Keys.onPressed: (event)=>{
            if (event.modifiers & Qt.ControlModifier)
                if (event.key === Qt.Key_C) {
                    //Ctrl+C复制
                    console.log("ctrl + c")
                } else if(event.key === Qt.Key_V) {
                    //Ctrl+V复制
                    console.log("ctrl + v")
    MouseArea {
        id: mouse_area
        anchors.fill: parent
        onClicked: {
            focus_scope.forceActiveFocus()

然后封装一下 QClipboard 剪贴板的相关接口,读写资源路径。

QUrl ClipboardTool::currentUrl()
    QClipboard *clipboard = QGuiApplication::clipboard();
    if (clipboard) {
        auto md = clipboard->mimeData();
        if (md) {
            auto urls = md->urls();
            if (!urls.isEmpty()) {
                return urls.first();
    return QUrl();
void ClipboardTool::setCurrentUrl(const QUrl &url)
    QClipboard *clipboard = QGuiApplication::clipboard();
    if (clipboard) {
        QMimeData *md = new QMimeData; 
        md->setUrls(QList<QUrl>()<<url);
        clipboard->setMimeData(md); //内部会管理mimeData的释放
                    QML 中提供了DropArea 类型来处理拖放,使用containsDrag 属性判断是否有拖拽动作,使用 dropped(DragEvent drop) 信号处理拖拽的释放动作,此信号带一个DragEvent 参数,可以从中获取拖放的内容。如果拖放的是文件,可以通过DragEvent 的 urls 属性取文件路径列表,再将路径设置给 Image source。
				
Go剪贴板( 应用程序) 使用Qt的功能将文本存储在剪贴板中或从剪贴板中加载或加载文本。 该分支使用qml.Common来调用QClipboard包装器。 这种方法(比 )要慢一点,但是代码要干净得多,而且往往更安全。 请参阅go-qml的。 如果满足,并且设置了PKG_CONFIG_PATH : $ go get gopkg.in/xlab/clipboard.v2 此剪贴板软件包可在go-qml支持的所有平台上使用。 需要安装的gopkg.in/qml.v1软件包(NB clipboard.v1 qml.v0分别取决于qml.v0 )。 附加信息: 软件包可能与go-qml机械不兼容,请参阅进度。 该软件包利用CGO和qml.Common来使用QApplication::clipboard 。 基准也更好: BenchmarkReadAll
onEntered为拖拽到(鼠标进入)控件触发事件; onDropped为拖拽到控件后(鼠标松手后)触发事件; dragdrop分别为onEntered和onDropped事件可捕抓到的内容; DropArea { anchors.fill: parent; onEnte...
官方文档:https://doc.qt.io/qt-5/qml-qtquick-droparea.html DropArea 用于指定区域中的拖放处理。 但是它是不可见的。 Drag 是一个附加属性,它可用于在将 Item 拖过时通知 DropArea import QtQuick 2.15 import QtQuick.Window 2.15 Window { id: root width: 640 height: 480 visible: true
在Qt5.10中qml实现的拖拽并不完善,以下Bug已在Qt5.12,Qt5.13中进行了修复。 在Qt Quick与 drag and drop 相关的几个QML Type: DropArea DropArea 是不可见的,它定义了一个可以接收拖放的区域。它的 entered 信号在有物体被拖入区域时发射,exited 信号在物体被拖出区域时发射,当物体在区域内被拖着来回移动时会不...
文档如是说,QML旨在通过C ++代码轻松扩展。Qt QML模块中的类使QML对象能够从C ++加载和操作,QML引擎与Qt元对象系统集成的本质使得C ++功能可以直接从QML调用。这允许开发混合应用程序,这些应用程序是通过混合使用QML,JavaScript和C ++代码实现的。 QML is designed to be easily extensible through C++ c...
1.写在前面 在Qt5.12中,QtQuick 2 添加了 TableView 组件,功能和 QtQuickControl 1 中的 TableView 类似,但是接口大不一样(QtQuick Control 1已经处于弃用状态,不建议使用)。 Qt Creator中有两个 QtQuick 2 TableView 的示例,但是都不是数据类型的,参考起来不大方... onEntered: { if (event.mimeData.hasUrls) { for (var i = 0; i < event.mimeData.urls.length; i++) { var url = event.mimeData.urls[i].toString() console.log("File dragged in: " + url) 在这个示例中,我们使用了一个DragArea组件并设置它的anchors.fill为parent,这样它会填充整个窗口。 当用户拖拽文件进入窗口时,onEntered信号会被触发。我们检查mimeData中是否包含URLs,并遍历它们以获取拖拽进来的文件的路径。 注意,为了能够接受拖拽进来的文件,你的应用程序可能需要在.pro文件中添加一些配置,例如: QT += core gui widgets greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += draganddrop