关闭 PyGTK window,如果获得焦点,然后失去焦点
Closing a PyGTK window, if the focus is gain and, after, lost
我在 Python3 中有一个程序可以改变我系统的音量。我想要的行为是它像一个弹出窗口 window,它将在 window 之后自行销毁,首先获得焦点,然后失去焦点。
我的代码有两个问题。第一,失去焦点时它不会自行关闭,给我一个错误:
on_focus_out_event() takes 2 positional arguments, but 3 were given.
然而,即使解决了这个错误,它也无法实现我想要的行为。
这是我用 Python 编写的第一个程序,不幸的是,我需要这方面的密切帮助。如果有人能帮助我,我将不胜感激。
#!/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)
focus-out-event
需要三个参数。将 window
参数添加到第 41 行的 self, event
。
def on_focus_out_event(self, event, window):
self.destroy()
在 Alperen 的回答下,我能够制作一个可以静音和更改系统音量的应用程序。我的应用程序只会在比例已更改或按钮至少被切换一次并且之后 window 失去焦点时关闭。这不是我第一个想要的行为,但我认为现在实施得更好。
P.S.: 我不确定代码是否缩进正确。
#!/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)
volume = subprocess.Popen("pacmd dump-volumes | awk 'NR==1{print }' | sed 's/\%//'", shell=True, stdout=subprocess.PIPE)
volume_str = volume.stdout.read()
scale_float = Gtk.Scale.new_with_range(Gtk.Orientation.HORIZONTAL, 0.0, 153, 1.0)
scale_float.set_value(int(volume_str))
scale_float.set_draw_value(False)
scale_float.set_value_pos(Gtk.PositionType.LEFT)
scale_float.connect('value-changed', self.on_value_changed)
scale_float.show_all()
ismuted = subprocess.Popen("pacmd list-sinks | grep muted | sed -e 's/.*: //g'", shell=True, stdout=subprocess.PIPE)
if ismuted.stdout.read().decode() == b'yes\n'.decode():
image=Gtk.Image.new_from_icon_name('audio-volume-muted', 1)
else:
image=Gtk.Image.new_from_icon_name('audio-volume-high', 1)
button = Gtk.Button()
button.set_image(image)
button.connect("clicked", self.on_button_clicked )
button.show_all()
notebook = Gtk.Notebook()
notebook.append_page(scale_float, button)
notebook.set_tab_pos(Gtk.PositionType.RIGHT)
self.add(notebook)
self.show_all()
def on_value_changed(self, scale):
val = int(scale.get_value())
proc = subprocess.Popen('pactl set-sink-volume 0 ' + str(val) + '%', shell=True, stdout=subprocess.PIPE)
proc.wait()
self.connect('focus-out-event', self.on_focus_out_event)
def on_focus_out_event(self, widget, window):
self.destroy()
def on_button_clicked(self, button):
subprocess.Popen("pactl set-sink-mute 0 toggle", shell=True, stdout=subprocess.PIPE)
ismuted = subprocess.Popen("pacmd list-sinks | grep muted | sed -e 's/.*: //g'", shell=True, stdout=subprocess.PIPE)
if ismuted.stdout.read().decode() == b'yes\n'.decode():
image=Gtk.Image.new_from_icon_name('audio-volume-muted', 1)
else:
image=Gtk.Image.new_from_icon_name('audio-volume-high', 1)
button.set_image(image)
self.connect('focus-out-event', self.on_focus_out_event)
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)
我在 Python3 中有一个程序可以改变我系统的音量。我想要的行为是它像一个弹出窗口 window,它将在 window 之后自行销毁,首先获得焦点,然后失去焦点。
我的代码有两个问题。第一,失去焦点时它不会自行关闭,给我一个错误:
on_focus_out_event() takes 2 positional arguments, but 3 were given.
然而,即使解决了这个错误,它也无法实现我想要的行为。
这是我用 Python 编写的第一个程序,不幸的是,我需要这方面的密切帮助。如果有人能帮助我,我将不胜感激。
#!/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)
focus-out-event
需要三个参数。将 window
参数添加到第 41 行的 self, event
。
def on_focus_out_event(self, event, window):
self.destroy()
在 Alperen 的回答下,我能够制作一个可以静音和更改系统音量的应用程序。我的应用程序只会在比例已更改或按钮至少被切换一次并且之后 window 失去焦点时关闭。这不是我第一个想要的行为,但我认为现在实施得更好。
P.S.: 我不确定代码是否缩进正确。
#!/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)
volume = subprocess.Popen("pacmd dump-volumes | awk 'NR==1{print }' | sed 's/\%//'", shell=True, stdout=subprocess.PIPE)
volume_str = volume.stdout.read()
scale_float = Gtk.Scale.new_with_range(Gtk.Orientation.HORIZONTAL, 0.0, 153, 1.0)
scale_float.set_value(int(volume_str))
scale_float.set_draw_value(False)
scale_float.set_value_pos(Gtk.PositionType.LEFT)
scale_float.connect('value-changed', self.on_value_changed)
scale_float.show_all()
ismuted = subprocess.Popen("pacmd list-sinks | grep muted | sed -e 's/.*: //g'", shell=True, stdout=subprocess.PIPE)
if ismuted.stdout.read().decode() == b'yes\n'.decode():
image=Gtk.Image.new_from_icon_name('audio-volume-muted', 1)
else:
image=Gtk.Image.new_from_icon_name('audio-volume-high', 1)
button = Gtk.Button()
button.set_image(image)
button.connect("clicked", self.on_button_clicked )
button.show_all()
notebook = Gtk.Notebook()
notebook.append_page(scale_float, button)
notebook.set_tab_pos(Gtk.PositionType.RIGHT)
self.add(notebook)
self.show_all()
def on_value_changed(self, scale):
val = int(scale.get_value())
proc = subprocess.Popen('pactl set-sink-volume 0 ' + str(val) + '%', shell=True, stdout=subprocess.PIPE)
proc.wait()
self.connect('focus-out-event', self.on_focus_out_event)
def on_focus_out_event(self, widget, window):
self.destroy()
def on_button_clicked(self, button):
subprocess.Popen("pactl set-sink-mute 0 toggle", shell=True, stdout=subprocess.PIPE)
ismuted = subprocess.Popen("pacmd list-sinks | grep muted | sed -e 's/.*: //g'", shell=True, stdout=subprocess.PIPE)
if ismuted.stdout.read().decode() == b'yes\n'.decode():
image=Gtk.Image.new_from_icon_name('audio-volume-muted', 1)
else:
image=Gtk.Image.new_from_icon_name('audio-volume-high', 1)
button.set_image(image)
self.connect('focus-out-event', self.on_focus_out_event)
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)