2012-09-05 72 views
2

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

我现在面临的问题是在现有顶级窗口小部件之外放置一个子窗口小部件,并创建一个新的顶级窗口小部件来包含此窗口小部件。让我们称之为分离。

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

我不能改变一切,但也是一个未来的问题。对接/取消对话是一种更好的方式吗?

问候 米哈伊

回答

1

我找到了一种方法来做到这一点。当拖动移出应用程序小部件时,QDrag对象发出一个0参数的targetChanged信号。

所以我从QDrag继承,然后在析构函数中发出一个自定义信号,如果target()为空。

唯一的问题是,光标看起来像一滴阻截,这我不能确定,因为QDrag只能设置光标像素图像移动或复制或链接有效的行动

更新:

这里继承的类。

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(); 

    QnConnect(drag, SIGNAL(tearOff()), this, SLOT(onTearOff())); 
} 
+1

用于研究的QT5同一问题的例子,发现这个聪明的答案。但是,你连接targetChanged信号是什么?什么小部件收到此通知?你是否将它连接回自定义的Drag对象本身?或者到创建Drag的源小部件并调用它的exec?另外,在targetChanged的插槽中,你可不可以在那个时候调用dragobj.setDragCursor(自定义光标像素图)?谢谢。哦,也! Drag :: exec()的Qt5文档说:“在Windows上,Qt事件循环在操作过程中被阻塞。”那么没有信号? – user405

+0

首先使用exec永远不是一个好主意,因为你创建了一个可能产生事件反转的子事件循环,这可能会导致你崩溃。 Qt对于子事件循环不太好。不要使用它们。我从我遇到的崩溃发言,因为一些模式弹出 – mhstnsc

+0

我更新了我的答案,包括一些代码 – mhstnsc