--- Title: pythonでfoobarのalternativeを作る 27 Author: yamasyuh68 Web: https://mimemo.io/m/Mzm71lmz1e4KLYj --- 190611 # Player 作り込み 連続演奏 リスト保存 - 連続演奏も実装、普通に使えるようになってきた https://live.staticflickr.com/65535/48042927111_690c97b8b2_z.jpg - スライダーは見せかけなり( ´∀`) ``` import sqlite3 , re ,vlc ,time ,os ,urllib.parse from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5.QtWidgets import QApplication,QWidget,QMainWindow , QAction , QListView,QVBoxLayout,QSlider,QLabel from PyQt5.QtGui import QStandardItemModel , QStandardItem ,QPixmap from PyQt5.QtCore import QTimer ,Qt import ui from sqlView_mylist import mylist ,taginfo 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() # tagview model self.ui.listView.setModel(self.model2) # list_tag self.current={'file':'' , 'dur':0 , 'list':None , 'row':0} self.setaction() self.makenewtab('default') self.p = vlc.MediaPlayer() self.timer = QtCore.QTimer(self) self.timer.setInterval(500) self.timer.timeout.connect(self.monitoring) self.taginfo=taginfo(self) self.autoplay=False def setaction(self): 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) actionsave = QAction('save', self) actionsave.triggered.connect(self.actionsave) actionset = QAction('set', self) actionset.triggered.connect(self.actionset) self.ui.toolBar.addAction(actionPlay) self.ui.toolBar.addAction(actionPause) self.ui.toolBar.addAction(actionStop) self.ui.toolBar.addAction(actionsave) self.ui.toolBar.addAction(actionset) self.ui.toolBar.addAction(actionBye) self.ui.toolBar.addSeparator() self.slider=QSlider(Qt.Horizontal) self.time=QLabel('0:0/0:0') self.ui.toolBar.addWidget(self.time) self.ui.toolBar.addWidget(self.slider) def makenewtab(self,name): self.current['list'] = mylist() self.ui.tabWidget.addTab(self.current['list'], name) self.ui.tabWidget.setCurrentWidget(self.current['list']) lyt = QVBoxLayout() lyt.setContentsMargins(0, 0, 0, 0) lyt.setSpacing(0) self.current['list'].setLayout(lyt) self.current['list'].doubleClicked.connect(self.ListdoubleClicked) def ListdoubleClicked(self,e): row=self.current['list'].selectionModel().currentIndex().row() fname=e.siblingAtColumn(2).data() if not fname : # title-row --> return return if self.p.is_playing() : self.removeplay() self.p.stop() else: self.timer.start() self.actionplay(fname,row) def actionplay(self,f,row): self.current['file']=f self.p.set_mrl(f) self.p.play() self.taginfo.show(f) self.current['list'].model().setItem (row,1, QStandardItem('▶')) self.current['list'].setCurrentIndex(self.current['list'].model().index(row,0)) self.setWindowTitle(f) def removeplay(self): delrow=self.current['list'].model().findItems('▶',Qt.MatchExactly,1)[0].row() self.current['list'].model().setItem(delrow,1,QStandardItem('')) return delrow def monitoring(self): if self.p.is_playing() : self.ui.statusbar.showMessage(str(self.p.get_time())) else: row=self.removeplay()+1 fname=self.current['list'].model().index(row,2).data() if not fname: # no path but album? row+=1 fname=self.current['list'].model().index(row,2).data() if not fname: # check again fname=self.current['list'].model().index(1,2).data() row=1 self.actionplay(fname,row) def actionpause(self): self.p.pause() def actionstop(self): self.p.stop() self.timer.stop() self.removeplay() self.autoplay=False def actionset(self): t=self.p.get_length() self.p.set_time(t-3000) # index = self.current['list'].model().index(3, 0); # self.current['list'].setCurrentIndex (index) # index=self.current['list'].selectedIndexes ()[0] # self.current['list'].setFirstColumnSpanned (index.row() ,index.parent() ,1) pass def actionsave(self): for i in range(self.current['list'].model().rowCount()): for p in range(self.current['list'].model().columnCount()): print(self.current['list'].model().index(i,p).data() + ' , ' , end ='') print('') # 改行する 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 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() ) if path: # dataがあればタイトル self.taginfo.show(path) if __name__ == '__main__': import sys app = QApplication(sys.argv) main_window = MainWindow() main_window.show() sys.exit(app.exec_()) ``` - 本体コードです、分割はしたけど長いな( ̄― ̄?) - 職場で構想練ってある程度のコード書いて、家に帰ってからそれを実行 結構エラー無くいけるので少し驚いている 目の前のVSCodeがあるとつい書いて試してエラーになる 逆に効率的かも - pauseきかない ┐('д')┌ ## 自動演奏の仕組み - 考え方はこんな感じ self.autoplay <=== 自動演奏フラグ、初期値は False タイマールーチンは monitoring 、initで作っておく def リストのDClick  行取得、ファイル取得、アルバム行なら何もしない  演奏中   removeplay , stop  NO 演奏中   タイマースタート、autoplay=True  .play def ストップ  removeplay、演奏stop、autoplay=False def monitoring()  isplaying   演奏時間の表示、スライダーの設定  isplaying=NO   次の曲を演奏    removeplay    次の行を取得してファイルを取得して play    (最後の曲なら冒頭に戻る、タイトル行に注意) def play(file,row)  ファイルをメディアにセットしてplay、▶を表示  演奏局を選択行にする def removeplay() : --> ▶ の表示を消すルーチン delrow=list.model().findItems('▶',Qt.MatchExactly,1)[0].row() list.model().setItem(delrow,1,QStandardItem('')) return delrow ## 保存・読込 ``` import sqlite3 , os from PyQt5.QtGui import QStandardItem class listsaver(): def save(model): fname=os.path.join(os.path.dirname(__file__) , 'listDB') conn = sqlite3.connect(fname) c = conn.cursor() c.execute('create table musiclists(name, title ,path)') for i in range(model.rowCount()): c.execute( "INSERT INTO musiclists (name, title ,path) VALUES (?,?,?)" , ( 'default' , model.index(i,0).data() , model.index(i,2).data())) conn.commit() conn.close() def load(model): fname=os.path.join(os.path.dirname(__file__) , 'listDB') conn = sqlite3.connect(fname) c = conn.cursor() for l in c.execute('select * from musiclists '): model.appendRow([QStandardItem(l[1]), QStandardItem(''), QStandardItem(l[2]) ]) c.close() conn.close() ``` - リストをsqlで保存、あっさりいけた( ´∀`) まだ複数のタブには対応していない すでにデータがある場合はエラーになる、どうしたらいいのかな?