优化线程通讯, mpd改为基于Gtk的信号槽机制通讯
parent
1b4834d022
commit
271a8838fb
24
main.py
24
main.py
|
@ -19,6 +19,7 @@ app_id = 'fun.wkit.sonist'
|
|||
home_dir = os.getenv('HOME')
|
||||
|
||||
|
||||
# 定义一个异步修饰器, 用于在子线程中运行一些会阻塞主线程的任务
|
||||
def run_async(func):
|
||||
def wrapper(*args, **kwargs):
|
||||
thread = threading.Thread(target=func, args=args, kwargs=kwargs)
|
||||
|
@ -27,7 +28,7 @@ def run_async(func):
|
|||
return thread
|
||||
return wrapper
|
||||
|
||||
|
||||
# 类型js的settimeout的修饰器
|
||||
def set_timeout(timeout = 0.5):
|
||||
def decorator(callback):
|
||||
def wrapper(*args):
|
||||
|
@ -39,6 +40,7 @@ def set_timeout(timeout = 0.5):
|
|||
return decorator
|
||||
|
||||
|
||||
|
||||
def get_music_dir():
|
||||
with open(f'{home_dir}/.mpd/mpd.conf', 'r') as f:
|
||||
data = f.read()
|
||||
|
@ -52,38 +54,38 @@ def get_music_dir():
|
|||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
__gsignals__ = {
|
||||
'playing': (GObject.SignalFlags.RUN_FIRST, None, (bool,)),
|
||||
'song_changed': (GObject.SignalFlags.RUN_FIRST, None, (bool,)),
|
||||
'state_changed': (GObject.SignalFlags.RUN_FIRST, None, (str,))
|
||||
}
|
||||
|
||||
|
||||
def __init__(self):
|
||||
Gtk.Application.__init__(self, application_id = app_id)
|
||||
|
||||
self.timer = None
|
||||
|
||||
self.mpd = MPDClient()
|
||||
|
||||
self.music_dir = get_music_dir()
|
||||
self.mpd = MPDClient()
|
||||
|
||||
self.connect('window-removed', self.on_window_removed)
|
||||
|
||||
self.mpd.connect()
|
||||
|
||||
|
||||
|
||||
@run_async
|
||||
def connect_mpd(self):
|
||||
|
||||
self.mpd.start()
|
||||
|
||||
def do_activate(self):
|
||||
print('hello mpc')
|
||||
self.set_app_menu(None)
|
||||
self.set_menubar(None)
|
||||
|
||||
|
||||
self.window = SonistWindow(self)
|
||||
self.about = AboutWindow()
|
||||
self.add_window(self.window)
|
||||
self.window.show_all()
|
||||
# self.about.show_all()
|
||||
|
||||
self.connect_mpd()
|
||||
|
||||
|
||||
def on_window_removed(self, app, win):
|
||||
if len(self.get_windows()) == 0:
|
||||
|
|
36
window.py
36
window.py
|
@ -1,11 +1,11 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import gi, sys, os, mutagen
|
||||
import gi, sys, os, mutagen, threading
|
||||
# from pprint import pprint as print
|
||||
|
||||
gi.require_version('Gtk', '3.0')
|
||||
|
||||
from gi.repository import Gtk, Gdk, GLib, GdkPixbuf
|
||||
from gi.repository import Gtk, Gdk, GLib, GdkPixbuf, GObject
|
||||
|
||||
from utils import blur_image, pic_to_pixbuf, base64_to_pixbuf
|
||||
|
||||
|
@ -18,7 +18,11 @@ from ui.timebar import Timebar
|
|||
from ui.option_menu import OptionMenu
|
||||
|
||||
|
||||
|
||||
# 定义一个修饰器, 用于将当前方法转到主线程中运行 (子线程中调用方法时)
|
||||
def idle(func):
|
||||
def wrapper(*args):
|
||||
GObject.idle_add(func, *args)
|
||||
return wrapper
|
||||
|
||||
|
||||
class SonistWindow(Gtk.Window):
|
||||
|
@ -34,12 +38,11 @@ class SonistWindow(Gtk.Window):
|
|||
|
||||
self.connect("destroy", self.quited)
|
||||
|
||||
self.mpd.bind('offline', lambda : self.reset_player())
|
||||
self.mpd.bind('online', lambda : self.sync_state(None, None, True))
|
||||
self.mpd.bind('state_changed', lambda stat: self.update_play_stat(stat == 'play'))
|
||||
self.mpd.bind('song_changed', lambda stat, song: self.sync_state(stat, song, False))
|
||||
self.mpd.bind('playing', lambda stat, song: self.update_playtime(stat))
|
||||
|
||||
self.mpd.connect('offline', lambda o: self.reset_player())
|
||||
self.mpd.connect('online', lambda o: self.sync_state(None, None, True))
|
||||
self.mpd.connect('state_changed', lambda o, stat: self.update_play_stat(stat == 'play'))
|
||||
self.mpd.connect('song_changed', lambda o, stat, song: self.sync_state(stat, song, False))
|
||||
self.mpd.connect('playing', lambda o, stat, song: self.update_playtime(stat))
|
||||
|
||||
self.set_name('SonistWindow')
|
||||
self.set_default_size(320, 384)
|
||||
|
@ -108,6 +111,9 @@ class SonistWindow(Gtk.Window):
|
|||
|
||||
self.add(layout)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def get_mpd_stat(self):
|
||||
try:
|
||||
|
@ -201,7 +207,7 @@ class SonistWindow(Gtk.Window):
|
|||
except:
|
||||
pass
|
||||
|
||||
|
||||
@idle
|
||||
def update_play_stat(self, played = True):
|
||||
if not self.mpd.connected:
|
||||
return
|
||||
|
@ -214,13 +220,16 @@ class SonistWindow(Gtk.Window):
|
|||
# 切换播放按钮状态
|
||||
self.ctrl_box.toggle_play_btn(played)
|
||||
|
||||
|
||||
@idle
|
||||
def update_playtime(self, stat = {}):
|
||||
times = stat['time'].split(':')
|
||||
self.timebar.update_time(int(times[0]), int(times[1]))
|
||||
|
||||
|
||||
@idle
|
||||
def sync_state(self, stat = None, song = None, first = False):
|
||||
self.ctrl_box.disabled = False
|
||||
print(threading.active_count())
|
||||
print(threading.current_thread())
|
||||
|
||||
self.stat = stat or self.get_mpd_stat()
|
||||
|
||||
|
@ -262,16 +271,19 @@ class SonistWindow(Gtk.Window):
|
|||
except:
|
||||
pass
|
||||
|
||||
@idle
|
||||
def reset_player(self):
|
||||
self.ctrl_box.disabled = True
|
||||
self.title_box.set_text('mpd is offline...')
|
||||
self.timebar.update_time()
|
||||
self.update_album('./usr/share/sonist/avatar.jpg')
|
||||
|
||||
@idle
|
||||
def update_album(self, filepath):
|
||||
self.set_background_image(filepath)
|
||||
self.album.reset(filepath).set_radius(64)
|
||||
|
||||
|
||||
def quited(self, win):
|
||||
self.app.remove_window(self)
|
||||
|
||||
|
|
Loading…
Reference in New Issue