关于不同类下的两个QTreeWidget 拖拽

两个不同类下的QTreeWidget不能用mimedata 类获取到拖拽的信息,这有解决的方法吗?注意是两个类的QTreeWidget ,不是同一个窗口下的QTreeWidget

参考GPT和自己的思路:可以通过实现自定义的拖放处理程序来解决两个不同类下的QTreeWidget拖拽的问题。具体来说,可以在拖拽源类和目标类中分别实现自定义拖放处理程序并通过自定义数据类型来传输拖拽信息。在源类的dragEvent事件中设置自定义数据类型的数据并启动拖放操作,在目标类的dropEvent事件中检测并获取自定义数据类型的数据,然后执行对应的操作。需要注意的是,自定义数据类型需要在两个类中保持一致才能正常传输数据。

可以通过自定义QMimeData类来解决两个不同类下的QTreeWidget无法获取拖拽信息的问题。
具体步骤如下:

 
在源类中重载QTreeWidget的mouseMoveEvent事件和dragEnterEvent事件,将需要传递的数据打包到自定义QMimeData类中,并调用QDrag类的exec函数开始拖拽操作:

void SourceClass::mouseMoveEvent(QMouseEvent *event)
{
    if (event->buttons() & Qt::LeftButton) {
        QTreeWidgetItem *item = currentItem();
        if (item) {
            QDrag *drag = new QDrag(this);
            QMimeData *mimeData = new QMimeData();
            // 将需要传递的数据打包到mimeData中
            mimeData->setText(item->text(0));
            drag->setMimeData(mimeData);
            drag->exec(Qt::CopyAction);
        }
    }
}
void SourceClass::dragEnterEvent(QDragEnterEvent *event)
{
    event->acceptProposedAction();
}

在目标类中重载QTreeWidget的dropEvent事件和dragEnterEvent事件,从自定义QMimeData类中获取传递的数据:

void TargetClass::dropEvent(QDropEvent *event)
{
    QTreeWidgetItem *item = new QTreeWidgetItem();
    // 从mimeData中获取传递的数据
    item->setText(0, event->mimeData()->text());
    addTopLevelItem(item);
    event->acceptProposedAction();
}
void TargetClass::dragEnterEvent(QDragEnterEvent *event)
{
    event->acceptProposedAction();
}

这样,两个不同类下的QTreeWidget就可以通过自定义QMimeData类来传递拖拽数据了。

该回答引用于gpt与OKX安生共同编写:
  • 该回答引用于gpt与OKX安生共同编写:

如果您想在不同类下的两个QTreeWidget之间实现拖放操作,您需要实现以下步骤:

  1. 在源QTreeWidget中实现拖动操作。为此,您需要重写QTreeWidget的mousePressEvent()函数,并使用QDrag对象构造MIME数据并启动拖动操作。

  2. 在目标QTreeWidget中实现拖放操作。为此,您需要重写QTreeWidget的dragEnterEvent()和dropEvent()函数,并从MIME数据中提取所需的信息,然后将其插入到目标QTreeWidget中。

以下是一些关键代码片段,以帮助您开始处理此问题:

源QTreeWidget的mousePressEvent()函数:


void SourceTreeWidget::mousePressEvent(QMouseEvent *event)
{
    QTreeWidgetItem* selectedItem = currentItem();

    // 从选定项目中获取需要传递的数据
    QMimeData* mimeData = new QMimeData();
    mimeData->setData("selectedItem", selectedItem->text().toUtf8());

    // 启动拖动操作
    QDrag* drag = new QDrag(this);
    drag->setMimeData(mimeData);
    drag->exec(Qt::CopyAction);
}

目标QTreeWidget的dragEnterEvent()和dropEvent()函数:

void TargetTreeWidget::dragEnterEvent(QDragEnterEvent *event)
{
    if (event->mimeData()->hasFormat("selectedItem")) {
        event->acceptProposedAction();
    }
}

void TargetTreeWidget::dropEvent(QDropEvent *event)
{
    if (event->mimeData()->hasFormat("selectedItem")) {
        QString selectedItem = QString(event->mimeData()->data("selectedItem"));

        // 在目标QTreeWidget中插入数据
        QTreeWidgetItem* newItem = new QTreeWidgetItem(this);
        newItem->setText(0, selectedItem);

        event->acceptProposedAction();
    }
}

