Search code examples
notificationsgtkgtk3toastpygobject

Can anyone help on finding an tutorial or example code about gtk in-app notifications API reference


I've recently studied the gtk design patterns, and found the in-app notifications. There is an description on when to use it, but no reference to the gtk api.

I have searched for it, but found just the GNotification and GApplication.send_notification, but this sends the notification to the desktop environment.

Can anyone help on finding an tutorial or example code for doing an in-app notification?


Solution

  • The app-notification "widget" is a mix of widgets, a css class and behaviors.

    You should use a Gtk.Overlay in the window that you plan to use app-notifications then use a container (eg Gtk.Box) with the predefined app-notification style class. The notification container should be wrapped in a Gtk.Revealer to allow the reveal "slide" transition.

    Here is a glade ui file (app-notification.ui) with an example:

    <?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>
    

    The result in Glade:

    enter image description here

    And here is some python code that uses the previous glade file and gives some dynamic behavior to the notification so that you can see it in action by clicking the buttons. The glade file should be named app-notification.ui, otherwise change the code to reflect the given name:

    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()