--- Title: pythonでfoobarのalternativeを作る 22 Author: yamasyuh68 Web: https://mimemo.io/m/1KpnX4yvR6GaEwQ --- ## Player 190531-0602 https://live.staticflickr.com/65535/47985537206_2be1771ebc_z.jpg - 音が出るようになった(・∀・)ノ - treeのインクリメンタルは一文字のアルファベットや数字は無視するようにしたので結構快適になってきた - 右下のリストをきちんと作った treeからのドラッグでリストに追加されます これって自分で実装しなくてもリストのドラッグの属性設定だけで出来ちゃうんだなあ、すごいわ (゚Д゚) - リストのダブルクリックで再生 treeとListって基本同じだ Qtのこのwidgetは使いづらいと思ってたけど慣れたら簡単でいいのかもしれない - toolbar を付けた、やっぱり無いと不便(¯―¯٥) 結構簡単だけどdesignerでは書けないのかな?? - タイマーを使う 再生中の経過時間の取得や再生状態の取得が必須になる リストの順次再生はこれから実装予定 python組み込みの`timer`だとうまくいかなかったのでQTで実装 - pickle を使ってtreeのmodelを保存したかったんだけどエラーで出来なかった ショック・・・(¯―¯٥) - タグのビューはvlcで取得してみた mutageの変わりにこれを使ったら速さはどうだろう? ``` import sqlite3 , re ,vlc ,time from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5.QtWidgets import QApplication,QWidget,QMainWindow ,QAction , QListView,QVBoxLayout from PyQt5.QtGui import QStandardItemModel , QStandardItem from PyQt5.QtCore import QTimer import ui class MainWindow(QMainWindow): def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.ui = ui.Ui_MainWindow() self.ui.setupUi(self) self.db= line='select artist ,album,title ,path from musics order by artist ,album,title' self.model=self.sqlexecute(line) self.ui.treeView.setModel(self.model) # tree self.model2 = QStandardItemModel() self.ui.listView.setModel(self.model2) # list_tag self.setaction() self.makenewtab('default') self.currentfile=r'(¯―¯٥)' self.p = vlc.MediaPlayer() self.timer = QtCore.QTimer(self) self.timer.setInterval(500) self.timer.timeout.connect(self.ShowInfo) def setaction(self): self.ui.actionBye.triggered.connect(self.actionbye) self.ui.actionchange.triggered.connect(self.actionchange) self.ui.actionclear.triggered.connect(self.actionclear) self.ui.actionreload.triggered.connect(self.actionreload) self.ui.actionplay.triggered.connect(self.actionplay) self.ui.actionpause.triggered.connect(self.actionpause) self.ui.actionstop.triggered.connect(self.actionstop) actionPlay = QAction('Play', self) actionPlay.triggered.connect(self.actionplay) actionPause = QAction('Pause', self) actionPause.triggered.connect(self.actionpause) actionStop = QAction('Stop', self) actionStop.triggered.connect(self.actionstop) actionBye = QAction('BYE', self) actionBye.triggered.connect(self.actionbye) self.ui.toolBar.addAction(actionPlay) self.ui.toolBar.addAction(actionPause) self.ui.toolBar.addAction(actionStop) self.ui.toolBar.addAction(actionBye) def makenewtab(self,name): obj = QtWidgets.QListView() self.ui.tabWidget.addTab(obj, name) self.ui.tabWidget.setCurrentWidget(obj) lyt = QVBoxLayout() lyt.setContentsMargins(0, 0, 0, 0) lyt.setSpacing(0) obj.setLayout(lyt) model = QStandardItemModel() obj.setModel(model) obj.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) obj.doubleClicked.connect(self.ListdoubleClicked) obj.setDragEnabled(True) obj.setDragDropMode(QtWidgets.QAbstractItemView.DragDrop) self.current=obj def ListdoubleClicked(self,e): # print(e.data()) # print(e.siblingAtColumn(1).data() ) self.actionplay(e.siblingAtColumn(1).data()) def actionplay(self,f): self.currentfile=f self.p.set_mrl(f) self.p.play() self.timer.start() def ShowInfo(self): if self.p.is_playing() : self.setWindowTitle(self.currentfile) self.ui.statusbar.showMessage(str(self.p.get_time())) else: self.timer.stop() # print('kita') def actionpause(self): self.p.pause() def actionstop(self): self.p.stop() self.timer.stop() def actionchange(self): model2 = QStandardItemModel() for i in range(3): parent1 = QStandardItem('Family {}. Some long status text for sp'.format(i)) model2.appendRow(parent1) for j in range(3): child1 = QStandardItem('Child {}'.format(i*3+j)) child2 = QStandardItem('row: {}, col: {}'.format(i, j+1)) child3 = QStandardItem('row: {}, col: {}'.format(i, j+2)) parent1.appendRow([child1, child2, child3]) self.ui.treeView.setModel(model2) def actionreload(self): pass def sqlexecute( self, line ): conn = sqlite3.connect( self.db ) c = conn.cursor() item=['×','×'] tree=[None,None,None,None] model = QStandardItemModel() for l in c.execute(line) : # print(l) if item[0] != l[0] : # 1 a-artist tree[1] = QStandardItem(l[0]) model.appendRow(tree[1]) item[0]=l[0] if item[1] != l[1] : # 1 date album tree[2] = QStandardItem( l[1] ) tree[1].appendRow(tree[2]) item[1]=l[1] tree[3]=QStandardItem(l[2]) , QStandardItem(l[3]) # tree[3].setData(l[3]) tree[2].appendRow(tree[3]) # l[3] path 入れてない c.close() conn.close() return model def actionbye(self): # with open( 'data.pickle', 'wb') as f : # pickle.dump( self.model ,f) quit() def actionclear(self): self.model.clear() def search(self,e): item=self.ui.lineEdit.text() temp=self.ui.treeView.model() if item=='' or (len(item)==1 and re.match('[a-zA-Z0-9_.,]',item) ) : # if item=='' : if temp == self.model : pass else: self.ui.treeView.setModel(self.model) del temp else : item="'%"+item+"%'" line='select artist ,album,title ,path from musics where \ artist like {} or path like {} or title like {}\ order by artist ,album,title'.format(item,item,item) self.ui.treeView.setModel(self.sqlexecute(line)) if temp != self.model: del temp def treeClicked(self,e): path=( e.siblingAtColumn(1).data() ) unko=QStandardItem('hoge') ins=vlc.Instance() media = ins.media_new(path) media.parse() self.model2.clear() self.model2.appendRow(QStandardItem(media.get_meta(vlc.Meta.Title))) self.model2.appendRow(QStandardItem(media.get_meta(vlc.Meta.Album))) self.model2.appendRow(QStandardItem(str(media.get_duration()/1000))) ins.release() if __name__ == '__main__': import sys app = QApplication(sys.argv) main_window = MainWindow() main_window.show() sys.exit(app.exec_()) ``` - 一応コード全部のせたけどさすがに見づらいな(¯―¯٥) # VLC module - pythonバインディングのインストはすぐだったけど、そもそも本体のバイナリが必要だった(winのdllね)。仕方ないので本体もインストしました。まあスグレモノのプレイヤーだからあっても良いんだけど。出来れば必要なdlllだけコピーすれば行けるようにして欲しいんだが・・ - 音を出すだけなら簡単なんだけど、しっかり使おうと思ったらそれなりに調べないと難しい(当然か(-_-)) サイトにはpyqt用のexampleなんてものも置いてあってかなり親切です どちらかというと動画用なのかもしれないけど・・・ 何とか上のコードまでは出来ましたが、もっと勉強が必要かな - 動画再生用のモジュールで音声だけって少し贅沢なのかも? 音声専用の軽いモジュールがあれば良いんだけどなあ Qtにはありそうだな・・・・