我最近研究了gtk设计模式,并找到了。有关何时使用它的说明,但没有引用gtk api。
我搜索了它,但找到了in-app notifications和GNotification,但这会将通知发送到桌面环境。
任何人都可以帮助找到用于进行应用内通知的教程或示例代码吗?
答案 0 :(得分:6)
app-notification" widget"是小部件,css类和行为的混合。
您应该在计划使用应用通知的窗口中使用Gtk.Overlay,然后使用带有预定义app-notification
类的Gtk.Frame。 Gtk.Frame应该包含在Gtk.Revealer中以允许显示" slide"过渡。
这是一个glade ui文件(app-notification.ui),带有一个例子:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.0 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkWindow" id="window1">
<property name="can_focus">False</property>
<property name="default_width">440</property>
<property name="default_height">250</property>
<child>
<object class="GtkOverlay" id="overlay1">
<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="GtkOverlay" id="overlay2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">start</property>
<child>
<object class="GtkRevealer" id="revealer2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<child>
<object class="GtkFrame" id="frame2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkBox" id="box2">
<property name="visible">True</property>
<property name="can_focus">False</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>
</object>
</child>
<child type="label_item">
<placeholder/>
</child>
<style>
<class name="app-notification"/>
</style>
</object>
</child>
</object>
<packing>
<property name="pass_through">True</property>
<property name="index">-1</property>
</packing>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>
Glade的结果:
这里有一些python代码,它使用上一个glade文件,并为通知提供一些动态行为,以便您可以通过单击按钮查看它。 glade文件应命名为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()
答案 1 :(得分: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,否则请更新上述方法以使用其他计时器方法。