Qt 拖放,限制为子矩形

qt drag and drop with restriction to child rectangle

本文关键字:拖放 Qt      更新时间:2023-10-16

我尝试实现一个基于拖放的选择,用户可以将元素放在小部件内的不同位置以启动某个过程。我首先查看了Qt DropSite示例,并通过向DropArea添加另一个大小为60x60px的标签来更改它。然后我根据 http://qt-project.org/doc/qt-4.8/dnd.html(拖放矩形部分(中的示例更改了方法DropArea::dragMoveEvent(QDragMoveEvent *event),而label等效于上述dropFrame

DropArea::DropArea(QWidget *parent)
    : QLabel(parent)
{
    setMinimumSize(200, 200);
    setFrameStyle(QFrame::Sunken | QFrame::StyledPanel);
    setAlignment(Qt::AlignCenter);
    setAcceptDrops(true);
    setAutoFillBackground(true);
    clear();
    label = new QLabel("Target", this);
    label->setFixedSize(60, 60);
    label->setAutoFillBackground(true);
    label->setBackgroundRole(QPalette::Light);
    label->move(80, 60);
}
void DropArea::dragMoveEvent(QDragMoveEvent *event)
{
  if(event->answerRect().intersects(label->geometry()))
  {
    setText(tr("<drop content>"));
    setBackgroundRole(QPalette::Highlight);
    event->acceptProposedAction();
    emit changed(event->mimeData());
  }
}

根据文档,必须接受 dragEnterEvent 中的 QDragEnterEvent 才能接收 dragMoveEvents。我接受该事件,但这会在进入 DropArea 后立即将光标更改为复制数据符号,并且整个小部件(而不仅仅是标签(上接受放置操作。

我是否必须自己处理光标更改,或者我是否忽略了一些细节以允许Qt正确处理该过程?

我不确定我是否正确理解了问题。但是我会试一试。

每当我尝试在非子类化的标准小部件上捕获诸如拖放之类的事件时,我更喜欢使用事件过滤器。

DropArea::DropArea(QWidget *parent)
: QLabel(parent)
{
  // ... stripped your example just showing the difference
  label->installEventFilter(this);
  label->setAcceptDrops(true);
}

bool DropArea::eventFilter(QObject *pFilterObj,QEvent *pEvent)
{
  if ( (pFilterObj == label) && (pEvent->type() == QEvent::DragEnter) )
  {
    QDragEnterEvent *dEvent = (QDragEnterEvent*)pEvent;
    if (dEvent->mimeData()->hasText()) dEvent->acceptProposedAction();
  }
  if ( (pFilterObj == label) && (pEvent->type() == QEvent::Drop) )
  {
    QDropEvent *dEvent = (QDropEvent*)pEvent;
    qDebug() << dEvent->mimeData()->text();
  }
  // give the default handlers a chance to act too
  return false;
}

如果您在应用程序中使用多个拖放标签,最好对 QLabel 进行子类化并覆盖拖放事件。即使使用Qt Creator,您也可以这样做。只需在那里添加一个常规标签,并 eit 属性成为自定义类的占位符。