Qt顯示Linux desktop natification氣泡提示框

来源:https://www.cnblogs.com/apocelipes/archive/2018/12/15/10124381.html
-Advertisement-
Play Games

在現代Linux桌面環境上我們時常可以看到類似的消息框: 這些消息框常用在如下場景: 即時聊天軟體的新消息 鬧鐘定時提示 電池電量提示 郵件消息 長耗時操作的完成提示 在freedesktop.org的規範中這種消息框被稱為 ,中文名我們形象得稱其為“氣泡框”。通過調用D BUS服務 提供的介面即可 ...


在現代Linux桌面環境上我們時常可以看到類似的消息框:

這些消息框常用在如下場景:

  • 即時聊天軟體的新消息
  • 鬧鐘定時提示
  • 電池電量提示
  • 郵件消息
  • 長耗時操作的完成提示

在freedesktop.org的規範中這種消息框被稱為Desktop Notification,中文名我們形象得稱其為“氣泡框”。通過調用D-BUS服務org.freedesktop.Notifications提供的介面即可顯示在桌面上。

所以我們先瞭解一下這個D-BUS服務。

org.freedesktop.Notifications概覽

一個氣泡框消息通常會包含如下的屬性:

名稱 說明
Application Name 標示發送消息的程式,最好使用程式全名
Replaces ID 可選的消息ID,伺服器通過id控制消息框的渲染,通常不用關註
Icon 顯示在氣泡框上的圖標
Summary 標題,只能顯示一行,叫title應該更合適
Body 消息體,支持部分HTML標簽;<b></b><i></i><u></u><a></a><img src=... alt=...>
Actions 顯示一些按鈕或者菜單(QAction),不過這一功能通常未被實現
Hints 為消息體提供的額外數據,比如顯示在屏幕的位置(x,y坐標)
Expiration Timeout 氣泡框顯示的時長,單位毫秒;指定為-1時行為取決於實現;為0時氣泡框將一直顯示在桌面上直到用戶點擊

其中Icon和Hints中的image_path必須為本地絕對路徑或者file://開頭的文件URL。另外使用桌面環境預定義圖標的名字也是可以的。

氣泡框還有三個緊急程度可供選擇:

名稱 說明
Low 0 預設值,可以設置如何顯示,應該設置一個合理的顯示時間以便氣泡框可以隱藏退出
Normal 1 同low
Critical 2 代表重要通知,不應該自動過期隱藏

所有的氣泡框消息請求都是非同步的,通常構造請求併發送後用戶就可以不再關心後續的信息,如果有特殊需要則可以自定義處理org.freedesktop.Notifications發送的信號。

得益於freedesktop.org的標準規範,包括KDE,GNOME,XFCE4在內的許多桌面環境都提供了對Desktop Notification的支持,雖然外觀上可能存在一些差異但是創建氣泡框的方法是一樣的。

不過不用擔心,我們不會直接去使用D-BUS,因為已經有簡化的現成方案可供選擇了。下麵就讓我們一起看看這些方案。

方案一:調用外部命令

可能你已經知道了,我要介紹的命令就是notify-send

notify-send幾乎被所有的桌面環境和發行版支持,它依賴於後面會介紹的libnotify和glib,如果你的系統上沒有安裝可以使用如下命令進行安裝:

debian/Ubuntu:

sudo apt install libnotify-bin

Arch Linux:

sudo pacman -S libnotify

安裝後可以用如下命令顯示氣泡框:

# notify-send title body [options]
notify-send test 'This is a desktop Notification test.' -t 10000

-t參數設置超時時間。效果如下:

具體的參數可以參考這裡:https://ss64.com/bash/notify-send.html

方案二:通過編程方式實現

在Qt代碼中調用外部命令就可以顯示氣泡框,然而這種方式不夠靈活,所以我們需要使用前面提到的libnotify在我們的代碼里生成並顯示氣泡框。

libnotify對各個語言都提供了binding,可以參考這裡
這裡我們選擇使用golang的binding:

package main
import ("github.com/mqu/go-notify")

func main() {
    notify.Init("Hello world")
    hello := notify.NotificationNew("Hello World!", "This is an example notification.","dialog-information")
    hello.SetTimeout(5000)
    hello.Show()
}

上面的代碼將會顯示一個可以在桌面停留5s的氣泡框:

