通知气泡中消息溢出

通知气泡中消息溢出

我正在学习如何使用 gtk 通知,似乎通过通知气泡显示的任何输出都有最大溢出大小,大概是 10 行左右。因此,如果我想显示的消息超过这个大小,它就会被抑制。有没有办法强制显示整个消息而不会抑制任何内容?

顺便说一下,我正在使用 notifyOSD。

答案1

我之前在(现已删除)的问答中发布了这篇文章。也许对你有用。


允许(非常)长的消息的补丁

下面的“补丁”将允许您在桌面上接收通知:

如果通知很长,则不应这样:

在此处输入图片描述

你会看到这个:

在此处输入图片描述

期间消息的长度自动设置为文本的长度。

它能做什么

notify-osd通过( )发送的通知notify-send限制为大约 120 个字符。
该解决方案使用 来“监听”已发送的消息dbus-monitor。如果消息超过 120 个字符,它将接管这些消息并使用“其自己的”消息窗口来显示通知,如上所示。

脚本

  1. 该设置由两部分组成:“listen-”脚本,用于拦截通知:

    #!/bin/bash
    
    currdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
    
    dbus-monitor "interface='org.freedesktop.Notifications'" |\
     grep --line-buffered "string" |\
     grep --line-buffered -e method -e ":" -e '""' -e urgency -e notify -v |\
     grep --line-buffered '.*(?=string)|(?<=string).*' -oPi |\
     grep --line-buffered -v '^\s*$' |\
     xargs -I '{}' $currdir/message {}
    

    将脚本复制到一个空文件中并保存为catch_notifs.sh

  2. 创建替换通知的脚本:

    #!/usr/bin/env python3
    import subprocess
    import os
    import gi
    gi.require_version('Gtk', '3.0')
    from gi.repository import GObject, Gtk, Gdk, Pango
    from threading import Thread
    import time
    import sys
    
    text = sys.argv[1]
    length = len(text)
    showtime = length/20
    
    def get_screen():
        scr = [s.split("x") for s in subprocess.check_output([
            "xrandr"]).decode("utf-8").split() if "+0+0" in s][0]
        return int(scr[0]) -450
    
    class Splash(Gtk.Window):
    
        def __init__(self):
            Gtk.Window.__init__(self, title="splashtitle")
            maingrid = Gtk.Grid()
            self.add(maingrid)
            maingrid.set_border_width(20)
            label = Gtk.Label(text)
            label.set_line_wrap(True)
            label.set_max_width_chars(45)
            label.modify_font(Pango.FontDescription('Ubuntu 11'))
            maingrid.attach(label, 0, 0, 1, 1)
            self.stop = Thread(target=self.close_window)
            self.stop.start()
    
        def close_window(self):
            time.sleep(showtime)
            Gtk.main_quit()
    
    def splashwindow():
        window = Splash()
        window.set_decorated(False)
        window.set_resizable(False)
        window.override_background_color(Gtk.StateType.NORMAL, Gdk.RGBA(0,0,0,1))
        window.modify_fg(Gtk.StateFlags.NORMAL, Gdk.color_parse("white"))
        # window.set_opacity(0.8)
        window.move(get_screen(), 80)
        window.set_keep_above(True)
        window.show_all()
        window.set_default_size(200, 500)
        GObject.threads_init()
        Gtk.main()
    
    if len(text) > 120:
        subprocess.Popen(["pkill", "notify-osd"])
        splashwindow()
    

    将上述脚本复制到一个空文件中,保存为(完全一样!)message(无扩展名)并使其可执行

  3. 存储两个脚本在同一个目录中
  4. 通过以下命令(从终端窗口)测试运行脚本:

    /bin/bash /path/to/catch_notifs.sh
    

    (保持运行)

    您可以通过运行(在另一个终端)来测试设置:

    notify-send '<long_text>'
    
  5. 如果一切正常,请将其添加到启动应用程序:Dash > 启动应用程序 > 添加。添加命令:

    /bin/bash /path/to/catch_notifs.sh
    

它应该可以工作:)

答案2

正如我在评论中指出的那样,notify-osd它不太适合大量消息,人们应该更喜欢它zenity

简单的使用示例是zenity通过生成对话框subprocess.call([COMMAND,OPTIONS])

import subprocess 

text="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."
command=['zenity', '--info', '--text="' +text + '"', '--width=250', '--height=300' ]
subprocess.call(command)

非常简单的例子。对于需要检查退出状态的内容,例如问题,您可能想要使用try - except - else结构

import subprocess 

text='Do you want to use Zenity?'
command=['zenity', '--question', 
         '--text="' +text + '"',
         '--width=250', '--height=300' ]


try:
    stdout = subprocess.check_call(command)

except subprocess.CalledProcessError:
    pass # if return sttus is non-zero, do something here

else:
    # if exit status was 0 , we do something here
    print "Yes, I want to use Zenity too"

如果您想要更高级的东西,可能会考虑学习 PyQt 或 Gtk 等图形工具包。

相关内容