如何跟踪拖动/下降操作的寿命



我有一个应用程序,它可以使用startDrag()dragEnterEvent()dropEvent()等将项目从修改的QListWidget删除到修改的QLabel,等等。

我现在不仅要在拖动 start 的情况下,而且还要收到通知,当时它会得到中断(通过按ESC或在void中的某个地方放置)。(我的目标是发现一个隐藏的小部件,我可以在中断拖动操作后立即丢弃物品。)

我爬上了文档,但找到了任何有希望的东西 - 有人已经完成了吗?

已经有一个非常相似的问题,但是它没有得到有用的答案,而且已经两年了 - 所以也许QT5引入了一些新的技巧?

在qt 4中至少为qt 5.7,drag为伪同步。它开始输入QListWidget::startDrag并调用QDrag::exec()的时刻,并在QListWidget::startDrag返回时结束。因此,您可能有:

void startDrag(Qt::DropActions supportedActions) override {
   emit dragStarted();
   QListWidget::startDrag(supportedActions); // reenters the event loop
   emit dragStopped();
}

易于露天,如果它忽略了是否真的发生了阻力(可以将其过滤掉)。

但是此实现可能会改变,实际上应该改变:事件循环重新进入是一团糟。而且我们还想知道QDrag::exec()是否真的在QDrag实例上被调用。因此,我们需要在控件返回事件循环后检查QDrag实例的存在(通过返回或重新输入)。

我们可以利用QDragQAbstractItemView的孩子。阻力启动后,您可以找到实例并跟踪其寿命。生命周期监视需要将函数张贴到事件循环中,以应对伪同步阻力实现。如果/何时拖动完全异步,下面的代码仍将工作。

// https://github.com/KubaO/stackoverflown/tree/master/questions/drag-lifetime-37846521
#include <QtWidgets>
template <typename F>
static void postToThread(F && fun, QObject * obj = qApp) {
   QObject src;
   QObject::connect(&src, &QObject::destroyed, obj, std::forward<F>(fun),
                    Qt::QueuedConnection);
}
struct MyListWidget : QListWidget {
   Q_SIGNAL void dragStarted();
   Q_SIGNAL void dragStopped();
   MyListWidget() {
      setDragEnabled(true);
      addItem("item1");
      addItem("item2");
   }
   void startDrag(Qt::DropActions supportedActions) override {
      postToThread([this]{
         auto drag = findChild<QDrag*>();
         if (drag) {
            emit dragStarted();
            connect(drag, &QObject::destroyed, this, &MyListWidget::dragStopped);
         }
      }, this);
      QListWidget::startDrag(supportedActions); // reenters the event loop
   }
   Q_OBJECT
};
int main(int argc, char **argv) {
   QApplication app(argc, argv);
   QWidget gui;
   QVBoxLayout layout(&gui);
   MyListWidget list;
   QLabel label;
   layout.addWidget(&list);
   layout.addWidget(&label);
   QObject::connect(&list, &MyListWidget::dragStarted, [&]{ label.setText("Drag Active"); });
   QObject::connect(&list, &MyListWidget::dragStopped, [&]{ label.clear(); });
   gui.show();
   return app.exec();
}
#include "main.moc"

相关内容

  • 没有找到相关文章

最新更新