Search code examples
python-3.xgtk3pygtk

Closing a PyGTK window, if the focus is gain and, after, lost


I have a program in Python3 that can change the volume of my system. The behavior I want is it to be like a popup window which will destroy itself after the window, first, get focus and, after, lost focus.

My code has two problems. The first, It does not close itself when the focus is lost, giving me an error:

on_focus_out_event() takes 2 positional arguments, but 3 were given.

And yet, even solving this error, it wouldn't accomplish my desired behavior.

This is my first program written in Python, unfortunately, I need a close help with this. If someone could help me, I would really appreciate it.

#!/usr/bin/python3
    
import sys
import subprocess
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
    
class AppWindow(Gtk.ApplicationWindow):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.set_border_width(0)
        self.set_size_request(500, -1)

        scale_float = Gtk.Scale.new_with_range(Gtk.Orientation.HORIZONTAL, 0.0, 153, 1.0)
        scale_float.set_value_pos(Gtk.PositionType.LEFT)
        scale_float.connect('value-changed', self.on_value_changed)
        scale_float.show_all()

        label_box = Gtk.Box()
        label_box.pack_start(
        Gtk.Image.new_from_icon_name('audio-volume-high', 1), False, False,5)
        label_box.pack_start(Gtk.Label(label=''), True, True, 0)
        label_box.show_all()

        notebook = Gtk.Notebook()
        notebook.append_page(scale_float, label_box)
        notebook.set_tab_pos(Gtk.PositionType.RIGHT)
            
        self.connect('focus-out-event', self.on_focus_out_event)
        self.add(notebook)
        self.show_all()


    def on_value_changed(self, scale_float):
        val = int(scale_float.get_value())
        proc = subprocess.Popen('pactl set-sink-volume 0 ' + str(val) + '%', shell=True, stdout=subprocess.PIPE)
        proc.wait()

    def on_focus_out_event(self, event):
        self.destroy()

class Application(Gtk.Application):
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, application_id="org.example.volume_control",**kwargs)
        self.window = None
    
    def do_activate(self):
        if not self.window:
            self.window = AppWindow(application=self,title="")
            self.window.show_all()
            self.window.present()

if __name__ == "__main__":
    app = Application()
    app.run(sys.argv)

Solution

  • focus-out-event requires three arguments. Add the window argument to self, event on line 41.

        def on_focus_out_event(self, event, window):
            self.destroy()
    

    enter image description here