PDA

View Full Version : Best way to 'customise' the docking areas of a QMainWindow?



agarny
13th May 2013, 09:41
Hi,

My application's main form inherits from QMainWindow and I rely on QMainWindow's docking feature to dock some widgets to my main form. It all works fine and everything, but... I would like to be able to show/hide a docking area by simply clicking a button within the docking area.

The idea is that the user might have customised the main form with some widgets docked here and there. However, he might at some point want the central widget to get as much space as possible to carry out a particular task. So, I would like him to be able to temporarily hide one or several docking areas, carry out his particular task, and then re-show those one or several docking areas.

I know that I could 'manually' show/hide the dock widgets (after/before saving/restoring my application's state), but this would 'break' my GUI logic since I have some menu items which I use to show/hide those dock widgets. Also, this wouldn't address the question of how this 'showing'/'hiding' would be triggered which I want to be done through a button within the docking area.

So... I was thinking of customising QMainWindow's docking feature so that it could do what I am after. However, with Qt implementating QMainWidnow's docking feature in private classes means that I cannot customise anything. I am therefore thinking of 'cloning' QMainWindow (and whatever would need 'cloning'), renaming the clone to, say, TMainWindow, customising TMainWindow to my specific needs, and then have my main form inherit from TMainWindow rather than QMainWindow.

If at all possible, I would rather not go down that route, but what other options are available to me?... Anyone?...

Cheers, Alan.

Santosh Reddy
13th May 2013, 10:49
I know that I could 'manually' show/hide the dock widgets (after/before saving/restoring my application's state), but this would 'break' my GUI logic since I have some menu items which I use to show/hide those dock widgets.
The better way is to change you GUI Menu logic to update the hide/show actions based on the currernt QDockWidget visibility.


Also, this wouldn't address the question of how this 'showing'/'hiding' would be triggered which I want to be done through a button within the docking area.
That should is simple, just add a button and connect to hide() slot.


So... I was thinking of customising QMainWindow's docking feature so that it could do what I am after. However, with Qt implementating QMainWidnow's docking feature in private classes means that I cannot customise anything. I am therefore thinking of 'cloning' QMainWindow (and whatever would need 'cloning'), renaming the clone to, say, TMainWindow, customising TMainWindow to my specific needs, and then have my main form inherit from TMainWindow rather than QMainWindow.
Not sure what you intend to change in QMainWindow to fit your requirement, whatever it be, I see this as an over-kill and defenetly will not worth to do.

agarny
13th May 2013, 11:01
The better way is to change you GUI Menu logic to update the hide/show actions based on the currernt QDockWidget visibility.It's already the case. However, when hiding a whole docking area, I wouldn't want the dock widgets to be considered hidden. It's the whole docking area which would be hidden, not the dock widgets themselves.


That should is simple, just add a button and connect to hide() slot.Where would you add the button? Which hide() slot are you talking about? Could it be that I didn't make myself clear? I mean, I want the button to be within the docking area, not somewhere else. Also, I want to hide the docking area itself, not the dock widgets it currently holds.


Not sure what you intend to change in QMainWindow to fit your requirement, whatever it be, I see this as an over-kill and defenetly will not worth to do.It might be an overkill, but it would be worth it in the sense that it would support one of my user's requirements. I wish there was another of getting that requirement implemented, but Qt's private implementations prevent me from doing it at this stage. That is, unless I missed something...

Santosh Reddy
13th May 2013, 11:39
It this what you want to do?


#include <QtGui>
#include <QApplication>

class DockWidget : public QDockWidget
{
Q_OBJECT
public:
explicit DockWidget(const QString &title, QWidget *parent = 0, Qt::WindowFlags flags = 0)
: QDockWidget(title, parent, flags)
{
QGroupBox * groupBox = new QGroupBox;
QPushButton * pushButton = new QPushButton("Hide");
connect(pushButton, SIGNAL(clicked()), SLOT(hide()));
groupBox->setLayout(new QGridLayout);
groupBox->layout()->addWidget(pushButton);
setWidget(groupBox);
}
};

int main(int argc, char **argv)
{
QApplication app(argc, argv);

QMainWindow mainWindow;
mainWindow.showMaximized();

{
QGroupBox * groupBox = new QGroupBox;
QLabel * label = new QLabel("Central Widget");
label->setFont(QFont("Arial", 24));
groupBox->setLayout(new QGridLayout);
groupBox->layout()->addWidget(label);
mainWindow.setCentralWidget(groupBox);
}

DockWidget * dockWidget = new DockWidget("DockWidget");
mainWindow.addDockWidget(Qt::LeftDockWidgetArea, dockWidget, Qt::Vertical);

return app.exec();
}

#include "main.moc"

agarny
13th May 2013, 13:06
It this what you want to do?No, this is not what I am after.

Ok, here is a screenshot of my application:

9029

To the left, you can see 3 dock widgets docked to my application's left docking area, and one dock widget docked to my application's right docking area. Now, what I would like is for a button to be roughly where the red arrows point, i.e. to the left/right of the splitter between the left/right docking area and the central widget. Then, if I was to click on each of those buttons, I would end up with the following GUI:

9030

The button would always be visible (as long as the docking area to which it belongs contains dock widgets) and would display a glyph to indicate whether clicking on it would show/hide its contents.

Santosh Reddy
13th May 2013, 13:31
In that case you cannot hide the QDockWidget. You should have two widget's in QDockWidget, one is the button to hide/show, and the other widget is the content which is actually hidded/showed. So at the end you will still have the QDockWidget visible with just the button.

agarny
13th May 2013, 13:48
In that case you cannot hide the QDockWidget. You should have two widget's in QDockWidget, one is the button to hide/show, and the other widget is the content which is actually hidded/showed. So at the end you will still have the QDockWidget visible with just the button.Unless I missed something, your solution implies that each dock widget would have a show/hide button (i.e. 3 show/hide buttons for the left docking area and 1 show/hide button for the right docking area in my first screenshot) while I want only one show/hide button for a given docking area.

Santosh Reddy
13th May 2013, 14:21
while I want only one show/hide button for a given docking area.
The you need to have one dock of left, and one dock on right. The three content widgets on left will have to put onto another QWidget in a QVBoxLayout (or whatever you like), that way you will have one button per docking area

agarny
13th May 2013, 14:36
The you need to have one dock of left, and one dock on right. The three content widgets on left will have to put onto another QWidget in a QVBoxLayout (or whatever you like), that way you will have one button per docking areaWould that still allow me to arrange my dock widgets as I want? For example, say that I want 2 dock widgets to be side by side and the third one 'below' them. Could that be done? Say that I want 2 dock widgets to be within a tab widget. Could that be done? Etc. All of that can be done by default, but I am not sure this could be done using your approach. Also, I don't believe there is anything that could prevent me from dragging/dropping one of the 3 dock widgets onto the button widget, thus making it a tab widget with two tabs: one for the dock widget and another for the button widget. Otherwise, in your solution, I get the feeling that there would be a splitter which could be used to resize the button widget while no such splitter should be present.

Anyway, I imagine that what I am after is quite specific, and I really can't think of a way to do it using what is currently available in Qt...