qt拖放限制到子矩形

时间:2013-10-09 16:32:35

标签: c++ qt drag-and-drop

我尝试实现基于drop的选择,其中用户可以将元素放在窗口小部件内的不同位置以启动某个过程。 我首先查看了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正确处理该过程?

1 个答案:

答案 0 :(得分:1)

我不确定我是否正确地提出了问题。不过我会试一试。

每当我尝试捕捉像拖放标准窗口小部件的事件时,我更喜欢使用事件过滤器。

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,您也可以这样做。只需在那里添加常规标签,然后将其属性作为自定义类的占位符。