PDA

View Full Version : Disable Close button (X) of a QDialog



BrainB0ne
2nd October 2007, 16:41
Hello,

I want to know if it is possible to disable the close button (X) of a QDialog during a Process.
After my Process is finished i want to enable the close button (X) again.

Posted some screenshots of an example to show what i mean.

http://img233.imageshack.us/img233/1830/closeenabledle2.jpg
http://img233.imageshack.us/img233/3424/closedisabledaa3.jpg


Any help is welcome :)

Greetz,

marcel
2nd October 2007, 17:29
I didn't manage to do it by using the Qt window flags, but it is possible using winapi:


#ifdef Q_WS_WIN
CMenu* menu = this->GetSystemMenu(FALSE);
menu->ModifyMenu(SC_CLOSE, MF_BYCOMMAND | MF_GRAYED );
#endif

rajesh
3rd October 2007, 09:20
Marcel,
this is not a Qt code. it is VC++ code.

marcel
3rd October 2007, 10:56
And what did I say?
It's not VC code, but it is winapi code. Please notice the ifdefs.

rajesh
3rd October 2007, 11:50
BrainB0ne,

try this:
setWindowFlags(Qt::FramelessWindowHint);
setWindowFlags(Qt::WindowTitleHint);

marcel
3rd October 2007, 11:55
The second setWindowFlags overrides the first.
And he said disable the button, not hide it. But I guess that's a solution too.

rajesh
3rd October 2007, 12:02
the first flag reset all flag to 0, so,it is also required.

marcel
3rd October 2007, 12:20
No.
Using the second flag only yields the same result.
setWindowFlags(Qt::WindowTitleHint) will result in the window flags to be JUST Qt::WindowTitleHint.

If you want to set more than one flag you have to OR them:
setWindowFlags(flag1 | flag2 | ... | flagn );

BrainB0ne
9th October 2007, 17:19
Damn i am really late with reacting.... sorry for that u guys.

I am gonna try some of the solutions mentioned... i will tell you about what i have done :)

BrainB0ne
9th October 2007, 17:37
hmmm... I dont get Marcel's solution to work with the Winapi code.

And the next solution with the windowflags also doesnt work at Qt 3, the mentioned defines do not exist.

Maybe i have to search trough the Qt 3 Assistent for appropriate window flags.

Thx for your help and till next time :)

marcel
9th October 2007, 18:55
hmmm... I dont get Marcel's solution to work with the Winapi code.

Do you get any errors or it just doesn't work?



Maybe i have to search trough the Qt 3 Assistent for appropriate window flags.

See http://doc.trolltech.com/3.3/qt.html#WidgetFlags-enum.
Play with different combinations until you get some result. But it really depends on the window manager to respect the flags.

BrainB0ne
10th October 2007, 11:42
Do you get any errors or it just doesn't work?

See http://doc.trolltech.com/3.3/qt.html#WidgetFlags-enum.
Play with different combinations until you get some result. But it really depends on the window manager to respect the flags.


With the Winapi code I first get the following errors:



#ifdef Q_WS_WIN

CMenu* menu = m_pParent->GetSystemMenu(FALSE);
menu->ModifyMenu(SC_CLOSE, MF_BYCOMMAND | MF_GRAYED );

#endif

: error C2065: 'CMenu' : undeclared identifier
: error C2065: 'menu' : undeclared identifier
: error C2039: 'GetSystemMenu' : is not a member of 'QWidget'
: see declaration of 'QWidget'
: error C2227: left of '->ModifyMenu' must point to class/struct/union
: error C2065: 'SC_CLOSE' : undeclared identifier
: error C2065: 'MF_BYCOMMAND' : undeclared identifier
: error C2065: 'MF_GRAYED' : undeclared identifier


After that i include the <afxwin.h> include file (for CMenu class)
Then the following errors show up:
C:\Program Files\Microsoft Visual Studio\VC98\MFC\INCLUDE\afx.h(226) : warning C4005: 'ASSERT' : macro redefinition
C:\Qt\3.3.4\include\qglobal.h(1010) : see previous definition of 'ASSERT'
: error C2039: 'GetSystemMenu' : is not a member of 'QWidget'
C:\Qt\3.3.4\include\qwidget.h(60) : see declaration of 'QWidget'

jpn
10th October 2007, 13:03
That's MFC, not WinAPI... ;)


