Как правильно реализовать функцию "свернуть до лотка" в Qt?

Как правильно реализовать функцию "свернуть до лотка" в Qt?

Я попробовал следующий код внутри QMainWindow::changeEvent(QEvent *e), но окно просто сводится к панели задач, а при восстановлении клиентская область становится пустой.

if (Preferences::instance().minimizeToTray())
{
    e->ignore();
    this->setVisible(false);
}

Попытка проигнорировать событие также не делает ничего.

Ответы

Ответ 1

По-видимому, требуется небольшая задержка для обработки других событий (возможно, кто-то выведет точную информацию?). Вот что я в итоге сделал, что прекрасно работает:

void MainWindow::changeEvent(QEvent* e)
{
    switch (e->type())
    {
        case QEvent::LanguageChange:
            this->ui->retranslateUi(this);
            break;
        case QEvent::WindowStateChange:
            {
                if (this->windowState() & Qt::WindowMinimized)
                {
                    if (Preferences::instance().minimizeToTray())
                    {
                        QTimer::singleShot(250, this, SLOT(hide()));
                    }
                }

                break;
            }
        default:
            break;
    }

    QMainWindow::changeEvent(e);
}

Ответ 2

В дополнение к тому, что сказал Джейк Петроулес, кажется, что просто:

QTimer::singleShot(0, this, SLOT(hide()));

. Из http://qt-project.org/doc/qt-4.8/qtimer.html#details:

В качестве специального случая a QTimer с таймаутом 0 будет отключен, как только будут обработаны все события в очереди событий оконной системы.

Таким образом, у вас нет проблемы с выбором соответствующего значения задержки...

Ответ 3

 void main_window::create_tray_icon()
 {
    m_tray_icon = new QSystemTrayIcon(QIcon(":/icon.png"), this);

    connect( m_tray_icon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(on_show_hide(QSystemTrayIcon::ActivationReason)) );

    QAction *quit_action = new QAction( "Exit", m_tray_icon );
    connect( quit_action, SIGNAL(triggered()), this, SLOT(on_exit()) );

    QAction *hide_action = new QAction( "Show/Hide", m_tray_icon );
    connect( hide_action, SIGNAL(triggered()), this, SLOT(on_show_hide()) );

    QMenu *tray_icon_menu = new QMenu;
    tray_icon_menu->addAction( hide_action );
    tray_icon_menu->addAction( quit_action );

    m_tray_icon->setContextMenu( tray_icon_menu );

    m_tray_icon->show();
  }

void main_window::on_show_hide( QSystemTrayIcon::ActivationReason reason )
{
    if( reason )
    {
        if( reason != QSystemTrayIcon::DoubleClick )
        return;
    }

    if( isVisible() )
    {
        hide();
    }
    else
    {
        show();
        raise();
        setFocus();
    }
}

Вот как я понимаю "свести к минимуму до лотка". Теперь вы можете свести к минимуму либо двойным щелчком по значку, либо щелчком правой кнопки мыши и выбором "Показать/Скрыть" в меню.