Russian Qt Forum
Сентябрь 30, 2024, 10:24 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Вывести QMessageBox поверх всех окон  (Прочитано 9238 раз)
QtProger
Гость
« : Июнь 30, 2010, 14:21 »

Как это сделать ?
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #1 : Июнь 30, 2010, 14:34 »

Код
C++ (Qt)
#ifdef Q_WS_X11
#include <QX11Info>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#endif
 
static void activateWindow( QWidget* w )
{
if( !w->isShown() )
w->show();
w->raise();
 
#ifdef Q_WS_X11
 
Display* dpy = QX11Info::display();
 
XClientMessageEvent ev = { 0 };
 
ev.type = ClientMessage;
ev.window = w->winId();
ev.message_type = XInternAtom( dpy, "_NET_ACTIVE_WINDOW", False );
ev.format = 32;
ev.send_event = True;
ev.data.l[1] = QX11Info::appUserTime();
 
XSendEvent( dpy,
RootWindowOfScreen( DefaultScreenOfDisplay( dpy) ), False,
SubstructureRedirectMask | SubstructureNotifyMask, (XEvent*) &ev );
XSync( dpy, False );
 
#elif defined(Q_OS_WIN)
 
SetWindowPos( w->winId(), HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
 
#endif
 
w->activateWindow();
}
 
class YourMessageBox : public QMessageBox
{
     ...
     ...
     virtual void setVisible ( bool visible )
     {
          QMessageBox::setVisible( visible );
          if( visible )
            activateWindow( this );
     }
};
 

Но если используете статические методы QMessageBox, то придётся вешать eventFilter:
Код
C++ (Qt)
class YourMainWindow : public QMainWindow
{
public:
      YourMainWindow( QWidget* parent = 0 ) : QMainWindow( parent )
      {
          qApp->installEventFilter( this );
      }
 
      bool eventFilter( QObject* o, QEvent* e )
      {
QWidget* w = o->isWidgetType() ? qobject_cast< QWidget* >( o ) : 0;
 
if( e->type() == QEvent::ShowToParent && w && w->window() == w &&
( w->windowType() == Qt::Window || w->windowType() == Qt::Dialog ) )
{
activateWindow( w );
}
return false;
      }
};
 

Последний вариант, имхо, предпочтительней, т.к. решает проблему для всех top-level и диалоговых окон.
« Последнее редактирование: Июнь 30, 2010, 14:49 от GreatSnake » Записан

Qt 5.11/4.8.7 (X11/Win)
tim474
Гость
« Ответ #2 : Июнь 30, 2010, 15:43 »

А флаг WindowStaysOnTopHint?
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #3 : Июнь 30, 2010, 16:02 »

Цитировать
А флаг WindowStaysOnTopHint?
Сей флаг просто "держит" окно поверх других не активируя его.
Записан

Qt 5.11/4.8.7 (X11/Win)
QtProger
Гость
« Ответ #4 : Июнь 30, 2010, 16:12 »

Сей флаг просто "держит" окно поверх других не активируя его.

Мне как раз это нужно. QMessageBox должен быть поверх всех окон. Активировать его не обязательно.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #5 : Июнь 30, 2010, 16:22 »

Цитировать
Активировать его не обязательно.
Это как это?
Какой толк от активного модального диалога наверху, если он не будет иметь клавиатурного фокуса?
Это ущербный gui получается.
Записан

Qt 5.11/4.8.7 (X11/Win)
QtProger
Гость
« Ответ #6 : Июнь 30, 2010, 16:30 »

Какой толк от активного модального диалога наверху, если он не будет иметь клавиатурного фокуса?
Это ущербный gui получается.

Клавиатурный фокус не требуется. QMessageBox я использую лишь в качестве уведомления.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #7 : Июнь 30, 2010, 16:34 »

Цитировать
Клавиатурный фокус не требуется. QMessageBox я использую лишь в качестве уведомления.
Т.е. когда всплывёт этот диалог, юзер не сможет нажать <Esc>, <Enter> или <Space>, чтобы его убрать?
Или я чего-то не понимаю, или ...
« Последнее редактирование: Июнь 30, 2010, 16:39 от GreatSnake » Записан

Qt 5.11/4.8.7 (X11/Win)
QtProger
Гость
« Ответ #8 : Июнь 30, 2010, 16:57 »

Т.е. когда всплывёт этот диалог, юзер не сможет нажать <Esc>, <Enter> или <Space>, чтобы его убрать?
Или я чего-то не понимаю, или ...

Да, было бы неплохо сделать клавиатурный фокус. Но вот что написано в справке к void QWidget::activateWindow ():

Цитировать
On Windows, if you are calling this when the application is not currently the active one then it will not make it the active window. It will change the color of the taskbar entry to indicate that the window has changed in some way. This is because Microsoft does not allow an application to interrupt what the user is currently doing in another application.

Из этого текста я понял, что в Виндовсе нельзя активировать окно приложения.
« Последнее редактирование: Июнь 30, 2010, 17:01 от QtProger » Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #9 : Июнь 30, 2010, 17:07 »

Хм, а для чего я выше привёл код альтернативного activateWindow()?
Записан

Qt 5.11/4.8.7 (X11/Win)
QtProger
Гость
« Ответ #10 : Июнь 30, 2010, 17:29 »

GreatSnake, я вставил твой код в widget.h, компилятор выдал кучу ошибок. Ошибки я написал в комментариях:

Код
C++ (Qt)
class YourMainWindow : public QMainWindow
{ //error: expected class-name before '{' token
public:
      YourMainWindow( QWidget* parent = 0 ) : QMainWindow( parent ) //error: class 'YourMainWindow' does not have any field named 'QMainWindow'
      {
               qApp->installEventFilter( this ); //error: no matching function for call to 'QApplication::installEventFilter(YourMainWindow* const)'
      }
 
      bool eventFilter( QObject* o, QEvent* e )
      {
               QWidget* w = o->isWidgetType() ? qobject_cast< QWidget* >( o ) : 0;
 
               if( e->type() == QEvent::ShowToParent && w && w->window() == w &&
                       ( w->windowType() == Qt::Window || w->windowType() == Qt::Dialog ) )
               {
                       activateWindow( w ); //error: 'activateWindow' was not declared in this scope
               }
               return false;
      }
};
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #11 : Июнь 30, 2010, 17:34 »

Мде...
Записан

Qt 5.11/4.8.7 (X11/Win)
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.667 секунд. Запросов: 22.