#include <QtGui>
#ifdef Q_WS_WIN
#include <qt_windows.h>
#endif // Q_WS_WIN

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

#ifdef Q_WS_WIN
HMENU menu = ::GetSystemMenu(window.winId(), FALSE);
::DeleteMenu(menu, SC_CLOSE, MF_BYCOMMAND);
::EnableMenuItem(menu, SC_CLOSE, MF_BYCOMMAND | MF_GRAYED);
// or (removes the item in of system menu)
// ::DeleteMenu(menu, SC_CLOSE, MF_BYCOMMAND);
#endif // Q_WS_WIN

window.show();
return app.exec();
}

BrainB0ne
10th October 2007, 14:34
That's MFC, not WinAPI... ;)


#include <QtGui>
#ifdef Q_WS_WIN
#include <qt_windows.h>
#endif // Q_WS_WIN

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

#ifdef Q_WS_WIN
HMENU menu = ::GetSystemMenu(window.winId(), FALSE);
::DeleteMenu(menu, SC_CLOSE, MF_BYCOMMAND);
::EnableMenuItem(menu, SC_CLOSE, MF_BYCOMMAND | MF_GRAYED);
// or (removes the item in of system menu)
// ::DeleteMenu(menu, SC_CLOSE, MF_BYCOMMAND);
#endif // Q_WS_WIN

window.show();
return app.exec();
}


Woooow! That did the job! :D I'm really happy with this solution :D :cool:

blue.death
6th November 2007, 13:06
Hi guys,
I'm quite late on this thread but I had the same problem :-)

Anybody knows how to disable that nasty little button on X11 and Mac OS X??

In case you need it, here is a nice macro I am using on Win32 - it's pretty similar to the latest post of course and it works fine:



# ifdef Q_OS_WIN
# include <windows.h>
# define ENABLE_CLOSE_BTN(Enable) \
{ QWidget* tlw = this; \
while (tlw && !tlw->isWindow() && tlw->windowType() != Qt::SubWindow) \
tlw = tlw->parentWidget(); \
HMENU hMenu = GetSystemMenu((HWND) tlw->winId(), FALSE); \
EnableMenuItem(hMenu, SC_CLOSE, Enable ? (MF_BYCOMMAND | MF_ENABLED) : (MF_BYCOMMAND | MF_GRAYED)); }
# endif // Q_OS_WIN


Now just use ENABLE_CLOSE_BTN(true) or ENABLE_CLOSE_BTN(false).

It will detect the top level widget of the widget containing the code, so you can use it inside of a child widget (eg. a wizard page in my case) without having to change the macro :D
Feel free to replace that "while" loop if you are always going to use it inside of a top level window.

And now on with your suggestions for X11/MAC ;)

MarkoSan
7th December 2007, 06:45
How do I hide close, resize and minimize featuers in QGLWidget??

setWindowFlags(Qt::FramelessWindowHint); does not work!!

jpn
7th December 2007, 09:47
How do I hide close, resize and minimize featuers in QGLWidget??

setWindowFlags(Qt::FramelessWindowHint); does not work!!
What do you mean? Are you showing QGLWidget as a top level window? QGLWidget is a QWidget so when it comes to adjusting window flags, anything that works for a plain QWidget should work with QGLWidget as well.

GokuH12
11th March 2009, 17:35
Hi guys,
I'm quite late on this thread but I had the same problem :-)

Anybody knows how to disable that nasty little button on X11 and Mac OS X??

In case you need it, here is a nice macro I am using on Win32 - it's pretty similar to the latest post of course and it works fine:



# ifdef Q_OS_WIN
# include <windows.h>
# define ENABLE_CLOSE_BTN(Enable) \
{ QWidget* tlw = this; \
while (tlw && !tlw->isWindow() && tlw->windowType() != Qt::SubWindow) \
tlw = tlw->parentWidget(); \
HMENU hMenu = GetSystemMenu((HWND) tlw->winId(), FALSE); \
EnableMenuItem(hMenu, SC_CLOSE, Enable ? (MF_BYCOMMAND | MF_ENABLED) : (MF_BYCOMMAND | MF_GRAYED)); }
# endif // Q_OS_WIN


Now just use ENABLE_CLOSE_BTN(true) or ENABLE_CLOSE_BTN(false).

