Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date
All threads index page 4

Qt-interest Archive, April 2008
QDockWidget in a minimized window


Message 1 in thread

Hello,
I have a problem with my QDockWidgets, I have two of them in my main window. 
Now if I minimise the main window and maximise it again, the docks are gone. 
I have options to make them visible again, but it would be nicer if the main 
window would be restored like they were before.

Do I have to implement two slots who react on the minimise/restore signals of 
the main window or is there a way to simply tell the docks that they should 
not close when the main is minimised?

Regards
Simon

--
 [ signature omitted ] 

Message 2 in thread

On Wednesday 16 April 2008 22:21:44 Simon SchÃfer wrote:
> Now if I minimise the main window and maximise it again, the docks
> are gone.
That's obviously a bug. Report it to the task tracker. Include your Qt 
version, Operating system and patch level  (a random guess: X11 and some 
composite manager running) , and if possible a small testcase.
make sure you are using Qt from www.trolltech.com and please do not report 
bugs from a fork.
thank you.

-- 
 [ signature omitted ] 

Message 3 in thread

>  I have a problem with my QDockWidgets, I have two of them in my main window.
>  Now if I minimise the main window and maximise it again, the docks are gone.

Hi Simon. I had a similar problem some time ago and it was definitely
a Qt bug. It all depends of the Qt version you're using. Try the
attached simple test I wrote and see if the same behaviour still
happens on your environment.
#include <QApplication>
#include <QApplication>
#include <QDockWidget>
#include <QLabel>
#include <QMainWindow>
#include <QVBoxLayout>
#include <QWidget>


int main( int argc, char * argv[] )
{
    QApplication app( argc, argv );
    QMainWindow mainWindow;
    QWidget * centralWidget = new QWidget();
    mainWindow.setCentralWidget( centralWidget );
    QVBoxLayout * box = new QVBoxLayout( centralWidget );

    QLabel * label1 = new QLabel( "Hello", centralWidget );
    label1->setAlignment( Qt::AlignHCenter | Qt::AlignVCenter );
    label1->show();

    box->addWidget( label1 );

    QLabel * label2 = new QLabel( "World" );
    label2->setAlignment( Qt::AlignHCenter | Qt::AlignVCenter );
    label2->show();

    QDockWidget * dock = new QDockWidget( "Dock", centralWidget );
    mainWindow.addDockWidget( Qt::RightDockWidgetArea, dock );
    dock->setWidget( label2 );
    dock->show();

    mainWindow.resize( 400, 300 );
    mainWindow.show();
    app.exec();
    return 0;
}

Message 4 in thread

@Arvid:
Sorry forgot to mention the informal stuff:
Qt 4.4.0 rc1
Linux, so yes its X11 with a stable version of KDE(3.5.8) and no composite.
I do not know what you mean by patch level
the kernel is the 2.6.24

> Hi Simon. I had a similar problem some time ago and it was definitely
> a Qt bug. It all depends of the Qt version you're using. Try the
> attached simple test I wrote and see if the same behaviour still
> happens on your environment.

With your program its working, so I tried to find the problem and I found it. 
Its a combination of having a menu entry thats checkable and therefore 
storing the current visibility status of the dock, which in return will not 
being reset when the main-window comes back to a visible state.

I could not find different signals for the dock (one for pressing the X button 
which closes the dock, and one for hide when window is minimised) or 
something similar. Perhaps there is something wrong with the code.

Regards Simon
#include "docktest.h"

docktest::docktest ()
{
	QWidget * centralWidget = new QWidget();
	setCentralWidget( centralWidget );
	QVBoxLayout * box = new QVBoxLayout( centralWidget );
	QLabel * label1 = new QLabel( "Hello", centralWidget );
	label1->setAlignment( Qt::AlignHCenter | Qt::AlignVCenter );
	label1->show();

	box->addWidget( label1 );

	QLabel * label2 = new QLabel( "World" );
	label2->setAlignment( Qt::AlignHCenter | Qt::AlignVCenter );
	label2->show();

	dock = new QDockWidget( "Dock", centralWidget );
	addDockWidget( Qt::RightDockWidgetArea, dock );
	dock->setWidget( label2 );
	dock->show();
	resize( 400, 300 );

	showDockAct = new QAction (tr("Show dock"), this);
	showDockAct->setCheckable (true);

	menu = menuBar ()->addMenu (tr("&Show"));
	menu->addAction (showDockAct);

	connect (dock, SIGNAL (visibilityChanged (bool)), showDockAct, SLOT (setChecked (bool)));
	connect (showDockAct, SIGNAL (changed ()), this, SLOT (showDock ()));
}

