完成设置界面的开发
							parent
							
								
									b2c7f5fc20
								
							
						
					
					
						commit
						4d2c6b37a1
					
				| 
						 | 
					@ -11,6 +11,8 @@ class AboutWindow(Gtk.AboutDialog):
 | 
				
			||||||
  def __init__(self):
 | 
					  def __init__(self):
 | 
				
			||||||
    super().__init__(self)
 | 
					    super().__init__(self)
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					    self.set_keep_above(True)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    self.set_program_name('Sonist Gtk')
 | 
					    self.set_program_name('Sonist Gtk')
 | 
				
			||||||
    self.set_logo_icon_name('google-chrome')
 | 
					    self.set_logo_icon_name('google-chrome')
 | 
				
			||||||
    self.set_license_type(Gtk.License.MIT_X11)
 | 
					    self.set_license_type(Gtk.License.MIT_X11)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										32
									
								
								main.py
								
								
								
								
							
							
						
						
									
										32
									
								
								main.py
								
								
								
								
							| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
#!/usr/bin/env python3
 | 
					#!/usr/bin/env python3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import gi, sys, os, threading, time, re
 | 
					import gi, sys, os, threading, time, re, json
 | 
				
			||||||
# import dbus
 | 
					# import dbus
 | 
				
			||||||
# import dbus.service, dbus.mainloop.glib
 | 
					# import dbus.service, dbus.mainloop.glib
 | 
				
			||||||
from pprint import pprint as print
 | 
					from pprint import pprint as print
 | 
				
			||||||
| 
						 | 
					@ -14,6 +14,7 @@ from utils import run_async
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from window import SonistWindow
 | 
					from window import SonistWindow
 | 
				
			||||||
from about_app import AboutWindow
 | 
					from about_app import AboutWindow
 | 
				
			||||||
 | 
					from preferences import PreferencesWindow
 | 
				
			||||||
from mpd import MPDClient
 | 
					from mpd import MPDClient
 | 
				
			||||||
 | 
					
 | 
				
			||||||
app_id = 'fun.wkit.sonist'
 | 
					app_id = 'fun.wkit.sonist'
 | 
				
			||||||
