Как правильно реализовать функцию «свернуть в трей» в Qt? - PullRequest
16 голосов
/ 26 июля 2010

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

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

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

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

Ответы [ 4 ]

17 голосов
/ 26 июля 2010

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

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);
}
11 голосов
/ 23 мая 2011

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

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

достаточно. От http://qt -project.org / doc / qt-4.8 / qtimer.html # details :

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

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

7 голосов
/ 26 июля 2010
 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();
    }
}

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

0 голосов
/ 30 июля 2018

Я обнаружил, что слот showMinimized() работает без задержки QTimer, поэтому вы можете использовать такой код:

mw->show();
if ( qApp->arguments().contains( "--startHidden" ) )
  mw->showMinimized();

в вашем main(), чтобы отобразить главное окно и сразу сделать его иконку, когда это необходимо.

...