void docktest::showDock ()
{
	if (showDockAct->isChecked ())
		dock->show();
	else
		dock->hide();
}
#ifndef __docktest_h
#ifndef __docktest_h
#define __docktest_h

#include <QDockWidget>
#include <QLabel>
#include <QMainWindow>
#include <QVBoxLayout>
#include <QWidget>
#include <QAction>
#include <QMenu>
#include <QMenuBar>


class docktest : public QMainWindow
{
	Q_OBJECT
	public:
		docktest ();

	private slots:
		void showDock ();
	private:
		QAction *	showDockAct;
		QMenu *		menu;
		QDockWidget *	dock;
};
#endif
#include <QApplication>
#include <QApplication>
#include "docktest.h"

int main( int argc, char * argv[] )
{
	QApplication app( argc, argv );
	docktest * test = new docktest ();
	test->show ();
	app.exec();
	return 0;
}

Message 5 in thread

>  With your program its working, so I tried to find the problem and I found it.
>  Its a combination of having a menu entry thats checkable and therefore
>  storing the current visibility status of the dock, which in return will not
>  being reset when the main-window comes back to a visible state.

When I read this, I remembered that that was exactly my issue some
time ago when developing SpeedCrunch, so I took a look at the source
and found the solution (see attached code).


>  I could not find different signals for the dock (one for pressing the X button
>  which closes the dock, and one for hide when window is minimised) or
>  something similar. Perhaps there is something wrong with the code.

You need to install an event filter and check whether it was emitted
from the dock and applies to the close event. Also, you need to remove
the connection for the visibility change event that you added because
it breaks the functionality. Please tell me if this code doesn't solve
the problem on your environment.
#include <QApplication>
#include <QApplication>
#include "docktest.h"

int main( int argc, char * argv[] )
{
	QApplication app( argc, argv );
	docktest * test = new docktest ();
	test->show ();
	app.exec();
	return 0;
}
#ifndef __docktest_h
#ifndef __docktest_h
#define __docktest_h

#include <QDockWidget>
#include <QLabel>
#include <QMainWindow>
#include <QVBoxLayout>
#include <QWidget>
#include <QAction>
#include <QMenu>
#include <QMenuBar>


class docktest : public QMainWindow
{
	Q_OBJECT
	public:
		docktest ();
		virtual bool eventFilter( QObject *, QEvent * );

	private slots:
		void showDock ();
	private:
		QAction *	showDockAct;
		QMenu *		menu;
		QDockWidget *	dock;
};
#endif
#include <QEvent>
#include <QEvent>

#include "docktest.h"


docktest::docktest ()
{
	QWidget * centralWidget = new QWidget();
	setCentralWidget( centralWidget );
	QVBoxLayout * box = new QVBoxLayout( centralWidget );
	QLabel * label1 = new QLabel( "Hello", centralWidget );
	label1->setAlignment( Qt::AlignHCenter | Qt::AlignVCenter );
	label1->show();

	box->addWidget( label1 );

	QLabel * label2 = new QLabel( "World" );
	label2->setAlignment( Qt::AlignHCenter | Qt::AlignVCenter );
	label2->show();

	dock = new QDockWidget( "Dock", centralWidget );
	addDockWidget( Qt::RightDockWidgetArea, dock );
	dock->setWidget( label2 );
	dock->installEventFilter( this );
	dock->show();
	resize( 400, 300 );

	showDockAct = new QAction (tr("Show dock"), this);
	connect (showDockAct, SIGNAL (changed ()), this, SLOT (showDock ()));
	showDockAct->setCheckable (true);
	showDockAct->setChecked (true);

	menu = menuBar ()->addMenu (tr("&Show"));
	menu->addAction (showDockAct);
}


bool docktest::eventFilter( QObject * o, QEvent * e )
{
    if ( o == dock )
    {
	if ( e->type() == QEvent::Close )
	{
	    qDebug("Dock close button pressed");
	    showDockAct->blockSignals( true );
	    showDockAct->setChecked( false );
	    showDockAct->blockSignals( false );
	    return true;
	}
	return false;
    }

    return QMainWindow::eventFilter( o, e );
}


void docktest::showDock ()
{
	if (showDockAct->isChecked ())
		dock->show();
	else
		dock->hide();
}

Message 6 in thread

> You need to install an event filter and check whether it was emitted
> from the dock and applies to the close event. Also, you need to remove
> the connection for the visibility change event that you added because
> it breaks the functionality. Please tell me if this code doesn't solve
> the problem on your environment.

The code worked thanks a lot. 

But I still think that it would be cleaner to have signals better signals from 
the QDockwidget (like one for hide and one for close)

Simon

--
 [ signature omitted ]