Greetings. I develop drag-and-drop tabs for an MDI application, like in Chrome or Visual Studio . For this, I have compiled the following conditions:

  1. If in QTabBar > 1 tab, then when dragging a tab outside the QTabBar it becomes a window, using setParent(nullptr); and continues to move behind the mouse cursor until we release the left button.
  2. If QTabBar 1 tab, then when dragging a tab, we simply move the window.
  3. If, while dragging a window using the method described in QTabBar 2, we dragged a tab onto a QTabBar , the window becomes a tab inside that QTabBar .

It should also be noted that there may be an unlimited number of windows and tabs. And cross-platform application.

I managed to implement the first 2 conditions, but I haven't been able to solve 3 days already. Question : How to determine that when dragging a window (as in QTabBar 2) we hit the QTabBar area? Or how to make the QTabBar to which we moved the tab to receive the event? What can you advise to implement 3 points?

The difficulty is that I cannot use the widgetAt(); method widgetAt(); because when dragging it will always return a pointer to the tab, and not to the widget under the window (the QTabBar I QTabBar ).

Study

In order to catch the mouse hover event in QTabBar , I tried such methods that, however, did not work:

  • setAttribute(Qt::WA_TransparentForMouseEvents, true); in order for the top window to let events through itself. It works only for widgets in one window.
  • event->ignore(); again, in order to skip the event. Acts similarly to the above.
  • The QHoverEvent class for the widget to receive events, even if blocked by another. It does not fit, because only works in one window.

Manual search, as advised by @isnullxbh, of all areas (via QTabBar::rect()->contains(mouse->globalPos()) ) is also not quite suitable, since costly in resources and problems arise if windows with QTabBar'ами overlap.

  • And what if you ask each childAt window? doc.qt.io/qt-4.8/qwidget.html#childAt - Unick
  • @Unick, no, that's not it. The problem is that I need to know if the mouse cursor is on the widget, at the moment when it is blocked by another widget. - Nik
  • one
    Too lazy to rebel at Qt, but suddenly you don’t: qtcentre.org/threads/… - isnullxbh
  • @isnullxbh regressed, downloaded. The site is not official. There is a project under the old version of Qt, tomorrow I will redo it for a new one, and write it off. - Nik
  • @Nik, wait, sir!) - isnullxbh

1 answer 1

Try to get all the QWindow widgets: QObject::findChildren<QWidget*>() . To cast to a QObject, use qobject_cast<ptrT>(...) . And then go through the resulting list and check the belonging of this point M (x, y) to each of the elements of the resulting list.

  • The fact is that there may be 20 windows, and finding all the widgets, finding the coordinates of each one will be too expensive in performance. - Nik
  • Then we have the following situation - we have several windows, they belong to the same application. The mouse cursor is at a certain position. As a result: in the first window under the cursor any list, in the second - the input field, etc. And would you like to get pointers of all these widgets? - isnullxbh
  • If so, go through these windows and call the findChild method - isnullxbh
  • Ideally, I would like to get a pointer to a widget that is a layer lower than the widget that the widgetAt(); function returned widgetAt(); that is, to widgetAt(); as if ignoring one layer. - Nik
  • I am 99% sure that the framework has no built-in solutions for such tasks. Too specific. Why do not you like the above option? Getting a list of windows in your code is not a problem, and then findChild will do everything for you. - isnullxbh