視窗最小化後隱藏
通常最小化的視窗會在工作列上顯示一個按鈕。當使用者按一下這個按鈕,視窗就還原了。這是一個被大多數案頭環境,比如Windows,KDE,GNOME所採用的普遍設計。不過,因為工作列通常只是案頭邊上一小行,容納不了很多按鈕,使用者通常希望把那些不常用的程式隱藏起來,只在通知欄顯示一個小表徵圖,要使用的時候再點擊那個小表徵圖恢複視窗。這種作法最典型的例子是QQ和Winamp。
原本以為這個功能是很容易的,今天試著做了一下,原來還有些小麻煩。最基本的思路是攔截視窗的最小化事件,通過閱讀Qt文檔,可以這麼做:
void MyWindow::changeEvent(QEvent* event)
{
if(event->type()==QEvent::WindowStateChange)
{
if(windowState() & Qt::WindowMinimized)
{
hide();
mSystemTrayIcon->show();
}
QMainWindow::changeEvent(event);
}
把這個代碼拿去試一下,發現不行,工作列的按鈕仍然還在,點擊還原後視窗一片空白。仔細想一下,估計是因為這個changeEvent()是在Qt處理最小化事件前調用的。我們把視窗隱藏了,但是Qt還以為視窗正要最小化。仍然運行一遍處理已最小化的視窗的代碼。所以出錯了。
解決的思路是先讓Qt處理完視窗最小化,等處理完之後再隱藏視窗。這樣的話,把hide()那一行改寫成:
QTimer::singleShot(0, this, SLOT(hide()));
這個是singleShot()的特殊用法,如果第一個參數,也就是等待時間為0,當Qt回到訊息迴圈的時候,通常就是當前處理的事件處理完之後就立即運行this->hide();
點擊通知欄表徵圖的處理代碼需要多一下setWindowState():
MyWindow::showMe()
{
show();
setWindowState(Qt::WindowNoState);
}