QDialog behavior changes when Qt::FramelessWindowHint is applied to it.
Hello,
i am facing a very weird problem. If i use Qt::FramelessWindowHint when constructing a QDialog, it's behavior is different than when i don't use the frameless flag. So far, i have noticed two major differences but i only have been able to workaround one.
1) The placement is not the same.
When calling ->show() on such QDialog-derived classes, the dialog isn't centered to it's parent QDialog. Instead, its top-left corner is being centered. So my workaround for this problem is to call move((this->width()-dlg->width())/2, (height()-dlg->height())/2); No big deal, but very weird.
2) The accept / reject messages are being "bubbled" to the parent dialog.
When such frameless dialog is shown, if i press the close button (Directly connected to the close() slot of the dialog), everything is fine. However, if i press ESC, the dialog gets discarded as expected, but the parent dialog too. i am looking for either a solution to this problem, or maybe to another way of making the dialog frameless.
Note that i'm using Qt OpenSource 4.8.0 on Windows, and it might be interesting to know if the issues are the same on linux / MacOS.
Thanks,
Pierre.
Re: QDialog behavior changes when Qt::FramelessWindowHint is applied to it.
It would help your cause if you posted a minimal, compilable code snippet that demonstrates the problem(s).
Re: QDialog behavior changes when Qt::FramelessWindowHint is applied to it.
Hello,
Here it is.
Code:
#ifndef DlgTest_h
#define DlgTest_h
#include <QtCore/QDebug>
#include <QtGui/QDialog>
#include <QtGui/QPalette>
#include <QtGui/QTextEdit>
#include <QtGui/QPushButton>
#include <QtGui/QGridLayout>
Q_OBJECT
public:
/**/ DlgTest
(quint32 num,
QWidget *p
=0, Qt
::WFlags f
=Qt
::FramelessWindowHint|Qt
::X11BypassWindowManagerHint) : QDialog(p, f
), _txt
(0), _num
(num
) { //setWindowFlags ();
if (_num>1)
setModal (true);
// Layout, button, and text box.
_txt
->setText
(QString::number(_num
));
grid->addWidget (_txt);
grid->addWidget (btn);
setLayout (grid);
// Upon clicking the button, launch another dialog.
connect(btn, SIGNAL(clicked()), this, SLOT(mainButtonClicked()));
};
protected slots:
void mainButtonClicked () {
DlgTest *dlg = new DlgTest(_num+1, this);
connect(dlg, SIGNAL(finished(int)), dlg, SLOT(deleteLater()));
dlg->show ();
qDebug() << dlg->geometry();
};
private:
quint32 _num;
};
#endif
You will start the first instance of this dialog with this in your main():
Now, you will try the code with the flags that are in the constructor. Each new dialog will be offsetted.
After testing with these flags, you will replace "Qt::FramelessWindowHint|Qt::X11BypassWindowManage rHint" by 0, and try again.
The behavior i get with this minimal example isn't even the same as the one i have in my app... The offset being negative, in my app it's positive.
And the "ESC" problem isn't even here, so i guess it's related to something else i do in my app... i'll try to dig further.
Sorry for the indentation... Visual studio doesn't seem to understand what soft tabs are on this computer.
[edit]
i found what to do to reproduce the ESC bug. Remove the flags from the constructor (Replace them by 0 by default). Then, put this in the constructor:
Code:
setWindowFlags(Qt::Dialog|Qt::FramelessWindowHint|Qt::X11BypassWindowManagerHint);
i have tried:
Code:
setWindowFlags(windowFlags()|Qt::FramelessWindowHint|Qt::X11BypassWindowManagerHint);
But the result is even different and unusable. So maybe i misunderstood the use of those flags?
[/edit]
Pierre.
Re: QDialog behavior changes when Qt::FramelessWindowHint is applied to it.
Your dialog changes position because of sanity check in QDialog::adjustPosition().
Frameless windows will be offseted from their parent by (minus) 10x40px.
I would expect the linux to behave the same (I haven't checked it though).
As to the ESC issue - I couldn't reproduce it. Works fine for me no mater what I do (qt 4.6.3, w7).
If you're looking for a different way to make dialog 'frameless' then add this to your dialog (and get rid of all other flags):
Code:
{
this
->setMask
( QRegion( this
->rect
() ) );
}
Re: QDialog behavior changes when Qt::FramelessWindowHint is applied to it.
Hello Spitfire, and thanks a lot for your help.
Your technique is very interesting, and i will try it.
As for the modals dialogs disappearing all at the same time when pressing ESC, i have found a workaround (Which is kind of ugly and forces me to keep track of windows orders, hide them, show them, etc so i can make the dialogs non-modal without risking to allow the user to change values in the parent windows).
If you are interested in reproducing the ESC bug, make my example dialog class modal (setModal(true)).
Thanks again!
Pierre.
Re: QDialog behavior changes when Qt::FramelessWindowHint is applied to it.
I've tried both modal and non-modal dialogs and in both cases ESC acts as expected (unless you press and hold it).
I personally believe you're doing something wrong as this should not happen.
Are you handling events yourself somewhere?
I don't have Qt 4.8 to try at the moment but I don't think it's a Qt issue.
Re: QDialog behavior changes when Qt::FramelessWindowHint is applied to it.
Hello again Spitfire!
i'm not handling events (The example i have posted reproduces the problem on my environment, Windows XP and Qt 4.8.0 compiled as dynamic).
i will try to make a small video showing the issue if i get a bit time to do so.
Thanks for your help,
Pierre.
Re: QDialog behavior changes when Qt::FramelessWindowHint is applied to it.
I've tested your class on w7 qt 4.8.1 (vm) and everything works as expected.