It will detect the top level widget of the widget containing the code, so you can use it inside of a child widget (eg. a wizard page in my case) without having to change the macro :D
Feel free to replace that "while" loop if you are always going to use it inside of a top level window.

And now on with your suggestions for X11/MAC ;)

Woo so good! thx for the nice macro! its works just nice :p

shad
28th April 2009, 10:37
Starting with Qt 4.5 there is a new window hint for controlling close button Qt::WindowCloseButtonHint:


QWidget w;
w.setWindowFlags(Qt::Window | Qt::CustomizeWindowHint | Qt::WindowTitleHint| Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonHint);

BrainB0ne
28th April 2009, 11:41
Starting with Qt 4.5 there is a new window hint for controlling close button Qt::WindowCloseButtonHint:


QWidget w;
w.setWindowFlags(Qt::Window | Qt::CustomizeWindowHint | Qt::WindowTitleHint| Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonHint);

That's very nice to hear/know when i'm going to use Qt 4.5 or higher in the future! :)

MarkoSan
28th April 2009, 14:17
That's very nice to hear/know when i'm going to use Qt 4.5 or higher in the future! :)

Very nice, thanks, but, is it possible to disable (X) in dialog that resided on QGraphicsView, I've read in the docs that is NOT possible ...

sophister
28th April 2009, 17:57
I use the same code in QT4.5, but it doesn't work!!
why??

kyue
3rd June 2009, 22:11
Anybody knows how to disable that nasty little button on X11 and Mac OS X??


I have the exact same problem. I'm using Qt 4.3 and don't have the luxury of Qt::WindowMinMaxButtonHint. :(

I need to keep the title bar empty, so Qt::FramelessWindowHint makes the message box a bit bare.

It was suggested that we can inherit a QDialog box and disable it there...would anyone else know of any other suggestions?

Thanks,
Kat

shad
3rd June 2009, 22:19
It was suggested that we can inherit a QDialog box and disable it there...would anyone else know of any other suggestions?
try upgrading to qt 4.5

lni
3rd June 2009, 22:40
Try this



#include <qapplication.h>
#include <qevent.h>
#include <qpushbutton.h>
#include <qdialog.h>
#include <qmessagebox.h>
#include <iostream>

class MyDialog : public QDialog
{
public:

MyDialog( QWidget* parent=0 ) : QDialog( parent ) {
}

protected:

void closeEvent ( QCloseEvent * event ) {
event->ignore();
QMessageBox::information( this, "Close?", "Close? No way!" );
}
};

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

MyDialog dlg;
QPushButton* button = new QPushButton( "Exit", &dlg );
QObject::connect( button, SIGNAL( clicked() ),
&app, SLOT( quit() ) );
dlg.resize( 300, 300 );
dlg.show();

return app.exec();

}

kyue
11th June 2009, 16:58
try upgrading to qt 4.5

Sorry, I didn't see these replies until now. It's not an option for us right now.

kyue
11th June 2009, 17:04
Try this



#include <qapplication.h>
#include <qevent.h>
#include <qpushbutton.h>
#include <qdialog.h>
#include <qmessagebox.h>
#include <iostream>

class MyDialog : public QDialog
{
public:

MyDialog( QWidget* parent=0 ) : QDialog( parent ) {
}

protected:

void closeEvent ( QCloseEvent * event ) {
event->ignore();
QMessageBox::information( this, "Close?", "Close? No way!" );
}
};

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

MyDialog dlg;
QPushButton* button = new QPushButton( "Exit", &dlg );
QObject::connect( button, SIGNAL( clicked() ),
&app, SLOT( quit() ) );
dlg.resize( 300, 300 );
dlg.show();

return app.exec();

}




Thank you for your reply. Yes, this was a solution that was considered. I'm wondering if there is another solution where we don't have to inherit and ignore the closeEvent...

kyue
18th June 2009, 00:27
If this helps anyone, you can remove the three buttons on the top left (close, minimize, maximize) on a Mac and leaving the title there using:


setWindowModality(Qt::WindowModal);

rajesh
18th June 2009, 06:53
try Window flags
see the example: http://doc.trolltech.com/4.3/widgets-windowflags.html

totem
8th December 2009, 18:01
hi

this did the job for me (on a QDialog based class) :


Qt::WindowFlags flags = windowFlags() ;
flags |= Qt::CustomizeWindowHint ;
flags &= ~Qt::WindowCloseButtonHint ;
setWindowFlags( flags ) ;