1. 程式人生 > >Qt/PyQt的系統托盤圖示(SystemTrayIcon)實現

Qt/PyQt的系統托盤圖示(SystemTrayIcon)實現

估計這種小的知識會有幾篇文章,除了全域性快捷鍵部分外,其他的都比較簡單,都是我實現 中碰到的一些小問題,這裡順面整理一下。事實上,稍微懂一點的人,去看看one key code highlighter的原始碼都能明白了。這裡相當於將其詳細的剖析一下。。。。。。。另外,實現上用Python+PyQt,事實上,主要的部分是對Qt的一些類的使用,所以其實看懂了C++的Qt中使用上是一樣的。啥?你看不懂Python?好的,這就是我為什麼靠C++吃飯,卻學習JAVA,JavaScript,Lua,Python,Bash的一個原因,不然你看不懂別人在寫啥-_-!(當然,我基本上也就學到能看懂)
對於pyQt完全不懂的,這裡也不用看了,《 》,《 》可以看看,但是寫的有點亂,因為那時候我懂得也少(不代表現在就懂的多了)

SystemTrayIcon在官方的Demo中有一個示例,(那些示例有些可真酷啊!)位置在Desktop->System Tray中。該示例展示了大部分需要用到的內容。包括實現TrayIcon,顯示氣泡資訊,TrayIcon的選單等等。

建立系統系統托盤圖示(TrayIcon)

主要用到的類是QtGui.QSystemTrayIcon。
圖示用QtGui.QIcon類來表示,可以以檔名字串為建構函式的引數。如:
icon = QtGui.QIcon('jt.png ')
然後用QtGui.QSystemTrayIcon的 setIcon(icon) 去完成系統TrayIcon的建立。OK,已經完成80%了,圖示已經出來了。

氣泡資訊

再然後呢?希望有特定的氣泡資訊?
QtGui.QSystemTrayIcon的showMessage
可以完成。

選單

再然後呢?希望有選單?這個稍微複雜點,在Qt中,選單是一個一個的Action,如下建立Action:

        self.quitAction = QtGui.QAction("&Quit

", self,
                                        triggered=QtGui.qApp.quit)
        
        self.aboutAction = QtGui.QAction("&About ", self,
                                        triggered=self.about)
注意上述Action的triggerd引數,實際上是一個Callable的回撥函式,意思是點選此選單時進行的操作。
然後將Action新增進某個Menu
self.trayIconMenu = QtGui.QMenu(self)
self.trayIconMenu.addAction(self.aboutAction)
self.trayIconMenu.addAction(self.quitAction)
然後將Menu
關聯上TrayIcon
self.trayIcon.setContextMenu(self.trayIconMenu)

完成了。

CheckBox選單

我的需求更加複雜一點,希望有可以Check的選單,當然,這個需求已經超出SystemTrayIcon相關的需求了,與Qt中的選單有關。

將需要實現成Check選單的所有命令新增到一個Action組中,在Qt中稱為QActionGroup。


        self.synGroup = QtGui.QActionGroup(self)
        
        for  syn in  config.syntaxSupport:
            action = QtGui.QAction(syn, self, checkable=True,
                triggered=self.setSyn)
            self.synGroup.addAction(action)

需要注意的是,每個Action的checkable引數設為True,表示是CheckBox型別的選單。
通過某個Action的setChecked來選中,比如:

        actions = self.synGroup.actions()
        if  len(actions) != 0:
            actions[0].setChecked(True)

主要注意的是,在Qt中QActionGroup返回的是一個QList的列表,但是在PyQt已經將其轉換為Python中原生的list了,這樣更加符合Python的使用習慣,當然,呼叫方法的時候也需要注意一下了,介面可是不同的,感謝RiverBank(PyQt的創造維護公司)偉大的工作,對於可憐的RiverBank我其實還有話要說,以後再詳述吧。
具體哪個選單選項被Check了,通過
checkedAction = self.synGroup.checkedAction()
來查詢,返回的是被Check的Action,此時假如你是通過Action的字串來查詢的話,(比如我)那麼呼叫Action的text
函式獲取。

一切都結束了。。。。。。。需要注意幾個特別的地方:
1。官方的教程中,有
QtGui.QApplication.setQuitOnLastWindowClosed(False)
這樣一句,大概的意思是在應用程式所有視窗都關閉的時候不關閉應用程式,事實上,就我試驗,無論是設為True,還是False,都不管關。。。。。。原因不明。
2。在應用程式利用QtGui.qApp.quit關閉後,TrayIcon其實還不會自動消失,直到你的滑鼠移動到上面去後,才會消失,這是個問題,(如同你terminate一些帶TrayIcon的應用程式時出現的狀況),這種問題的解決我是通過在程式退出前將其setVisible(False)來完成的。

完整原始碼獲取說明

由於篇幅限制,本文一般僅貼出程式碼的主要關心的部分,程式碼帶工程(或者makefile)完整版(如果有的話)都能用Mercurial在Google Code中下載。文章以博文發表的日期分目錄存放,請直接使用Mercurial克隆下庫:

要是僅僅想瀏覽全部程式碼也可以直接到google code上去看,在下面的地址:

原創文章作者保留版權 轉載請註明原作者 並給出連結