PDA

View Full Version : Dock of dock



Rakma74
19th August 2012, 17:21
Dear Sirs,


I'm using Qt for a software project I recently started, and the development is in a good way... this tool is fantatic, and the Qt creator IDE so friendly...

However, I would have a question concerning the windows:
I currently use around 8 dock windows, and I would like to display them in 2 'screen large' separate windows (4 docks in each), and to have the possibility to chose the current large window which would display the 4 docks (by the menu, or whatever).

I was thinking about using 2 large docks and trying to dock 4 windows inside both, impossible, because the addDockWidget function can't be used on docks...
I was also waondering if there would be a possibility to create 2 main windows...

If you would have any type, please, let me know !

Thanks in advance,

Best Regards,

Stéphane

Added after 1 4 minutes:

PS:
I just discovered that it could probably be possible using this:




#include <QtGui>
#include <QDebug>

// #include "main.moc"

class Window: public QMainWindow
{
Q_OBJECT
public:
Window(QWidget *p = 0): QMainWindow(p) {
count = 0;
central = new QLabel(this);
setCentralWidget(central);
}
public slots:
void receive() {
central->setText(QString::number(count++));
}
private:
QLabel *central;
int count;
};

class Controller: public QObject {
Q_OBJECT
public:
Controller(QObject *parent = 0): QObject(parent) {
m_winA = new Window();
m_winA->setWindowTitle("Window A");
connect(this, SIGNAL(signalA()), m_winA, SLOT(receive()));

m_winB = new Window();
m_winB->setWindowTitle("Window B");
connect(this, SIGNAL(signalB()), m_winB, SLOT(receive()));

m_winA->show();
m_winB->show();

// some fake incoming events
m_count = 0;
connect(&m_timer, SIGNAL(timeout()), this, SLOT(incoming()));
m_timer.start(100);
}
~Controller() {
delete m_winA;
delete m_winB;
}
public slots:
void incoming() {
if (m_count++ % 3 == 0)
emit signalA();
else
emit signalB();
}
signals:
void signalA();
void signalB();
private:
Window *m_winA;
Window *m_winB;

int m_count;
QTimer m_timer;
};

int main(int argc, char *argv[])
{
QApplication app(argc, argv);
Controller c;
return app.exec();
}

//


However, it creates 2 separate windows...

Rakma74
20th August 2012, 10:33
Here you are the best example of what I would like to do:

http://qgroundcontrol.org/screenshots (done with Qt, so it should be possible)

At the top left, there is an index with few buttons, and when clicked it display new large windows (screen size) with dock windows inside...

Hope it gives you some indications about my wish...

Best Regards,

Stéphane

Ginsengelf
20th August 2012, 10:38
Hi, you create two instances of Window in Controller::Controller(), and since none of them has a parent, both become windows (see QWidget::QWidget).

Ginsengelf

Rakma74
20th August 2012, 17:41
Thanks for your answer, I tried with the same parent, without success... :( Always 2 windows...

I finally found the solution using this strategy:

1 QMainWindow <-- 1 DockWidgets <-- 1 QMainWindow <-- n DockWidgets
same QMainWindow <-- 1 DockWidgets <-- 1 QMainWindow <-- n DockWidgets



#include <QtGui>
#include <QDebug>

#include "main.h"

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


QMainWindow *main_window;
main_window = new QMainWindow;

// 2 DOCK WIDGETS FOR THE MAIN WINDOW
QDockWidget *dock;

// N DOCK WIDGETS FOR THE MAIN WINDOWS OF THE 2 DOCK WIDGETS
QDockWidget *sub_dock;


// MAIN DOCK 1 -----------------------------------------------

dock = new QDockWidget("W1", main_window);

QMainWindow *Sub_window1;
Sub_window1 = new QMainWindow;
dock->setWidget(Sub_window1);

main_window->addDockWidget(Qt::TopDockWidgetArea, dock);

// -----------------------------------------------------------


// 2 dock widgets to be added to the MAIN DOCK 1
QWidget *widg1;
QWidget *widg2;

sub_dock = new QDockWidget("SW1", Sub_window1);
widg1 = new QWidget;
sub_dock->setWidget(widg1);
Sub_window1->addDockWidget(Qt::TopDockWidgetArea, sub_dock);

sub_dock = new QDockWidget("SW2", Sub_window1);
widg2 = new QWidget;
sub_dock->setWidget(widg2);
Sub_window1->addDockWidget(Qt::TopDockWidgetArea, sub_dock);



// MAIN DOCK 2 -----------------------------------------------

dock = new QDockWidget("W2", main_window);

QMainWindow *Sub_window2;
Sub_window2 = new QMainWindow;
dock->setWidget(Sub_window2);

main_window->addDockWidget(Qt::TopDockWidgetArea, dock);

// -----------------------------------------------------------


main_window->show();


return app.exec();
}




Thanks for all !!

Best Regards,

Stéphane

Added after 1 58 minutes:

Sorry, I have another question.

How would it be possible to dock 2 Dock windows (in a QMainWindow) with this property: each dock would take the whole QMainWindow size, and we could switch from a dock to another by clicking on their name.

To do that, I have to move the dock manually with the mouse, I would like to know if it is possible on start...

Thanks in advance,

Stéphane

ChrisW67
21st August 2012, 03:38
Sounds like the QMainWindow::AllowTabbedDocks (the default) and/or QMainWindow::ForceTabbedDocks option. See setDockOption().

If you do not intend that the user is able to float these widgets off in their own windows then it looks like your whole design would be better matched by a QStackedWidget containing a series of QTabWidget pages containing what you are currently placing in the dock widgets.

Rakma74
21st August 2012, 11:11
Thanks so much for your answer, this is exactely what I was looking for.

However, I tried with this code


// Force the 2 main dock windows to be tabbed
main_window->setDockOptions(QMainWindow::ForceTabbedDocks);


without success... There seems to be a bug from Qt
https://bugreports.qt-project.org/browse/QTBUG-9545?page=com.atlassian.jira.plugin.system.issueta bpanels:all-tabpanel

Fortunately, another post, I just found thanks to your answer, gave me the solution :
http://www.qtcentre.org/threads/8566-QMainWindow-(ForceTabbedDocks)

So, now I do this :



// 2 DOCK WIDGETS FOR THE MAIN WINDOW
QDockWidget *dock1;
QDockWidget *dock2;

... ...

main_window->tabifyDockWidget(dock1, dock2);



Thanks for all,

Stéphane

Added after 54 minutes:

Important : On Startup, W2 was visible by default, and I wanted W1 to be visible...

It can be done with the following command:

// Make first main dock window visible
dock1->raise();

Best Regards,

Stéphane