#python-3.x #gtk3 #pygtk
Вопрос:
У меня есть программа на Python3, которая может изменять громкость моей системы. Поведение, которое я хочу, чтобы оно было похоже на всплывающее окно, которое уничтожит себя после того, как окно сначала сфокусируется, а затем потеряет фокус.
В моем коде есть две проблемы. Во-первых, он не закрывается сам по себе, когда фокус теряется, что дает мне ошибку:
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)
Ответ №1:
focus-out-event
требуется три аргумента. Добавьте window
аргумент self, event
в строку 41.
def on_focus_out_event(self, event, window):
self.destroy()
Ответ №2:
С ответом Альперена я смог создать приложение, которое может отключать звук и изменять громкость моей системы. Мое приложение закроется только в том случае, если масштаб был изменен или если кнопка была переключена хотя бы один раз, и после этого окно теряет фокус. Это не мое первое желаемое поведение, но я думаю, что сейчас оно реализовано еще лучше.
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 $8}' | 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'yesn'.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'yesn'.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)