0

I have two widgets (both QFrames), none of them have any title bar associated with them (which I achieve through setWindowFlags(Qt::FramelessWindowHint)). One of them is a main widget, and the other a sidebar sort of widget, which is supposed to stick to it at its right boundary (its height being approximately 1/4th of the main widget).

I cannot keep them both in a transparent QFrame with static positioning, since the main widget is draggable through its top (since title bar is missing on it, I do it manually by intercepting mousepress/mousemove events and moving it accordingly). The custom drag on the main widget works fine, but when I try to move the sidebar along with, a very obvious visual delay shows up between the two, there are momentary gaps visible between the two while dragging the main widget to the left, or momentary overlapping between the two when dragging the main widget to the right (the sidebar is not draggable, no drag logic is implemented for it).

How do I 'glue' these two widgets together, such that they move together all the time without any delay? I browsed the Qt docs, it may be possible that QDockWidget can help here, but I could not understand how. The main widget here is not a QMainWindow.

Platform - OS X Yosemite, Qt 5.3.1, 32 bit.

SexyBeast
  • 7,913
  • 28
  • 108
  • 196

1 Answers1

1

You should definitely use QDockWidget here.

Make your "main widget" derive from QMainWindow rather than QFrame (it may not be "obvious" as QMainWindow does not derive from QFrame, but it should not be such a big deal).

Then, encapsulate your second widget within a QDockWidget and dock it in the main widget like that:

// secondWidget being your QFrame based widget
// mainWidget being your "main widget"
QDockWidget* dockingBar = new QDockWidget("My bar", mainWidget );
dockingBar->setWidget( secondWidget );
// dock on left side, change first parameter to dock somewhere else:
mainWidget->addDockWidget( Qt::LeftDockWidgetArea, dockingBar );

An alternative is to create a third widget that would become your top-level widget and use a QLayout to insert your two QFrames in this new one:

QWidget* newTopLevelWidget = new QWidget();
// QHBoxLayout to have mainWidget on the left hand side of secondWidget
// Replace by QVBoxLayout to have mainWidget on top of secondWidget
QLayout* layout = new QHBoxLayout( newTopLevelWidget );
layout->addWidget( mainWidget );
layout->addWidget( secondWidget );
jpo38
  • 20,821
  • 10
  • 70
  • 151
  • Thanks. Will making it a `QMainWindow` take away any attribute that I could do with `QFrame`, like removing title bar, making it draggable in spite of that, use just an image as background by using translucent background property, etc? And how do I glue the sidebar? Will adding the dock widget through `addDockWidget` automatically glue them? Shouldn't the first param be `RightDockingArea`, given that the main widget is on the left and the the sidebar on the right side of it? – SexyBeast Jan 03 '16 at 10:26
  • Yes, try `RightDockingArea` you'll see how it will look like when done, they will be sticked together. But user can still choose to undock the widget. With the alternative solution I propose, user cannot "unglue" the widgets. – jpo38 Jan 03 '16 at 10:31
  • But as I said in my second paragraph, that solution is not feasible as I need to make the main widget movable, and the sidebar along with it. How will putting them inside a parent widget achieve this? And how can the user undock them? I will be removing the cancel/close buttons through `setWindowFlags(Qt::FramelessWindowHint)`. How will the user undock the sidebar, then? – SexyBeast Jan 03 '16 at 10:33
  • Putting them inside a parent widget will make them glued together and move together when the parent is moved. It's the easiest way to make two widgets remain next to each other. – jpo38 Jan 03 '16 at 10:39