C++ 拖放包含组合框的listwidget项

C++ 拖放包含组合框的listwidget项,c++,qt,qt5,qcombobox,qlistwidget,C++,Qt,Qt5,Qcombobox,Qlistwidget,我有两个图标模式的listwidgets list1是100个小部件项目的列表(每个小部件项目是一个图标,里面有3-4个项目)。 这些组合框项目是图标的数据,这永远不会改变,它们与小部件项目一起打包,listwidget2为空,我只想能够从1拖动小部件项目(图标和带有项目的组合框),并用list1的一些小部件创建一个收藏夹列表,组合框项目或列表1的小部件项目不会发生任何更改,它们始终具有相同的数据, 问题是每次我拖动小部件时,只有图标被复制到另一个listwidget QDir dir ("i

我有两个图标模式的listwidgets list1是100个小部件项目的列表(每个小部件项目是一个图标,里面有3-4个项目)。 这些组合框项目是图标的数据,这永远不会改变,它们与小部件项目一起打包,listwidget2为空,我只想能够从1拖动小部件项目(图标和带有项目的组合框),并用list1的一些小部件创建一个收藏夹列表,组合框项目或列表1的小部件项目不会发生任何更改,它们始终具有相同的数据, 问题是每次我拖动小部件时,只有图标被复制到另一个listwidget

 QDir dir ("icons");
 QFileInfoList list = dir.entryInfoList(QDir::AllEntries | 
 QDir::Dirs|QDir::NoDotAndDotDot);

 for(int i=0 ; i < list.length() ; i++){
 dir_names.push_back(list.at(i).baseName());
 /*Setting the icon*/
 QIcon icon;
 icon.addFile(list.at(i).absoluteFilePath(), QSize(), QIcon::Normal, 
 QIcon::Off);
 QListWidgetItem *iconItem = new QListWidgetItem(ui->listWidget);
 iconItem->setIcon(icon);

 QComboBox *box = new QComboBox;
 QListWidgetItem *textItem = ui->listWidget->item(i);

 ui->listWidget->setItemWidget( textItem,box);
 box->setFixedHeight(18);
 box->addItem(list.at(i).baseName());
 }
QDir目录(“图标”);
QFileInfoList=dir.entryInfoList(QDir::AllEntries |
QDir::Dirs | QDir::NoDotAndDotDot);
对于(int i=0;ilistWidget);
图标图标->设置图标(图标);
QCOMBOX*box=新的QCOMBOX;
QListWidgetItem*textItem=ui->listWidget->item(i);
ui->listWidget->setItemWidget(文本项,框);
框->设置固定高度(18);
box->addItem(list.at(i).baseName());
}

如果要移动组合框,必须覆盖dropEvent方法,因此必须创建从QListWidget继承的类,获取该小部件并复制必要的数据。如果您想在Qt设计器中使用它,您必须

listwidget.h

#ifndef LISTWIDGET_H
#define LISTWIDGET_H

#include <QListWidget>

class ListWidget : public QListWidget
{
    Q_OBJECT
public:
    ListWidget(QWidget * parent = 0);
    void dropEvent(QDropEvent * event);

protected:
    void mouseMoveEvent(QMouseEvent * event);
};

#endif // LISTWIDGET_H
\ifndef LISTWIDGET\u H
#定义LISTWIDGET\u H
#包括
类ListWidget:公共QListWidget
{
Q_对象
公众:
ListWidget(QWidget*parent=0);
作废事件(QDropEvent*事件);
受保护的:
作废mouseMoveEvent(QMouseEvent*事件);
};
#endif//LISTWIDGET\u H
listwidget.cpp

#include "listwidget.h"

#include <QDropEvent>
#include <QComboBox>

ListWidget::ListWidget(QWidget *parent):QListWidget(parent)
{
    setDragEnabled(true);
    setAcceptDrops(true);
    setDropIndicatorShown(true);
    setDefaultDropAction(Qt::MoveAction);
}

void ListWidget::dropEvent(QDropEvent *event)
{
    if(event->dropAction() == Qt::MoveAction && event->source()){
        ListWidget *listWidget = qobject_cast<ListWidget *>(event->source());
        if(!listWidget)
            return;

        QList<QPersistentModelIndex> pIndexes;
        for(QModelIndex index: listWidget->selectedIndexes()){
            pIndexes << QPersistentModelIndex(index);
        }

        std::sort(pIndexes.begin(), pIndexes.end());

        QListWidgetItem *item = itemAt(event->pos());
        int rowStart = item? row(item) : count();

        for(QPersistentModelIndex pindex: pIndexes){
            int r = QModelIndex(pindex).row();
            QComboBox *input = qobject_cast<QComboBox *>(listWidget->itemWidget(listWidget->item(r)));

            QComboBox *output;
            if(input){
                // move data to QComboBox
                output = new QComboBox;
                for(int i=0; i<input->count(); i++){
                    output->addItem(input->itemText(i));
                    output->setCurrentText(input->currentText());
                }
            }

            QListWidgetItem *it = listWidget->takeItem(r);
            insertItem(rowStart, it);
            if(input)
                setItemWidget(it, output);
        }
        setState(QAbstractItemView::NoState);
    }
}

void ListWidget::mouseMoveEvent(QMouseEvent *event)
{
    setState(QAbstractItemView::DraggingState);
    QListWidget::mouseMoveEvent(event);
}
#包括“listwidget.h”
#包括
#包括
ListWidget::ListWidget(QWidget*parent):QListWidget(parent)
{
setDragEnabled(真);
setAcceptDrops(真);
setDropIndicatorShown(真);
setDefaultDropAction(Qt::MoveAction);
}
void ListWidget::dropEvent(QDropEvent*事件)
{
if(event->dropAction()==Qt::MoveAction&&event->source()){
ListWidget*ListWidget=qobject_cast(事件->源());
如果(!listWidget)
返回;
QList-pIndexes;
对于(QModelIndex索引:listWidget->SelectedIndex()){
pIndexes pos());
int rowStart=item?行(item):count();
用于(QPersistentModelIndex pindex:pIndexes){
int r=QModelIndex(pindex).row();
QComboBox*input=qobject_cast(listWidget->itemWidget(listWidget->item(r));
QCOMBOX*输出;
如果(输入){
//将数据移动到QComboBox
输出=新的QCOMBOX;
对于(int i=0;icount();i++){
输出->添加项(输入->项目文本(i));
输出->设置当前文本(输入->当前文本());
}
}
QListWidgetItem*it=listWidget->takeItem(r);
插入项(rowStart,it);
如果(输入)
setItemWidget(it,输出);
}
setState(qabstractemview::NoState);
}
}
void ListWidget::mouseMoveEvent(QMouseEvent*事件)
{
设置状态(QAbstratemView::DraggingState);
QListWidget::mouseMoveEvent(事件);
}

下面是一个例子。

eyllanesc非常感谢代码,它对我帮助很大。它可以移动项目,但不可以复制。现在我正在尝试弄清楚如何将项目从列表1拖动到列表2,而不将其从列表1中删除。这是我缺少的简单代码还是需要很多额外的代码?我没有墨迹此行`listWidget->takeItem(r);`从列表1中删除该项目