请注意,您需要将源QTreeWidget和目标QTreeWidget实例化为不同的对象,并在适当的位置连接信号和槽。这里提供的代码片段仅用于演示关键思路,请根据您的应用程序需求进行修改。

  • 以下是一个完整的示例程序,可以实现从一个QTreeWidget向另一个QTreeWidget拖放项目:
#include <QtWidgets>

class SourceTreeWidget : public QTreeWidget
{
public:
    SourceTreeWidget(QWidget* parent = nullptr) : QTreeWidget(parent)
    {
        // 添加一些演示数据
        QStringList headers;
        headers << "Source";
        setHeaderLabels(headers);

        QStringList items;
        items << "Item 1" << "Item 2" << "Item 3";
        foreach (QString item, items) {
            QTreeWidgetItem* newItem = new QTreeWidgetItem(this);
            newItem->setText(0, item);
        }

        setSelectionMode(QAbstractItemView::SingleSelection);
        setDragEnabled(true);
        setAcceptDrops(false);
    }

protected:
    void mousePressEvent(QMouseEvent *event) override
    {
        QTreeWidgetItem* selectedItem = currentItem();

        // 从选定项目中获取需要传递的数据
        QMimeData* mimeData = new QMimeData();
        mimeData->setData("selectedItem", selectedItem->text().toUtf8());

        // 启动拖动操作
        QDrag* drag = new QDrag(this);
        drag->setMimeData(mimeData);
        drag->exec(Qt::CopyAction);
    }
};

class TargetTreeWidget : public QTreeWidget
{
public:
    TargetTreeWidget(QWidget* parent = nullptr) : QTreeWidget(parent)
    {
        // 添加一些演示数据
        QStringList headers;
        headers << "Target";
        setHeaderLabels(headers);

        setSelectionMode(QAbstractItemView::SingleSelection);
        setDragDropMode(QAbstractItemView::DragDrop);
        setDefaultDropAction(Qt::CopyAction);
        setAcceptDrops(true);
    }

protected:
    void dragEnterEvent(QDragEnterEvent *event) override
    {
        if (event->mimeData()->hasFormat("selectedItem")) {
            event->acceptProposedAction();
        }
    }

    void dropEvent(QDropEvent *event) override
    {
        if (event->mimeData()->hasFormat("selectedItem")) {
            QString selectedItem = QString(event->mimeData()->data("selectedItem"));

            // 在目标QTreeWidget中插入数据
            QTreeWidgetItem* newItem = new QTreeWidgetItem(this);
            newItem->setText(0, selectedItem);

            event->acceptProposedAction();
        }
    }
};

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

    QWidget window;
    QHBoxLayout* layout = new QHBoxLayout(&window);

    SourceTreeWidget* sourceTree = new SourceTreeWidget();
    TargetTreeWidget* targetTree = new TargetTreeWidget();

    layout->addWidget(sourceTree);
    layout->addWidget(targetTree);

    window.setLayout(layout);
    window.show();

    return a.exec();
}

这个程序创建了两个QTreeWidget,一个源QTreeWidget和一个目标QTreeWidget。在源QTreeWidget中选择一个项目并拖动它,然后放到目标QTreeWidget中,就可以实现向另一个QTreeWidget拖放项目的功能。

  • 这篇文章讲的很详细,请看:QTreeWidget实现节点拖拽
  • 除此之外, 这篇博客: Qt学习笔记之常用控件QTreeWidget中的 三、QTreeWidget例子 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • #ifndef TREEWIDGET_H 
    #define TREEWIDGET_H 
    
    #include <QtGui> 
    
    class TreeWidget : public QWidget 
    { 
    public: 
            TreeWidget(); 
    
    private: 
            QTreeWidget *tree; 
    }; 
    
    #endif // TREEWIDGET_H
    #include "treewidget.h" 
    
    TreeWidget::TreeWidget() 
    { 
            tree = new QTreeWidget(this); 
            tree->setColumnCount(1); 
            QTreeWidgetItem *root = new QTreeWidgetItem(tree, QStringList(QString("Root"))); 
            QTreeWidgetItem *leaf = new QTreeWidgetItem(root, QStringList(QString("Leaf 1"))); 
            root->addChild(leaf); 
            QTreeWidgetItem *leaf2 = new QTreeWidgetItem(root, QStringList(QString("Leaf 1"))); 
            leaf2->setCheckState(0, Qt::Checked); 
            root->addChild(leaf2); 
            QList<QTreeWidgetItem *> rootList; 
            rootList << root; 
            tree->insertTopLevelItems(0, rootList); 
    }