可拖动图标示例
“可拖动图标”示例演示了如何在同一应用程序内的控件之间,以及在不同应用程序之间进行图像数据的拖放操作。
![]()
在许多使用拖放操作的情境中,用户通常从某个特定控件开始拖动,并将内容放置到另一个控件上。在此示例中,我们通过继承QLabel 类来创建用作拖动源的标签,并将它们放置在QWidget中,这些控件既充当容器,也充当放置目标。
此外,当发生拖放操作时,我们不仅需要发送图像,还需发送用户在图像中点击位置的相关信息,以便用户能将其精确放置在目标位置上。这种细节要求意味着我们必须为数据创建一个自定义 MIME 类型。
DragWidget 类定义
我们用于显示图标的控件是从 `QLabel` 派生的子类:
class DragWidget : public QFrame
{
public:
explicit DragWidget(QWidget *parent = nullptr);
protected:
void dragEnterEvent(QDragEnterEvent *event) override;
void dragMoveEvent(QDragMoveEvent *event) override;
void dropEvent(QDropEvent *event) override;
void mousePressEvent(QMouseEvent *event) override;
};由于QLabel 类已经提供了图标所需的大部分功能,我们只需重写QWidget::mousePressEvent()方法即可实现拖放功能。
DragWidget 类的实现
DragWidget 的构造函数会为控件设置一个属性,以确保该控件在关闭时会被删除:
DragWidget::DragWidget(QWidget *parent)
: QFrame(parent)
{
setMinimumSize(200, 200);
setFrameStyle(QFrame::Sunken | QFrame::StyledPanel);
setAcceptDrops(true);
QLabel *boatIcon = new QLabel(this);
boatIcon->setPixmap(QPixmap(":/images/boat.png"));
boatIcon->move(10, 10);
boatIcon->show();
boatIcon->setAttribute(Qt::WA_DeleteOnClose);
QLabel *carIcon = new QLabel(this);
carIcon->setPixmap(QPixmap(":/images/car.png"));
carIcon->move(100, 10);
carIcon->show();
carIcon->setAttribute(Qt::WA_DeleteOnClose);
QLabel *houseIcon = new QLabel(this);
houseIcon->setPixmap(QPixmap(":/images/house.png"));
houseIcon->move(10, 80);
houseIcon->show();
houseIcon->setAttribute(Qt::WA_DeleteOnClose);
}要启用从图标拖拽的功能,我们需要处理鼠标点击事件。我们通过重写 `QWidget::mousePressEvent()` 方法并创建一个 `QDrag ` 对象来实现这一点。
void DragWidget::mousePressEvent(QMouseEvent *event)
{
QLabel *child = static_cast<QLabel*>(childAt(event->position().toPoint()));
if (!child)
return;
QPixmap pixmap = child->pixmap();
QByteArray itemData;
QDataStream dataStream(&itemData, QIODevice::WriteOnly);
dataStream << pixmap << QPoint(event->position().toPoint() - child->pos());由于我们将向图标小部件发送图标位图数据以及用户点击该图标的相关信息,因此我们构建一个QByteArray ,并使用QDataStream 将这些细节打包起来。
为了实现互操作性,拖放操作会使用 MIME 类型来描述其包含的数据。在 Qt 中,我们使用QMimeData 对象来描述这些数据:
为此,我们选择了一个非官方的 MIME 类型,并将 `QByteArray ` 传递给 MIME 数据对象。
拖放操作本身由一个QDrag 对象处理:
QDrag *drag = new QDrag(this);
drag->setMimeData(mimeData);
drag->setPixmap(pixmap);
drag->setHotSpot(event->position().toPoint() - child->pos());在此,我们将数据传递给拖拽对象,设置一张在操作过程中将随光标一同显示的位图,并定义一个热区的位置,使该位图位于光标正下方。
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.