#!/usr/bin/python3 # coding: utf-8 from tkinter import * from tkinterdnd2 import * import os import sys import pyboard import serial.tools.list_ports from tkinter import messagebox ##### グローバル変数 ##### gport = None ##### イベントハンドラ ##### # リストボックスにドロップ def listbox_drop(event): files = listbox.tk.splitlist(event.data) for f in files: if os.path.exists(f): print('Dropped file: "%s"' % f) if os.path.isfile(f): putfile(f) filelist() else: messagebox.showwarning('Warning', 'フォルダは転送できません') else: print('Not dropping file "%s": file does not exist.' % f) def input_key(ev): # print(ev) if ev.keysym == 'F5': filelist() elif ev.keysym == 'Delete': selected = listbox.curselection() for i in selected: src = listbox.get(i) call_pybfunc('fs_rm', src) print('Deleted %s' % src) if len(selected): filelist() def on_closing(errmsg=''): if errmsg: messagebox.showerror('Error', errmsg) root.destroy() sys.exit(0) ##### pyboard関数 ##### def connect(): global gport try: pyb = pyboard.Pyboard(gport) pyb.enter_raw_repl() return pyb except: on_closing('デバイスに接続できません') def disconnect(pyb): try: pyb.exit_raw_repl() pyb.close() except: on_closing('切断に失敗しました') # コマンド実行 def exec_command(cmd): pyb = connect() try: retval = pyb.exec_(cmd) except: on_closing('コマンド実行時にエラーが発生しました') disconnect(pyb) return retval.decode('utf-8') # pyboard.py の関数をコール def call_pybfunc(funcname, *args): pyb = connect() if funcname=='fs_put': pyb.fs_put(args[0], args[1]) elif funcname=='fs_rm': pyb.fs_rm(args[0]) disconnect(pyb) def initialize(): global gport for p in sorted(serial.tools.list_ports.comports()): if p.hwid.startswith('USB'): gport = p.device set_title(gport) filelist() break else: on_closing('デバイスがみつかりません') def list_clear(): listbox.delete(0, END) def filelist(): list_clear() files = ls() for f in files: listbox.insert(END, f) def ls(src='/'): cmd = ( "import uos\nfor f in uos.listdir(%s):\n" " print(f)" % (("'%s'" % src) if src else "") ) retval = exec_command(cmd) return retval.splitlines() def putfile(src): dest = os.path.basename(src) call_pybfunc('fs_put', src, dest) def set_title(title): root.title('PyBfm - ' + title) ##### メイン ##### # メインウィンドウの生成 root = TkinterDnD.Tk() root.protocol("WM_DELETE_WINDOW", on_closing) root.title('PyBfm') root.geometry('400x300') # root.config(bg='#cccccc') # Frameウィジェットの生成 frame = Frame(root) # Listboxウィジェットの生成 listbox = Listbox(frame, selectmode=EXTENDED) listbox.drop_target_register(DND_FILES) listbox.dnd_bind('<>', listbox_drop) listbox.bind("", input_key) # スクロールバーの生成 scroll = Scrollbar(frame, orient=VERTICAL) listbox.configure(yscrollcommand=scroll.set) scroll.config(command=listbox.yview) # ウィジェットの配置 frame.pack(expand=True,fill=BOTH) listbox.pack(expand=True,fill=BOTH, side=LEFT) scroll.pack(side=RIGHT, fill=Y) initialize() root.mainloop()