我试图创建一个可拆卸的样式小部件,就像Chrome标签可拆卸的方式一样(类名为Tab)。我有一切工作,除了有时(可能有50%的时间)的错误,Tab对象永远不会获得鼠标释放事件,并停止获取鼠标移动事件。
基本上,分离系统通过允许鼠标按下/移动/释放功能中的拖动来工作,就像正常一样。 mouseMoveEvent
检查从开始移动的总距离,如果超过一定数量,将启动"分离"处理。分离过程涉及将父窗口小部件设置为0(顶级窗口小部件,未修饰窗口),因此Tab对象几乎浮动在鼠标下方的所有内容上,并继续随之拖动直到释放。
我浏览了所有正在传递的QEvent
项,我发现当出现此问题时,QEvent :: MouseMove项(以及此后的所有鼠标事件)都被发送到TabBar(Tab对象& #39; s原始父母)。这在Tab上调用setParent(0)
后直接发生。
void Tab::mousePressEvent(*) {
[set up some boolean, start positions, etc]
}
void Tab::mouseMoveEvent(*) {
[track the updated position]
if (positionChange > STATIC_AMOUNT)
detachTab();
}
void Tab::mouseReleaseEvent(*) {
[return the Tab to its original position, and set the parent back to the TabBar]
}
void Tab::detachTab() {
QPoint mappedPos = mapToGlobal(0, 0);
setParent(0); //The loss of MouseMove events occurs when this returns.
move(mappedPos);
show();
raise();
}
以下是Tab对象接收的事件(第一行是QEvent类型,第二行是名称)
[Tab::detachTab() started]
[setParent(0) started]
QEvent::Hide
QEvent::Leave
qApp QEvent::MouseMove [ TabBar ] <-- now the TabBar is soaking up the mouse events
QEvent::HideToParent
QEvent::ParentAboutToChange
QEvent::ParentChange
[setParent(0) returned]
....
总结:我的可拖动QWidget在将其父设置为0后丢失了QEvent :: MouseMove和QEvent :: MouseButtonRelease事件。
任何建议都会非常感激!
答案 0 :(得分:2)
有点棘手的解决方法。我没有测试它,这只是一个想法。
当您的鼠标悬停在窗口小部件的可拖动部分时,您可以使用Qt::FramelessWindowHint
创建最顶层的窗口小部件(让我们称之为Shade)(并且可以使用Qt::WA_TranslucentBackground
)。您可以通过重新实现paintEvent
来操纵Shade外观。例如 - 绘制原始窗口小部件的内容,或绘制一些透明预览等
然后您可以在拖动过程中调整Shade的大小,以向用户显示该窗口小部件将被分离。你不会松开鼠标捕捉。
当用户释放鼠标时 - 你会记住Shade的位置,将其销毁并分离+移动原始小部件。
如果您想了解更多细节,请随时询问。
答案 1 :(得分:0)
这是similar question 因此,您假设使用QDocWidget并使用tabifyDockWidget强制堆叠此小部件。