Qt - 如何在拖动项目时显示图像/图标/数据?
Posted
技术标签:
【中文标题】Qt - 如何在拖动项目时显示图像/图标/数据?【英文标题】:Qt - How to show image/icon/data while dragging an item? 【发布时间】:2018-05-10 18:40:41 【问题描述】:我有一个应用程序,我可以将一个项目拖到 QGraphicsScene 并根据项目文本创建一个新对象,但是如何在项目周围移动时更改正在显示的数据?
例如,我想显示一个图标而不是文本:
我有一个包含一些项目的列表:
OptionList::OptionList(QWidget *parent) : QListWidget(parent)
this->setDragEnabled(true);
this->setDropIndicatorShown(true);
this->setSelectionMode(QAbstractItemView::SingleSelection);
this->setDefaultDropAction(Qt::CopyAction);
this->setViewMode(QListView::ListMode);
for(const QString &color : "Blue", "Red", "Green", "Yellow")
OptionItem *item = new OptionItem;
item->setText(color);
item->setFlags(Qt::ItemIsEnabled| Qt::ItemIsSelectable| Qt::ItemIsDragEnabled);
addItem(item);
我将元素放入场景中以创建一个新对象:
MyScene::MyScene()
setBackgroundBrush(Qt::lightGray);
void MyScene::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
if(event->mimeData()->hasFormat("application/x-qabstractitemmodeldatalist"))
event->setAccepted(true);
void MyScene::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
if(event->mimeData()->hasFormat("application/x-qabstractitemmodeldatalist"))
event->setAccepted(true);
void MyScene::dropEvent(QGraphicsSceneDragDropEvent *event)
QByteArray encoded = event->mimeData()->data("application/x-qabstractitemmodeldatalist");
QDataStream stream(&encoded, QIODevice::ReadOnly);
QStringList colors;
while (!stream.atEnd())
int row, col;
QMap<int, QVariant> roleDataMap;
stream >> row >> col >> roleDataMap;
colors << roleDataMap[Qt::DisplayRole].toString();
QPointF posView = event->scenePos() ;
for(const QString & color: colors)
Block *newBlock = new Block(color);
newBlock->setPos(posView);
addItem(newBlock);
然后,我创建了派生自 QListWidgetItem 的 OptionItem 类,并重新实现了 mousePressEvent、mouseMoveEvent 和 mouseReleaseEvent
OptionItem::OptionItem()
void OptionItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
event->setAccepted(true);
void OptionItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
QDrag *drag = new QDrag(event->widget());
QMimeData *mime = new QMimeData;
QImage image(":/images/MyIcon_icon.png");
mime->setImageData(image);
drag->setMimeData(mime);
drag->setPixmap(QPixmap::fromImage(image));
drag->setHotSpot(QPoint(15, 30));
drag->exec();
event->setAccepted(true);
void OptionItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
event->setAccepted(true);
我尝试按照 Qt Creator 中的拖放机器人示例进行操作,但这不是一回事
当我开始拖动项目时,图像似乎出现得很快
有没有办法在整个操作中拖动项目时显示图标?
【问题讨论】:
【参考方案1】:从QAbstractItemView
继承的类支持默认拖动,因此它们已经实现了方法,而不是您指出的示例显示了如何为某些没有它的类实现此功能,您的任务很简单,你必须覆盖QListWidget
的方法startDrag
。
optionilist.h
#ifndef OPTIONLIST_H
#define OPTIONLIST_H
#include <QListWidget>
class OptionList: public QListWidget
public:
OptionList(QWidget* parent=nullptr);
protected:
void startDrag(Qt::DropActions supportedActions);
;
#endif // OPTIONLIST_H
optionlist.cpp
#include "optionlist.h"
#include <QDrag>
OptionList::OptionList(QWidget *parent): QListWidget(parent)
setDragEnabled(true);
setDropIndicatorShown(true);
setSelectionMode(QAbstractItemView::SingleSelection);
setDefaultDropAction(Qt::CopyAction);
setViewMode(QListView::ListMode);
for(const QString &color : "Blue", "Red", "Green", "Yellow")
QListWidgetItem *blue = new QListWidgetItem;
blue->setText(color);
blue->setFlags(Qt::ItemIsEnabled| Qt::ItemIsSelectable| Qt::ItemIsDragEnabled);
addItem(blue);
void OptionList::startDrag(Qt::DropActions supportedActions)
if(supportedActions & Qt::CopyAction)
QList<QListWidgetItem *> m_items = selectedItems();
if(m_items.isEmpty())
return;
QMimeData *data = mimeData(m_items);
QDrag *drag = new QDrag(this);
QPixmap pixmap(":/images/MyIcon_icon.png");
drag->setPixmap(pixmap);
drag->setMimeData(data);
drag->setHotSpot(pixmap.rect().center());
drag->exec(Qt::CopyAction);
else
QListWidget::startDrag(supportedActions);
完整代码可以在以下link找到。
【讨论】:
我在QListWidget中使用了startDrag方法,当我开始拖动item时,应用程序输出打印如下错误:QDrag: No mimedata set before start the drag 我使用了调试器,看起来变量数据到达拖动时没有值->setMimeData(data);也许问题出在 mimeData() 函数上?应用程序成功运行,但当我尝试拖动项目时,应用程序输出中出现消息“QDrag:在开始拖动之前未设置 mimedata”。我也尝试编译您的代码,但由于 nullptr 标识符,我不得不在 .pro 文件中设置 CONFIG += c++11,同样的消息仍然出现在应用程序输出中。 我尝试了你的项目并得到了同样的信息。我已经消除了 OptionItem 实现。我正在使用 Qt 5.4.1 版本。这是我的代码的链接:github.com/Gabriel-22/myqt/tree/master/Project1【参考方案2】:以上是正确的!
还要注意drag->setMimeData(data);
需要在drag->setPixmap(pixmap);
之后调用。
否则,在拖拽移动的过程中,它会显示原来的mimedata类型,而不是显示图像/图标。
【讨论】:
以上是关于Qt - 如何在拖动项目时显示图像/图标/数据?的主要内容,如果未能解决你的问题,请参考以下文章