| 
						 | 
					@ -37,15 +38,35 @@ class Application(Gtk.Application):
 | 
				
			||||||
  def __init__(self):
 | 
					  def __init__(self):
 | 
				
			||||||
    Gtk.Application.__init__(self, application_id = app_id)
 | 
					    Gtk.Application.__init__(self, application_id = app_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    self.timer = None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    self.music_dir = get_music_dir()
 | 
					    self.music_dir = get_music_dir()
 | 
				
			||||||
    self.album_cache_dir = f"{home_dir}/.cache/sonist/album"
 | 
					    self.album_cache_dir = f"{home_dir}/.cache/sonist/album"
 | 
				
			||||||
    self.lyric_cache_dir = f"{home_dir}/.cache/sonist/lyric"
 | 
					    self.lyric_cache_dir = f"{home_dir}/.cache/sonist/lyric"
 | 
				
			||||||
    self.mpd = MPDClient()
 | 
					    self.config_dir = f"{home_dir}/.config/sonist"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    self.config_file = os.path.join(self.config_dir, 'config.json')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    os.makedirs(self.album_cache_dir, exist_ok = True)
 | 
					    os.makedirs(self.album_cache_dir, exist_ok = True)
 | 
				
			||||||
    os.makedirs(self.lyric_cache_dir, exist_ok = True)
 | 
					    os.makedirs(self.lyric_cache_dir, exist_ok = True)
 | 
				
			||||||
 | 
					    os.makedirs(self.config_dir, exist_ok = True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    self.config_data = {
 | 
				
			||||||
 | 
					      "host": '127.0.0.1',
 | 
				
			||||||
 | 
					      "port": 6600,
 | 
				
			||||||
 | 
					      "music_directory": self.music_dir,
 | 
				
			||||||
 | 
					      "auto_scan": True
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if os.path.isfile(self.config_file):
 | 
				
			||||||
 | 
					      with open(self.config_file, 'r') as f:
 | 
				
			||||||
 | 
					        buff = f.read()
 | 
				
			||||||
 | 
					        self.config_data = json.loads(buff)
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					      with open(self.config_file, 'w') as f:
 | 
				
			||||||
 | 
					        buff = json.dumps(self.config_data)
 | 
				
			||||||
 | 
					        f.write(buff)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    self.mpd = MPDClient(self.config_data['host'], self.config_data['port'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    self.connect('window-removed', self.on_window_removed)
 | 
					    self.connect('window-removed', self.on_window_removed)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -65,6 +86,7 @@ class Application(Gtk.Application):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    self.window = SonistWindow(self)
 | 
					    self.window = SonistWindow(self)
 | 
				
			||||||
    self.about = AboutWindow()
 | 
					    self.about = AboutWindow()
 | 
				
			||||||
 | 
					    self.preferences = PreferencesWindow(self, self.mpd)
 | 
				
			||||||
    self.add_window(self.window)
 | 
					    self.add_window(self.window)
 | 
				
			||||||
    self.window.show_all()
 | 
					    self.window.show_all()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -73,8 +95,6 @@ class Application(Gtk.Application):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def on_window_removed(self, app, win):
 | 
					  def on_window_removed(self, app, win):
 | 
				
			||||||
    if len(self.get_windows()) == 0:
 | 
					    if len(self.get_windows()) == 0:
 | 
				
			||||||
      if self.timer is not None:
 | 
					 | 
				
			||||||
        self.timer.cancel()
 | 
					 | 
				
			||||||
      self.mpd.destroy()
 | 
					      self.mpd.destroy()
 | 
				
			||||||
      print('朕要休息了~~~')
 | 
					      print('朕要休息了~~~')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,109 @@
 | 
				
			||||||
 | 
					#!/usr/bin/env python3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import gi, sys, os, mutagen, base64, json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					gi.require_version('Gtk', '3.0')
 | 
				
			||||||
 | 
					from gi.repository import Gtk, Gdk, GLib, GdkPixbuf, GObject
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class PreferencesWindow(Gtk.Dialog):
 | 
				
			||||||
 | 
					  def __init__(self, app, mpd):
 | 
				
			||||||
 | 
					    Gtk.Dialog.__init__(self, title = "Sonist 基础设置")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    self.set_default_size(464, 320)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    self.app = app
 | 
				
			||||||
 | 
					    self.mpd = mpd
 | 
				
			||||||
 | 
					    self.layout = self.get_content_area()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    config = app.config_data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    grid = Gtk.Grid(column_spacing = 8, row_spacing = 16)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    txt1 = Gtk.Label('MPD地址: ')
 | 
				
			||||||
 | 
					    txt2 = Gtk.Label('MPD端口: ')
 | 
				
			||||||
 | 
					    txt3 = Gtk.Label('音乐目录: ')
 | 
				
			||||||
 | 
					    txt4 = Gtk.Label('自动扫描: ')
 | 
				
			||||||
 | 
					    txt5 = Gtk.Label('   开启时, App启动时会自动扫描音乐变化')
 | 
				
			||||||
 | 
					    txt6 = Gtk.Label('当前歌曲数: ')
 | 
				
			||||||
 | 
					    txt7 = Gtk.Label('0 首')
 | 
				
			||||||
 | 
					    input1 = Gtk.Entry(placeholder_text = '默认 127.0.0.1')
 | 
				
			||||||
 | 
					    input2 = Gtk.SpinButton.new_with_range(min = 1024, max = 65535, step = 1)
 | 
				
			||||||
 | 
					    input3 = Gtk.Entry(placeholder_text = '默认读取 $HOME/.mpd/mpd.conf 中定义的目录')
 | 
				
			||||||
 | 
					    switch = Gtk.Switch()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    input1.set_size_request(312, -1)
 | 
				
			||||||
 | 
					    input1.set_text(config['host'])
 | 
				
			||||||
 | 
					    input2.set_value(config['port'])
 | 
				
			||||||
 | 
					    input3.set_text(config['music_directory'])
 | 
				
			||||||
 | 
					    switch.set_active(config['auto_scan'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    grid.attach(txt1, 0, 0, 1, 1)
 | 
				
			||||||
 | 
					    grid.attach(input1, 2, 0, 1, 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    grid.attach(txt2, 0, 1, 1, 1)
 | 
				
			||||||
 | 
					    grid.attach(input2, 2, 1, 1, 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    grid.attach(txt3, 0, 2, 1, 1)
 | 
				
			||||||
 | 
					    grid.attach(input3, 2, 2, 1, 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    grid.attach(txt4, 0, 3, 1, 1)
 | 
				
			||||||
 | 
					    box = Gtk.Box()
 | 
				
			||||||
 | 
					    box.add(switch)
 | 
				
			||||||
 | 
					    box.add(txt5)
 | 
				
			||||||
 | 
					    grid.attach(box, 2, 3, 1, 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    grid.attach(txt6, 0, 4, 1, 1)
 | 
				
			||||||
 | 
					    grid.attach(txt7, 2, 4, 1, 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    self.scan_result = txt7
 | 
				
			||||||
 | 
					    self.host_input = input1
 | 
				
			||||||
 | 
					    self.port_input = input2
 | 
				
			||||||
 | 
					    self.dir_input = input3
 | 
				
			||||||
 | 
					    self.switch_input = switch
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    self.layout.set_border_width(32)
 | 
				
			||||||
 | 
					    self.layout.add(grid)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    self.add_button('关闭', 0)
 | 
				
			||||||
 | 
					    self.add_button('保存', 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    self.set_keep_above(True)
 | 
				
			||||||
 | 
					    self.connect("response", self.on_button_clicked)
 | 
				
			||||||
 | 
					    mpd.connect('online', lambda o: self.get_mpd_music())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def get_mpd_music(self):
 | 
				
			||||||
 | 
					    res = self.mpd.stats()
 | 
				
			||||||
 | 
					    self.scan_result.set_text(f"{res.get('songs')} 首")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def show(self):
 | 
				
			||||||
 | 
					    if self.mpd.connected:
 | 
				
			||||||
 | 
					      self.get_mpd_music()
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					      self.scan_result.set_text("MPD 未运行...")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    self.show_all()
 | 
				
			||||||
 | 
					    self.run()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def on_button_clicked(self, dialog,  res):
 | 
				
			||||||
 | 
					    data = {}
 | 
				
			||||||
 | 
					    # 1 为保存按钮
 | 
				
			||||||
 | 
					    if res == 1:
 | 
				
			||||||
 | 
					      data['host'] = self.host_input.get_text()
 | 
				
			||||||
 | 
					      data['port'] = int(self.port_input.get_value())
 | 
				
			||||||
 | 
					      data['music_directory'] = self.dir_input.get_text()
 | 
				
			||||||
 | 
					      data['auto_scan'] = self.switch_input.get_active()
 | 
				
			||||||
 | 
					      self.app.config_data = data
 | 
				
			||||||
 | 
					      with open(self.app.config_file, 'w') as f:
 | 
				
			||||||
 | 
					        buff = json.dumps(data)
 | 
				
			||||||
 | 
					        f.write(buff)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    self.hide()
 | 
				
			||||||
| 
						 | 
					@ -49,7 +49,7 @@ class OptionMenu(Gtk.Menu):
 | 
				
			||||||
  def on_menu_select(self, item):
 | 
					  def on_menu_select(self, item):
 | 
				
			||||||
    match(item.name):
 | 
					    match(item.name):
 | 
				
			||||||
      case '首选项':
 | 
					      case '首选项':
 | 
				
			||||||
        pass
 | 
					        self.app.preferences.show()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      case '窗口置顶':
 | 
					      case '窗口置顶':
 | 
				
			||||||
        self.on_top = not self.on_top
 | 
					        self.on_top = not self.on_top
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue