任何人都可以帮忙找到有关 gtk 应用内通知 API 参考的教程或示例代码吗

问题描述 投票:0回答:2

我最近研究了gtk设计模式,发现了应用内通知。有关于何时使用它的描述,但没有参考 gtk api。

我搜索过它,但只找到了GNotificationGApplication.send_notification,但这会将通知发送到桌面环境。

任何人都可以帮助找到用于执行应用内通知的教程或示例代码吗?

notifications gtk gtk3 toast pygobject
2个回答
9
投票

应用程序通知“小部件”是小部件、CSS 类和行为的组合。

您应该在计划使用应用程序通知的窗口中使用 Gtk.Overlay,然后使用具有预定义

app-notification
样式类的容器(例如 Gtk.Box)。通知容器应包装在 Gtk.Revealer 中,以允许显示“幻灯片”转换。

这是一个有示例的 Glade ui 文件 (app-notification.ui):

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface>
  <requires lib="gtk+" version="3.20"/>
  <object class="GtkWindow" id="window1">
    <property name="can_focus">False</property>
    <property name="default_width">640</property>
    <property name="default_height">480</property>
    <child>
      <placeholder/>
    </child>
    <child>
      <object class="GtkOverlay" id="overlay">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <child>
          <object class="GtkBox" id="box1">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="orientation">vertical</property>
            <child>
              <object class="GtkLabel" id="label1">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="label" translatable="yes">APP-NOTIFICATION EXAMPLE</property>
              </object>
              <packing>
                <property name="expand">True</property>
                <property name="fill">True</property>
                <property name="position">0</property>
              </packing>
            </child>
            <child>
              <object class="GtkButton" id="button1">
                <property name="label" translatable="yes">show app-notification</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
              </object>
              <packing>
                <property name="expand">False</property>
                <property name="fill">True</property>
                <property name="position">1</property>
              </packing>
            </child>
          </object>
          <packing>
            <property name="index">-1</property>
          </packing>
        </child>
        <child type="overlay">
          <object class="GtkRevealer" id="revealer2">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="halign">center</property>
            <property name="valign">start</property>
            <child>
              <object class="GtkBox" id="box2">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="valign">start</property>
                <property name="spacing">20</property>
                <child>
                  <object class="GtkLabel" id="label2">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="label" translatable="yes">This is an app-notification. Click the button to dismiss</property>
                  </object>
                  <packing>
                    <property name="expand">False</property>
                    <property name="fill">True</property>
                    <property name="position">0</property>
                  </packing>
                </child>
                <child>
                  <object class="GtkButton" id="button2">
                    <property name="visible">True</property>
                    <property name="can_focus">True</property>
                    <property name="receives_default">True</property>
                    <property name="relief">none</property>
                    <child>
                      <object class="GtkImage" id="image2">
                        <property name="visible">True</property>
                        <property name="can_focus">False</property>
                        <property name="icon_name">window-close-symbolic</property>
                      </object>
                    </child>
                    <style>
                      <class name="image-button"/>
                    </style>
                  </object>
                  <packing>
                    <property name="expand">False</property>
                    <property name="fill">True</property>
                    <property name="position">1</property>
                  </packing>
                </child>
                <style>
                  <class name="app-notification"/>
                </style>
              </object>
            </child>
          </object>
        </child>
      </object>
    </child>
  </object>
</interface>

Glade的结果:

enter image description here

这里有一些 python 代码,它使用之前的空地文件并为通知提供一些动态行为,以便您可以通过单击按钮来查看它的运行情况。林间空地文件应命名为 app-notification.ui,否则更改代码以反映给定名称:

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk

def onButtonShow(self):
    revealer.set_reveal_child(True)

def onButtonClose(self):
    revealer.set_reveal_child(False)

builder = Gtk.Builder()
builder.add_from_file("app-notification.ui")

window = builder.get_object("window1")

buttonShow = builder.get_object("button1")
buttonClose = builder.get_object ("button2")
revealer = builder.get_object("revealer2") 

buttonShow.connect ("clicked", onButtonShow)
buttonClose.connect ("clicked", onButtonClose)
window.connect ("destroy", Gtk.main_quit)
window.show_all()

Gtk.main()

2
投票

如果您更喜欢在不使用 Glade 的情况下创建此内容,则可以使用类似的内容(基于之前的答案):

假设您当前的代码具有类似以下内容:

window = Gtk.ApplicationWindow(application=self)
window.add(main_widget)

然后你可以将代码更改为如下所示:

window = Gtk.ApplicationWindow(application=self)
overlay = Gtk.Overlay()
window.add(overlay)
overlay.add(main_widget)
self._notify_timeout = None

# Notification overlay widget
self._revealer = Gtk.Revealer(valign=Gtk.Align.START, halign=Gtk.Align.CENTER)
box = Gtk.Box(orientation="horizontal", spacing=18)
box.get_style_context().add_class("app-notification")
self._notify_label = Gtk.Label(wrap=True)
box.pack_start(self._notify_label, expand=False, fill=True, padding=18)
button = Gtk.Button.new_from_icon_name("window-close-symbolic", Gtk.IconSize.BUTTON)
button.set_relief(Gtk.ReliefStyle.NONE)
button.set_receives_default(True)
button.connect("clicked", functools.partial(self._revealer.set_reveal_child, False))
box.pack_start(button, expand=False, fill=True, padding=18)
self._revealer.add(box)
overlay.add_overlay(self._revealer)

然后要显示通知,您可以添加如下方法:

def notify(self, message, timeout=5):
    if self._notify_timeout is not None:
        self._notify_timeout.cancel()

    self._notify_label.set_text(message)
    self._revealer.set_reveal_child(True)

    if timeout > 0:
        self._notify_timeout = asyncio.get_event_loop().call_later(
            timeout, functools.partial(self._revealer.set_reveal_child, False))

除了现有答案提供的内容之外,这还添加了超时功能,以便在几秒钟后自动删除通知。该代码假设您正在使用 asyncio,如果没有,则更新上述方法以使用另一个计时器方法。

© www.soinside.com 2019 - 2024. All rights reserved.