在一个子类QListWidget
上,我有几个项。下面所示的每个QListWidget
项目(例如"ROS Init"、"Images"等(都与特定图标相关联。
我遇到的问题是我试图拖放与QListWidget
项目相对应的特定图标,但什么也没发生。
负责拖动的功能下方:
void ListView::startDrag(Qt::DropActions supportedActions)
{
QMap<int, QString> icons;
icons.insert(IT_RosInit, "ROS Init");
icons.insert(IT_Images, "Images");
icons.insert(IT_Path, "Path");
icons.insert(IT_RosShutDown, "ROS Shutdown");
if (supportedActions & Qt::CopyAction)
{
const QList<QListWidgetItem *> &m_items(selectedItems());
if (m_items.isEmpty())
return;
QPixmap pixmapLaser("/home/images/laserscan.png");
QPixmap pixmapPCloud2("/home/images/pcloud2.png");
// etc ...
QStringList iconImages;
for(int i = 0; i < icons.count(); ++i)
{
for (const QString &tableType : iconImages) {
if (tableType == "ROS Init")
{
auto *data = mimeData(m_items);
auto *drag = new QDrag(this);
drag->setPixmap(pixmapLaser);
drag->setMimeData(data);
drag->setHotSpot(pixmapLaser.rect().center());
drag->exec(Qt::CopyAction);
}
else if(tableType == "Images")
{
auto *data2 = mimeData(m_items);
auto *drag2 = new QDrag(this);
drag2->setPixmap(pixmapPCloud2);
drag2->setMimeData(data2);
drag2->setHotSpot(pixmapPCloud2.rect().center());
drag2->exec(Qt::CopyAction);
}
}
}
}
else
{
QListWidget::startDrag(supportedActions);
}
}
在对QListWidget
进行子类化之后,我只是重新实现了通常的拖放函数。除了startDrag
之外,所有其他函数都正常工作,事实上,当我试图拖动正确的QPixmap
时,我实际上没有看到任何拖动。
我查阅了这个有用的来源,也查阅了另一个有用的来源——但它没有重新实现startDrag
,而是实现了dropEvent
,这对我来说不是问题,因为它运行得很好。
我也咨询了这个消息来源和其他消息来源,但这也无助于解决问题。
感谢您为问题的解决提供线索
解决方案
我会用以下方式来处理这个问题:
-
设置
QListWidgetItem
的ItemIsDragEnabled
标志以启用要拖动的项目:item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled);
-
为每个项目设置所需的数据:
item->setData(Qt::UserRole, type);
其中type
是枚举值IT_RosInit
、IT_Images
等之一。
-
启用
ListWidget
:的拖动功能setDragEnabled(true); setDragDropMode(QAbstractItemView::DragOnly);
-
使用项目设置设置在
startDrag
中创建的QDrag
对象。
示例
以下是我为您准备的一个示例,用于演示如何实现所提出的解决方案:
主窗口.cpp
MainWindow::MainWindow(QWidget *parent) :
QWidget(parent)
{
auto *l = new QVBoxLayout(this);
auto *list = new ListView(this);
list->addItem(createItem(":/pix/images/laserscan.png", tr("RosInit"), IT_RosInit));
list->addItem(createItem(":/pix/images/icons/pcloud2.png", tr("Images"), IT_Images));
list->addItem(createItem(":/pix/images/icons/some_icon.png", tr("Path"), IT_Path));
list->addItem(createItem(":/pix/images/icons/another_icon.png", tr("RosShutDown"), IT_RosShutDown));
l->addWidget(list);
resize(300, 400);
setWindowTitle("IconDrag");
}
QListWidgetItem *MainWindow::createItem(const QString &pm, const QString &text, int type)
{
auto *item = new QListWidgetItem(QIcon(QPixmap(pm)), text);
item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled);
item->setData(Qt::UserRole, type);
return item;
}
ListView.cpp
ListView::ListView(QWidget *parent) :
QListWidget(parent)
{
setDragEnabled(true);
setDragDropMode(QAbstractItemView::DragOnly);
setSelectionBehavior(QAbstractItemView::SelectRows);
setSelectionMode(QAbstractItemView::SingleSelection);
}
void ListView::startDrag(Qt::DropActions supportedActions)
{
if (supportedActions & Qt::CopyAction) {
const QList<QListWidgetItem *> &items(selectedItems());
if (items.isEmpty())
return;
const QPixmap &pm(items.first()->icon().pixmap(64));
auto *item = items.first();
auto *mimeData = new QMimeData();
auto *drag = new QDrag(this);
mimeData->setData("text/plain", item->data(Qt::UserRole).toByteArray());
drag->setPixmap(pm);
drag->setMimeData(mimeData);
drag->setHotSpot(pm.rect().center());
drag->exec(Qt::CopyAction);
}
}