Событие ActivationChange окна QT под Linux

У меня есть следующая проблема: у меня есть окно, похожее на «всплеск», в моем приложении, и на нем есть несколько кнопок для открытия последнего проекта, создания нового и т. д. При нажатии эти кнопки скрывают окно и делать вещи.

Это окно создается со следующим кодом и флагами:

void MainWindowButtonDialog::showMe()
{
    setModal(false);
    setWindowFlags(Qt::SplashScreen | Qt::CustomizeWindowHint |
                      Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint);
    show();
}

Окно называется m_btnDlg.

Теперь, из-за запросов от клиентов, когда приложение теряет фокус, мне нужно скрыть это окно, а когда приложение получает фокус, мне нужно снова показать его. Это делается с помощью следующего кода:

void MainWindow::changeEvent(QEvent *e)
{
    if( e->type() == QEvent::WindowStateChange )
    {
        if( isMinimized() )
        {
            if(m_btndlg && m_btndlg->isVisible())
            {
                m_btndlg->hide();
                m_splashWasVisible = true;
            }
        }
        else
        {
            if(m_splashWasVisible)
            {
                m_btndlg->show();
                m_splashWasVisible = false;
            }
        }
    }
    if(e->type() == QEvent::ActivationChange)
    {
        if(!isActiveWindow())
        {
            if(m_btndlg && m_btndlg->isVisible() && !m_btndlg->isActiveWindow())
            {
                m_btndlg->hide(); // *****
                m_splashWasVisible = true;
            }
        }
        else
        {
            if(m_splashWasVisible)
            {
                m_btndlg->show();
                m_splashWasVisible = false;
            }
        }
    }
    QMainWindow::changeEvent(e);
}

Теперь к проблеме: приведенный выше код до сих пор отлично работал (как под Linux - Gnome 2.x на CentOS 5.x, так и под KDE 3.x, а также под Windows, все интересные версии). Недавно клиент установил несколько систем Fedora, а также Gnome 3, KDE 4 и т. д., и вдруг приложение ведет себя странно. Когда я нажимаю кнопку, чтобы создать новый проект, он скрывает заставку, и ничего не происходит. Строка, отмеченная ** выше, является ответственной. Кажется, что эти новые оконные менеджеры отправляют события активации не по порядку.

Есть ли у кого-нибудь опыт с этим?

(Дополнительный код доступен по запросу). Мы используем Qt 4.6.3 спасибо.


person Ferenc Deak    schedule 21.03.2012    source источник


Ответы (1)


Вы должны попробовать события уровня приложения QEvent::ApplicationActivate и QEvent::ApplicationDeactivate с фильтром событий, установленным на qApp.
Эти события запускаются при изменении фокуса приложения или сворачивании окна приложения.

MainWindow::MainWindow() {
  qApp->installEventFilter(this);
}

bool MainWindow::eventFilter(QObject *obj, QEvent *evt)
{
    if(obj==qApp && ( evt->type() == QEvent::ApplicationActivate
                      || evt->type() == QEvent::ApplicationDeactivate))
    {
        bool shouldHide = evt->type() == QEvent::ApplicationDeactivate;
        if (shouldHide) {
            m_splashWasVisible = m_btndlg && m_btndlg->isVisible();
            if(m_splashWasVisible) 
                m_btndlg->hide();
        } else {
            if(m_splashWasVisible) 
                m_btndlg->show();
        }    
    }
    return QMainWindow::eventFilter(obj, evt);
}

Кроме того, вы можете отобразить окно-заставку как часть главного окна поверх всех других виджетов, установив главное окно в качестве его родителя и используя QWidget::raise().

person alexisdm    schedule 22.03.2012
comment
Я исправил это. Проблема заключалась в том, что после того, как я скрыл это, я также сделал setFlags... и удивительно, когда был указан флаг Qt::SplashWindow, что-то внутри QT сломалось, так как он попытался установить что-то для родителя окна, которое было 0 в моем кейс. Возможно, это исправят в более поздних версиях. Однако спасибо за направление, которое вы мне подтолкнули. - person Ferenc Deak; 26.03.2012