开发者

How do I properly implement a "minimize to tray" function in Qt?

开发者 https://www.devze.com 2023-01-09 07:57 出处:网络
How do I properly implement a \"minimize to tray\" f开发者_开发问答unction in Qt? I tried the following code inside QMainWindow::changeEvent(QEvent *e), but the window simply minimizes to the taskbar

How do I properly implement a "minimize to tray" f开发者_开发问答unction in Qt?

I tried the following code inside QMainWindow::changeEvent(QEvent *e), but the window simply minimizes to the taskbar and the client area appears blank white when restored.

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

Attempting to ignore the event doesn't seem to do anything, either.


Apparently a small delay is needed to process other events (perhaps someone will post the exact details?). Here's what I ended up doing, which works perfectly:

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);
}


In addition to what Jake Petroules said, it appears that simply doing:

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

is enough. From http://qt-project.org/doc/qt-4.8/qtimer.html#details :

As a special case, a QTimer with a timeout of 0 will time out as soon as all the events in the window system's event queue have been processed.

This way you don't have the problem of selecting an appropriate delay value...


 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();
    }
}

That's how I realize a "minimize to tray". You can now minimize either by double clicking on the icon, or by right-clicking and selecting "Show/Hide" in the menu.


I have found that the showMinimized() slot works without a QTimer delay, so you can use code like:

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

in your main() to show a main window and immediately iconize it, when desired.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号