不過如果每次都要使用一大串代碼才能顯示消息的話必然是低效的,而且需要換算時間至毫秒,所以我寫了一個幫助函數在notify.go:

// ShowNotification 顯示org.freedesktop.Notifications氣泡消息框
// duration == -1時使用預設delay
// duration == 0表示不設置超時,desktop notification將會一直顯示
func ShowNotification(title, text, image string, delay time.Duration) {
    var notifyDelay int32
    if delay == -1 {
        notifyDelay = duration2millisecond(defaultNotifyDelay)
    } else {
        notifyDelay = duration2millisecond(delay)
        // 不合法值(包括duration不足1ms),使用預設值進行替換
        if notifyDelay == -1 {
            notifyDelay = duration2millisecond(defaultNotifyDelay)
        }
    }

    libnotify.Init(applicationName)

    notify := libnotify.NotificationNew(title, text, image)
    if notify == nil {
        fmt.Fprintf(os.Stderr, "Unable to create a new notification\n")
        return
    }
    notify.SetTimeout(notifyDelay)

    notify.Show()
}

// duration2millisecond 將time.Duration轉換成millisecond
// duration不足1ms將返回-1
func duration2millisecond(duration time.Duration) int32 {
    res := int32(duration / time.Millisecond)
    if res < 0 {
        return -1
    }

    return res
}

首先將時間值轉換成毫秒數,如果太小或者不合法就使用預設的停留時間。applicationName是程式的完整名稱。
因為氣泡框消息是非同步的,所以在調用了Show()之後函數就會返回,後續操作xwindows都會幫我們處理,所以這個函數調用之後是立刻返回的,不會阻塞Qt的gui事件迴圈,可以放心的使用:

// download something success
ShowNotification("下載", "文件下載完成", "dialog-information", 5*time.Second)

這樣我們也可以輕鬆地在我們的Qt程式中使用氣泡消息框了。

參考:

https://developer.gnome.org/notification-spec/


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Python開髮菜鳥入坑 項目要求pdf轉成圖片,網上較多的方案對於windows極其不友好,wand,Pythonmagick(win下載地址:www.lfd.uci.edu/~gohlke/pythonlibs/#pythonmagick),imagemagick(win下載地址:www.ima ...
  • Inno Setup 系列之安裝、卸載前檢測進程運行情況並關閉相應進程 ...
  • 從頭開始學習OI之Tarjan. 今天重新學習了Tarjan演算法..來這裡寫一下學習筆記...但是我太菜了..還是講不好怎麼辦... ...
  • 給定一個包含 n 個整數的數組 nums,判斷 nums 中是否存在三個元素 a,b,c ,使得 a + b + c = 0 ?找出所有滿足條件且不重覆的三元組。 註意:答案中不可以包含重覆的三元組。 我們先對數組排序,得到如下圖的結果 我們要計算a+b+c=0,先對數組迴圈得到a,然後b就是a的索 ...
  • 題目內容: 這一周的編程題是需要你在課程所給的時鐘程式的基礎上修改而成。但是我們並不直接給你時鐘程式的代碼,請根據視頻自己輸入時鐘程式的Display和Clock類的代碼,然後來做這個題目。 我們需要給時鐘程式加上一個表示秒的Display,然後為Clock增加以下public的成員函數: publ ...
  • 一 在下麵兩種情況下使用靜態方法: 1.當一個方法不需要訪問對象轉態,其所需的參數讀書通過顯示參數提供的(例如 Math.pow). 2.當一個方法只需要訪問類靜態域(enployee.getNextld). 二 方法參數的使用情況 一個方法不能修改一個基本數據類型的參數(即數值型和布爾型). 一個 ...
  • 等值、大小比較 在python中, 只要兩個對象的類型相同,且它們是內置類型(字典除外),那麼這兩個對象就能進行比較 。關鍵詞:內置類型、同類型。所以,兩個對象如果類型不同,就沒法比較,比如數值類型的數值不能和字元串類型的數值或字母比較。 對於python中的等值、不等值、大小比較的規則為何如此,以 ...
  • 布爾類型 python中True表示真,False表示假,它們是布爾類型: 在python中,bool的True和False是數值1和0的字元串表示格式,實際上 bool類型是int類型的一個子類 。 因為True/False是數值1和0的另一種表示方式,它們可以直接參与數值運算。 True/Fal ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...