Qt 在源应用程序小部件外部拖放小部件

Qt 在源应用程序小部件外部拖放小部件,qt,qt4,Qt,Qt4,我有一个Qt桌面应用程序,它有几个顶级小部件。顶级小部件的子小部件可以使用拖放机制在顶级小部件之间移动 我现在的问题是在任何现有的顶级小部件之外放置一个子小部件,并创建一个新的顶级小部件来包含这个小部件。我们称之为分离 这可以通过拖放来完成吗?我找不到我的dropEvent去哪了? 即使不允许放置,我是否可以在应用程序中处理放置事件?也许是释放鼠标什么的 我现在不能改变一切,但这也是未来的问题。停靠/取消停靠是更好的方法吗 问候 米海我找到了一种方法。当拖动移动到应用程序窗口小部件外部时,QDr

我有一个Qt桌面应用程序,它有几个顶级小部件。顶级小部件的子小部件可以使用拖放机制在顶级小部件之间移动

我现在的问题是在任何现有的顶级小部件之外放置一个子小部件,并创建一个新的顶级小部件来包含这个小部件。我们称之为分离

这可以通过拖放来完成吗?我找不到我的dropEvent去哪了? 即使不允许放置,我是否可以在应用程序中处理放置事件?也许是释放鼠标什么的

我现在不能改变一切,但这也是未来的问题。停靠/取消停靠是更好的方法吗

问候
米海

我找到了一种方法。当拖动移动到应用程序窗口小部件外部时,QDrag对象将发出一个参数为0的targetChanged信号

因此,我从QDrag继承,然后如果target()为null,则在析构函数中发出一个自定义信号

唯一的问题是,光标看起来像是drop的阻拦,我无法解决这个问题,因为QDrag只能为移动、复制或链接等有效操作设置光标pixmap

更新:

下面是继承的类

class TabDrag: public QDrag
{
    Q_OBJECT
public:
    explicit TabDrag(QWidget *dragSource);
    ~TabDrag();

signals:
    void tearOff(); /// emit tearOff signal if the QDrag object is destroyed and target was null
};

TabDrag::TabDrag(QWidget *dragSource):QDrag(dragSource)
{
}

TabDrag::~TabDrag()
{
    // check if we need to detach this tab
    if(!target())
    {
        emit tearOff();
    }
}
tearOff信号应该连接到您想要发生的任何事情。在我的例子中,我从选项卡中拉出小部件并将父窗口更改为一个新窗口

用法示例

void MyTabBar::mouseMoveEvent(QMouseEvent* event)
{
..................
    TabDrag * drag = new TabDrag(this);
    drag->setMimeData(mimeData);
    drag->setPixmap(*m_tabPixmap.data());
    drag->setHotSpot(QPoint(m_dragStartPos.x() - tabAtRect.x(), m_dragStartPos.y() - tabAtRect.y()));
    drag->exec();

    connect(drag, SIGNAL(tearOff()), this, SLOT(onTearOff()));
}

为Qt5研究同样的问题,并找到这个聪明的答案。但是你把目标切换信号连接到什么?哪个窗口小部件收到此通知?是否将其连接回自定义拖动对象本身?或者到创建拖动并调用其exec的源小部件?另外,在targetChanged的插槽中,您当时是否可以调用dragobj.setDragCursor(自定义光标pixmap)?谢谢哦,还有!Drag::exec()的Qt5文档中说“在Windows上,Qt事件循环在操作过程中被阻止。”因此没有信号?首先使用exec从来不是一个好主意,因为您创建的子事件循环可能会产生事件反转,这可能会导致崩溃。Qt对于子事件循环不是很好。不要使用它们。我说的是我经历的车祸,因为一些模态弹出是的,你是对的。我还使用exec()。我不记得了。嗯……那我应该研究一下我自己的建议:)。如果事件循环被阻止,则可能无法在拖动时进行窗口更新。希望Qt5提供更好的选项,但我没有此奢侈品。如果您找到Qt5的任何内容,请告诉我。我也很感兴趣。