#!/usr/bin/env python #-*- coding: UTF-8 -*- # Filename: mainGuiQt4.py # Author: Xu Jia (Sanfanling) E-mail:xujia19@sohu.com # Lisence: GPL-2.0 import chardet import embedLrc from PyQt4.QtGui import * from PyQt4.QtCore import * import lrcParser,readConfig,s2t from chooseItemQt4 import chooseItem from lrcEditorQt4 import lrcEditorQt4 from helpBrowserQt4 import helpWindow from ttpChooseGuiQt4 import ttpChooseGui from otherSettingQt4 import otherSettingQt4 from hasRelationDialogQt4 import hasRelationDialog from hasNoRelationDialogQt4 import hasNoRelationDialog import sys,commands,glob,re,os,ConfigParser,random,pickle # modular engine design from engines import * class netThread(QThread): ''' This class provide a network function for lrcShow-II, normally it connect to the search engine and analysis if the lrc we needed exists ''' def __init__(self,receiver,artist,title,locale,proxy,engine): QThread.__init__(self) self.receiver=receiver self.artist=artist self.title=title self.locale=locale self.proxy=proxy self.engine=engine def run(self): exec 'p=%s.%s(self.proxy,self.locale)' %(self.engine,self.engine) originalLrc,timeOut=p.request(self.artist,self.title) if(originalLrc is None): self.sleep(1) ev=netEvent(None,timeOut,p.netEncoder) QApplication.postEvent(self.receiver,ev) else: if(len(originalLrc)==1): originalLrc,timeOut=p.downIt(originalLrc[0][2]) self.sleep(1) ev=netEvent(originalLrc,timeOut,p.netEncoder) QApplication.postEvent(self.receiver,ev) else: self.sleep(1) ev=userChooseEvent(originalLrc,self.engine) QApplication.postEvent(self.receiver,ev) class downAfterChoose(QThread):# modular engine design needed def __init__(self,receiver,url,proxy,engine): QThread.__init__(self) self.receiver=receiver self.url=url self.proxy=proxy self.engine=engine def run(self): exec 'p=%s.%s(self.proxy)' %(self.engine,self.engine) originalLrc,timeOut=p.downIt(self.url) ev=netEvent(originalLrc,timeOut,p.netEncoder) QApplication.postEvent(self.receiver,ev) class myThread(QThread): ''' This thread class provides the function to waiting for Amarok's signal, and when lrcShow-II first run, it would to decide the Amarok's status ''' def __init__(self,receiver,app): QThread.__init__(self) self.receiver=receiver self.app=app def run(self): status=commands.getoutput('dcop amarok player status') if(status=='2'):#playing amarokStatus='playing' elif(status=='0'):#stop amarokStatus='stop' else:#pause amarokStatus='pause' amarokSignal='startup' ev=myEvent(amarokSignal,amarokStatus) self.app.postEvent(self.receiver,ev) while True: try: signal=sys.stdin.readline().strip() if(signal=='engineStateChange: paused'): amarokSignal='engineStateChange' amarokStatus='pause' ev=myEvent(amarokSignal,amarokStatus) self.app.postEvent(self.receiver,ev) elif(signal=='engineStateChange: playing'): amarokSignal='engineStateChange' amarokStatus='playing' self.sleep(1)#for a xine engine's bug ev=myEvent(amarokSignal,amarokStatus) self.app.postEvent(self.receiver,ev) elif(signal=='engineStateChange: empty'): amarokSignal='engineStateChange' amarokStatus='stop' ev=myEvent(amarokSignal,amarokStatus) self.app.postEvent(self.receiver,ev) elif(re.search('configure',signal)): ev=configEvent() self.app.postEvent(self.receiver,ev) except: pass ############ all of the Events below are sent by threads and received by main GUI process' customEvent class myEvent(QEvent): def __init__(self,amarokSignal,amarokStatus): QEvent.__init__(self,QEvent.Type(QEvent.User+1)) self.amarokSignal=amarokSignal self.amarokStatus=amarokStatus class netEvent(QEvent): def __init__(self,originalLrc,timeOut,netEncoder): QEvent.__init__(self,QEvent.Type(QEvent.User+2)) self.originalLrc=originalLrc self.timeOut=timeOut self.netEncoder=netEncoder class userChooseEvent(QEvent): def __init__(self,alist,engine): QEvent.__init__(self,QEvent.Type(QEvent.User+3)) self.alist=alist self.engine=engine class configEvent(QEvent): def __init__(self): QEvent.__init__(self,QEvent.Type(QEvent.User+4)) ############ main GUI process ########### class mainBox(QTextBrowser): def __init__(self,*args): apply(QTextBrowser.__init__,(self,) + args) #self.setWindowOpacity(0.5) self.setAlignment(Qt.AlignCenter) self.setLineWrapMode(QTextEdit.NoWrap) self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.winFlags=self.windowFlags() self.showMode='normal' p=readConfig.readConfig('lrcShow-II.conf') try:# app is developing, the newest config file would be changed, if config file is changed and user's is still old, an error would occur, then need to update (tmpPath,self.ifDownload,self.lineNum,bc,fc,hc,self.fontType,self.fontSize,self.proxy,self.encoderToWrite,self.searchEngine,self.saveLrcPath,self.noLrc,self.includeCancel,self.autoInsertAmarok,self.titleBarInfo,self.completeTag,self.filterLyrics,self.nullLine,self.filterRule,self.filterCap,self.asTrackName,self.minWidth,self.horizontal,self.fontWeight,self.fontItalic,self.saveToMediaPath,self.searchMediaPath,self.useUslt,lastPos,self.lrcTagType,self.lastShowMode,self.lastIsTop,self.rememberShowMode,fullscreen,osd,normal,insert,cancel,editor,save,delay,advance,fastbar)=p.parse() self.horizontalChange=self.horizontal except: QMessageBox.information(self,_(u'配置文件错误'),_(u'可能配置文件已经过时\nlrcShow-II将尝试为您自动更新配置文件,并保留原有设置\n请再次启动脚本\n如再次出现该对话框或出现Amarok弹出信息,请删除配置文件')) import updateConfig p=updateConfig.updateConfig('4') p.update() sys.exit() self.shortCut_fullscreen=QKeySequence.fromString(fullscreen) self.shortCut_osd=QKeySequence.fromString(osd) self.shortCut_normal=QKeySequence.fromString(normal) self.shortCut_insert=QKeySequence.fromString(insert) self.shortCut_cancel=QKeySequence.fromString(cancel) self.shortCut_editor=QKeySequence.fromString(editor) self.shortCut_save=QKeySequence.fromString(save) self.shortCut_delay=QKeySequence.fromString(delay) self.shortCut_advance=QKeySequence.fromString(advance) self.shortCut_fastbar=QKeySequence.fromString(fastbar) if(self.proxy=='no'): self.proxy=None else: self.proxy={'http':self.proxy} self.initMenu() if(self.ifDownload=='yes'): self.downloadMenu_yesAction.setChecked(True) else: self.downloadMenu_noAction.setChecked(True) self.downloadMenu_thisAction.setEnabled(False) self.initSettingMenuBar() a=bc.split(',') b=fc.split(',') c=hc.split(',') self.backGroundColor=QColor(int(a[0]),int(a[1]),int(a[2])) self.foreGroundColor=QColor(int(b[0]),int(b[1]),int(b[2])) self.highLightColor=QColor(int(c[0]),int(c[1]),int(c[2])) self.setAutoFillBackground(True)# is it necessary? tell me! self.initColor(self.backGroundColor,self.foreGroundColor,self.highLightColor) self.setMinimumHeight(200) self.setMinimumWidth(self.minWidth) px,py=lastPos.split(',') self.move(int(px),int(py)) if(self.fontItalic=='yes'):# Shit! if some variables get the bool value from readConfig module derectly, it would be better self.setFont(QFont(self.fontType,self.fontSize,self.fontWeight,True)) else: self.setFont(QFont(self.fontType,self.fontSize,self.fontWeight,False)) self.setWindowIcon(QIcon('../scripts/lrcShow-II/icon/logo.png')) self.mytimer=QTimer() self.mytimer.setSingleShot(True) self.checktimer=QTimer() self.checktimer.setSingleShot(False) self.hideMouseTimer=QTimer()# for auto hiding cursor in fullscreen display mode self.locale=sys.getfilesystemencoding()# detecting locale self.path=tmpPath.split(',') self.path=map(lambda x:unicode(x,'utf8').encode(self.locale),self.path)[0:-1] self.saveLrcPath=unicode(self.saveLrcPath,'utf8').encode(self.locale) mydb=open('lrcShow-II.db','r')# get the strategy data from the database u=pickle.Unpickler(mydb) self.myData=u.load() mydb.close() self.topIsChecked=False if(self.rememberShowMode=='yes'): if(self.lastShowMode=='osd'): self.displayMenu_osdAction_() #elif(self.lastShowMode=='fullscreen'): # self.displayMenu_fullscreenAction_() if(self.lastIsTop=='yes'): self.displayMenu_topAction.setChecked(True) self.displayMenu_topAction_(True) self.encoder=self.encoderToWrite self.fileName=None self.originalLrc=None self.extPath=None self.usltLrc=None self.connect(self.hideMouseTimer,SIGNAL("timeout()"),self.checkHideMouse) self.connect(self.mytimer,SIGNAL("timeout()"),self.scrollContent) self.connect(self.checktimer,SIGNAL("timeout()"),self.checkTime) self.connect(self.lrcAdjustMenu_delayAction,SIGNAL("triggered()"),self.seekSlow) self.connect(self.lrcAdjustMenu_advancedAction,SIGNAL("triggered()"),self.seekFast) self.connect(self.lrcAdjustMenu_saveToFileAction,SIGNAL("triggered()"),self.saveToFile) self.connect(self.amarokControlMenu_playorpauseAction,SIGNAL("triggered()"),self.amarokControlMenu_playorpause) self.connect(self.amarokControlMenu_stopAction,SIGNAL("triggered()"),self.amarokControlMenu_stop) self.connect(self.amarokControlMenu_prevAction,SIGNAL("triggered()"),self.amarokControlMenu_prev) self.connect(self.amarokControlMenu_nextAction,SIGNAL("triggered()"),self.amarokControlMenu_next) self.connect(self.colorMenu_backAction,SIGNAL("triggered()"),self.colorMenu_back) self.connect(self.colorMenu_foreAction,SIGNAL("triggered()"),self.colorMenu_fore) self.connect(self.colorMenu_lightAction,SIGNAL("triggered()"),self.colorMenu_light) self.connect(self.colorMenu_defaultAction,SIGNAL("triggered()"),self.colorMenu_default) self.connect(self.setFontAction,SIGNAL("triggered()"),self.setFontAction_) self.connect(self.setLineAction,SIGNAL("triggered()"),self.setLineAction_) self.connect(self.downloadMenu_yesAction,SIGNAL("triggered()"),self.downloadMenu_yesAction_) self.connect(self.downloadMenu_noAction,SIGNAL("triggered()"),self.downloadMenu_noAction_) self.connect(self.downloadMenu_thisAction,SIGNAL("triggered()"),self.downloadMenu_thisAction_) self.connect(self.displayMenu_normalAction,SIGNAL("triggered()"),self.displayMenu_normalAction_) self.connect(self.displayMenu_fullscreenAction,SIGNAL("triggered()"),self.displayMenu_fullscreenAction_) self.connect(self.displayMenu_osdAction,SIGNAL("triggered()"),self.displayMenu_osdAction_) self.connect(self.displayMenu_topAction,SIGNAL("triggered(bool)"),self.displayMenu_topAction_) self.connect(self.openLrcEditorAction,SIGNAL("triggered()"),self.openLrcEditorAction_) self.connect(self.setSearchEngineAction,SIGNAL("triggered()"),self.setSearchEngineAction_) self.connect(self.otherFunctionsMenu_searchAction,SIGNAL("triggered()"),self.otherFunctionsMenu_searchAction_) self.connect(self.otherFunctionsMenu_reloadAction,SIGNAL("triggered()"),self.otherFunctionsMenu_reloadAction_) self.connect(self.otherFunctionsMenu_cancelAction,SIGNAL("triggered()"),self.otherFunctionsMenu_cancelAction_) self.connect(self.otherFunctionsMenu_insertAction,SIGNAL("triggered()"),self.otherFunctionsMenu_insertAction_) self.connect(self.otherFunctionsMenu_otherSetting,SIGNAL("triggered()"),self.otherFunctionsMenu_otherSetting_) self.connect(self.otherFunctionsMenu_readUsltAction,SIGNAL("triggered()"),self.otherFunctionsMenu_readUsltAction_) self.connect(self.otherFunctionsMenu_insertUsltAction,SIGNAL("triggered()"),self.otherFunctionsMenu_insertUsltAction_) self.connect(self.otherFunctionsMenu_deleteUsltAction,SIGNAL("triggered()"),self.otherFunctionsMenu_deleteUsltAction_) self.connect(self.otherFunctionsMenu_deleteAllUsltAction,SIGNAL("triggered()"),self.otherFunctionsMenu_deleteAllUsltAction_) self.connect(self.setStrategyAction,SIGNAL("triggered()"),self.setStrategyAction_) self.connect(self.viewHelpAction,SIGNAL("triggered()"),self.viewHelpAction_) self.connect(self.aboutAction,SIGNAL("triggered()"),self.aboutAction_) self.connect(self.aboutQtAction,SIGNAL("triggered()"),self.aboutQtAction_) self.connect(self.closeAction,SIGNAL("triggered()"),SLOT("close()")) def customEvent(self,ev): if(ev.type()==QEvent.User+1): # for detecting Amarok's status when app starts up and listening the signal from Amarok self.amarokSignal=ev.amarokSignal self.amarokStatus=ev.amarokStatus if(self.checktimer.isActive()): self.checktimer.stop() if(self.mytimer.isActive()): self.mytimer.stop() try: self.downAfterChoose.terminate() except: pass try: self.downloadThread.terminate() except: pass try:# if some dialogs exist when changes the track, they need to be shut down, the same as below, for example, the strategy dialog has the information just belongs to current track, it shouldn't be shown when different track starts self.chooseItermDialog1.done(-1) except: pass try: self.chooseItermDialog2.done(-1) except: pass try: self.relationDialog.done(-1) except: pass if(self.amarokStatus=='playing'): self.initTime() self.checktimer.setInterval(2500) self.checktimer.start() else: self.checktimer.stop() self.initTime() if(self.amarokStatus=='pause' and self.amarokSignal=='engineStateChange'):# pause self.amarokControlMenu_playorpauseAction.setText(_(u'播放')) self.amarokControlMenu_playorpauseAction.setIcon(QIcon('../scripts/lrcShow-II/icon/amarok_play.png')) if(self.amarokStatus=='playing' or (self.amarokStatus=='pause' and self.amarokSignal=='startup')): self.title=commands.getoutput('dcop amarok player title') self.artist=commands.getoutput('dcop amarok player artist') self.media=commands.getoutput('dcop amarok player path') self.extInfo=os.path.splitext(os.path.basename(self.media))[0] self.extPath=os.path.dirname(self.media) if(self.asTrackName=='yes'): self.nameForSave=self.extInfo+'.lrc' else: self.nameForSave='%s - %s.lrc' %(self.artist,self.title) self.fileName=None self.originalLrc=None self.usltLrc=None self.downloadMenu_thisAction.setEnabled(False) if(self.titleBarInfo=='yes' and (self.artist<>'' or self.title<>'')): self.setWindowTitle('%s - %s' %(unicode(self.artist,self.locale),unicode(self.title,self.locale))) else: self.setWindowTitle(_(u'lrcShow-II')) if(self.amarokStatus=='pause' and self.amarokSignal=='startup'): #pause self.amarokControlMenu_playorpauseAction.setText(_(u'播放')) self.amarokControlMenu_playorpauseAction.setIcon(QIcon('../scripts/lrcShow-II/icon/amarok_play.png')) else: self.amarokControlMenu_playorpauseAction.setText(_(u'暂停')) self.amarokControlMenu_playorpauseAction.setIcon(QIcon('../scripts/lrcShow-II/icon/amarok_pause.png')) self.amarokControlMenu_stopAction.setEnabled(True) self.otherFunctionsMenu_searchAction.setEnabled(True) self.setStrategyAction.setEnabled(True) self.otherFunctionsMenu_reloadAction.setEnabled(True) self.otherFunctionsMenu_readUsltAction.setEnabled(True) self.otherFunctionsMenu_deleteUsltAction.setEnabled(True) self.otherFunctionsMenu_deleteAllUsltAction.setEnabled(True) if(self.title=='' and self.artist==''): self.showInfo('

'+_(u'没有有效的标签信息')+'

') else: if(self.completeTag=='no'): self.checkData() else: if(self.title<>'' and self.artist<>''): self.checkData() else: self.showInfo('

'+_(u'欢迎使用lrcShow-II')+'

') if(self.amarokStatus=='stop'): self.fileName=None self.originalLrc=None self.usltLrc=None self.extPath=None if(self.titleBarInfo=='yes'): self.setWindowTitle(_(u'lrcShow-II')) else: self.setWindowTitle(_(u'lrcShow-II')) self.amarokControlMenu_playorpauseAction.setText(_(u'播放')) self.amarokControlMenu_playorpauseAction.setIcon(QIcon('../scripts/lrcShow-II/icon/amarok_play.png')) self.amarokControlMenu_stopAction.setEnabled(False) self.otherFunctionsMenu_searchAction.setEnabled(False) self.setStrategyAction.setEnabled(False) self.otherFunctionsMenu_reloadAction.setEnabled(False) self.otherFunctionsMenu_readUsltAction.setEnabled(False) self.otherFunctionsMenu_deleteUsltAction.setEnabled(False) self.otherFunctionsMenu_deleteAllUsltAction.setEnabled(False) self.showInfo('

'+_(u'欢迎使用lrcShow-II')+'

',True) elif(ev.type()==QEvent.User+2):# for receiving the lrc from net self.originalLrc=ev.originalLrc t=ev.timeOut if(self.originalLrc and not ev.netEncoder): self.netEncoder=chardet.detect(self.originalLrc)['encoding'] if(self.netEncoder=='GB2312'): self.netEncoder='gb18030' else: self.netEncoder=ev.netEncoder if(self.originalLrc): self.initEvent(self.originalLrc,True) else: if(not t): self.showInfo('

'+_(u'没有找到匹配的歌词')+'

') else: self.showInfo('

'+_(u'网络连接超时')+'

') if(ev.type()==QEvent.User+3):# when searched more than one lrc from net, especially use the ttplayer engine lrcList=ev.alist engineReturn=ev.engine self.chooseItermDialog1=ttpChooseGui(self) for j in lrcList: self.chooseItermDialog1.listBox.insertItem(lrcList.index(j),j[0].decode('utf8')+' - '+j[1].decode('utf8')) self.chooseItermDialog1.listBox.setCurrentRow(0) result1=self.chooseItermDialog1.exec_() if(result1==QDialog.Accepted): k=self.chooseItermDialog1.listBox.currentRow() url=lrcList[k][2] self.downAfterChoose=downAfterChoose(self,url,self.proxy,engineReturn) self.downAfterChoose.start() elif(result1==QDialog.Rejected): self.showInfo('

'+_(u'没有找到匹配的歌词')+'

') if(ev.type()==QEvent.User+4):# receive the signal of switching pyqt version when user clicks the configure button of Amarok script manager a=QMessageBox.question(self,_(u'询问'),_(u'是否切换至PyQT3版本?'),QMessageBox.Yes,QMessageBox.No) if(a==QMessageBox.Yes): try: from qt import QString except ImportError: QMessageBox.critical(self,_(u'错误'),_(u'没有找到PyQT3,切换不成功!')) except RuntimeError: p=ConfigParser.ConfigParser() p.read('lrcShow-II.conf') p.set('version','pyqt','3') p.write(open('lrcShow-II.conf', 'w')) QMessageBox.information(self,_(u'成功'),_(u'切换成功,重启脚本后生效!')) def showInfo(self,lf,ok=False):# to show the necessary info in window, no lrc, Amarok stops, searching and so on self.mainContents=lf self.initMainEvent(True) self.otherFunctionsMenu_cancelAction.setEnabled(False) self.otherFunctionsMenu_insertAction.setEnabled(False) self.lrcAdjustMenu_delayAction.setEnabled(False) self.lrcAdjustMenu_advancedAction.setEnabled(False) self.lrcAdjustMenu_saveToFileAction.setEnabled(False) self.otherFunctionsMenu_insertUsltAction.setEnabled(False) if(not ok): if(self.noLrc=='normal'): pass elif(self.noLrc=='hide'): self.hide() elif(self.noLrc=='mini'): self.showMinimized() def initEvent(self,lf,ask=False): # new lrc found, necessary init process if(self.noLrc=='hide' and self.isHidden()): if(self.showMode=='fullscreen'): self.show() self.showFullScreen() else: self.show() if(self.noLrc=='mini' and self.isMinimized()): if(self.showMode=='fullscreen'): self.showFullScreen() else: self.showNormal() self.seekTime=0 self.totalSeekTime=0 self.otherFunctionsMenu_cancelAction.setEnabled(True) self.otherFunctionsMenu_insertAction.setEnabled(True) self.lrcAdjustMenu_delayAction.setEnabled(True) self.lrcAdjustMenu_advancedAction.setEnabled(True) self.lrcAdjustMenu_saveToFileAction.setEnabled(False) self.otherFunctionsMenu_insertUsltAction.setEnabled(True) self.openLrcEditorAction.setEnabled(True) if(self.ifDownload=='yes' and ask): try: unicode(lf,self.netEncoder).encode(self.encoderToWrite) except UnicodeEncodeError: QMessageBox.critical(self,_(u'编码错误'),_(u'在将搜索到的歌词(%s)编码为您预设的保存编码(%s)时发生错误,此次下载被忽略!\n这一般是由于搜索到的歌词中含有无法编码的字符造成的。\n如果多次出现本对话框,强烈建议您关闭自动下载功能,另外也可以设置保存编码为gb18030或者utf8以避免这个问题。') %(self.netEncoder,self.encoderToWrite)) else: if(self.saveToMediaPath=='yes' and self.extPath): pathTmp=self.extPath else: pathTmp=self.saveLrcPath try: file=open(os.path.join(pathTmp,self.nameForSave),'w') except: pass else: file.write(unicode(lf,self.netEncoder).encode(self.encoderToWrite)) file.close() self.originalLrc=None self.fileName=os.path.join(pathTmp,self.nameForSave) if(self.ifDownload=='no' and ask): self.downloadMenu_thisAction.setEnabled(True) if(ask): a=unicode(lf,str(self.netEncoder),'ignore') p=lrcParser.lrc(a) if(self.lineNum==1 and self.horizontal=='yes'): self.tag,self.mainContents=p.format(self.filterRule,self.filterLyrics,self.nullLine,self.filterCap,True) else: self.tag,self.mainContents=p.format(self.filterRule,self.filterLyrics,self.nullLine,self.filterCap) self.initMainEvent() self.goToCurrentPara() else: self.encoder=chardet.detect(lf)['encoding'] if(self.encoder=='GB2312'): self.encoder='gb18030' try: a=unicode(lf,self.encoder) except UnicodeDecodeError: self.showInfo('

'+_(u'读取本地歌词文件时出现编码错误')+'

') self.openLrcEditorAction.setEnabled(False) else: p=lrcParser.lrc(a) if(self.lineNum==1 and self.horizontal=='yes'): self.tag,self.mainContents=p.format(self.filterRule,self.filterLyrics,self.nullLine,self.filterCap,True) else: self.tag,self.mainContents=p.format(self.filterRule,self.filterLyrics,self.nullLine,self.filterCap) self.initMainEvent() self.goToCurrentPara() if(self.autoInsertAmarok=='yes' and commands.getoutput('dcop amarok player lyrics')==''): self.otherFunctionsMenu_insertAction_() os.system('dcop amarok contextbrowser showLyrics') def initMainEvent(self,noLrcInfo=False): if(self.mytimer.isActive()): self.mytimer.stop() try: self.killTimer(self.timerId) except: pass if(self.lineNum==1 and self.horizontal=='yes'): if(self.showMode<>'osd'): self.displayMenu_osdAction_() self.displayMenu_normalAction.setEnabled(False) if(self.lineNum==1 and self.horizontal=='yes' and not noLrcInfo): fontInfoClass=QFontMetrics(self.font()) spacelength=fontInfoClass.width(u' ') spaceNum=(self.width()/2)/spacelength t=self.mainContents.strip().split(u'!@#$') self.fragmentLength=map(lambda x:fontInfoClass.width(x),t) t=map(lambda x: u'    %s    ' %x,t[1:]) self.lrcFile=u' '*spaceNum for jj in t: self.lrcFile+=jj self.lrcFile=self.lrcFile+u' '*spaceNum self.setHtml(self.lrcFile) self.fixLength=8*spacelength else: j='

 

'*((self.lineNum-1)/2) self.lrcFile=j+self.mainContents+j+'

 

' self.setText(self.lrcFile) self.moveCursor(QTextCursor.Start) self.margin=QFontMetrics(self.font()).height()+12 self.setFixedHeight(self.margin*self.lineNum) def goToCurrentPara(self):# to center and highlight the current line currentTime=int(commands.getoutput('dcop amarok player trackCurrentTimeMs')) try: p=-1 while True: p+=1 if(self.tag[p]>=currentTime): break except AttributeError: pass except: if(self.lineNum==1 and self.horizontal=='yes'): all=0 for i in range(len(self.tag)): all+=self.fragmentLength[i] self.hPos=((len(self.tag))*2-1)*self.fixLength/2+all+self.fragmentLength[len(self.tag)]/2 self.horizontalScrollBar().setValue(self.hPos) else: for i in range(len(self.tag)+(self.lineNum-1)/2-1): self.moveCursor(QTextCursor.Down) self.highLight() self.hPos=self.margin*len(self.tag) self.verticalScrollBar().setValue(self.hPos) else: if(self.lineNum==1 and self.horizontal=='yes'): all=0 for i in range(p): all+=self.fragmentLength[i] self.hPos=(p*2-1)*self.fixLength/2+all+self.fragmentLength[p]/2 self.horizontalScrollBar().setValue(self.hPos) self.num=p if(self.amarokStatus=='pause'): pass else: self.mytimer.start(self.tag[p]-currentTime) else: for i in range(p+(self.lineNum-1)/2-1): self.moveCursor(QTextCursor.Down) self.num=p if(self.amarokStatus=='pause'): pass else: self.mytimer.start(self.tag[p]-currentTime) try: self.hPos=self.margin*(self.num-1) self.verticalScrollBar().setValue(self.hPos) if(self.lineNum<>1): self.highLight() except: pass def highLight(self): self.moveCursor(QTextCursor.StartOfLine) self.moveCursor(QTextCursor.NextBlock,QTextCursor.KeepAnchor) def downLoad(self): txt=_(u'正在从')+self.searchEngine+_(u'歌词服务器搜索...') self.showInfo('

'+txt+'

',True) self.downloadThread=netThread(self,self.artist,self.title,self.locale,self.proxy,self.searchEngine) self.downloadThread.start() def checkData(self):# special function to check if the current track has strategy data=self.myData.get('%s||%s' %(self.artist,self.title),False) if(data<>'FLAG.SKIP_ALL' and data<>'FLAG.SKIP_SEARCHLOCAL' and data<>'FLAG.SKIP_SEARCHENGINE' and data and os.path.exists(data)): self.fileName=data file=open(self.fileName) lf=file.read() file.close() self.initEvent(lf) elif(data<>'FLAG.SKIP_ALL' and data<>'FLAG.SKIP_SEARCHLOCAL' and data<>'FLAG.SKIP_SEARCHENGINE' and data and not os.path.exists(data)): del self.myData['%s||%s' %(self.artist,self.title)] mydb=open('lrcShow-II.db','w') pickler=pickle.Pickler(mydb,True) pickler.dump(self.myData) mydb.close() self.searchLocalLrc() elif(data=='FLAG.SKIP_SEARCHLOCAL'): self.downLoad() elif(data=='FLAG.SKIP_SEARCHENGINE'): self.searchLocalLrc(False) elif(data=='FLAG.SKIP_ALL'): self.showInfo('

'+_(u'欢迎使用lrcShow-II')+'

') else: if(self.useUslt=='yes'): p=embedLrc.embedLrc(self.media) lrc=p.detectLrc() if(lrc<>None): self.usltLrc=True self.initEvent(lrc) else: self.searchLocalLrc() else: self.searchLocalLrc() def searchLocalLrc(self,flag=True):# just search local if(len(self.path)<>0 or (len(self.path)==0 and self.searchMediaPath=='yes')): searchTmp=self.path[:] if(self.searchMediaPath=='yes'): searchTmp.append(self.extPath) k=[] for tmp in searchTmp: for lrcfile in glob.glob(os.path.join(tmp,'*.lrc')): if(self.title.lower() in os.path.basename(lrcfile).lower() and self.artist.lower() in os.path.basename(lrcfile).lower() and self.asTrackName=='no'): if(lrcfile not in k): k.append(lrcfile) if(self.extInfo==os.path.splitext(os.path.basename(lrcfile))[0] and self.asTrackName=='yes'): if(lrcfile not in k): k.append(lrcfile) if(len(k)==0): if(flag==True): self.downLoad() else: self.showInfo('

'+_(u'欢迎使用lrcShow-II')+'

') elif(len(k)==1): self.fileName=k[0] file=open(self.fileName) lf=file.read() file.close() self.initEvent(lf) else: self.showInfo('

'+_(u'欢迎使用lrcShow-II')+'

',True) self.chooseItermDialog2=chooseItem(self) for i in k: self.chooseItermDialog2.listBox.insertItem(k.index(i),unicode(i,self.locale)) self.chooseItermDialog2.listBox.setCurrentRow(0) result2=self.chooseItermDialog2.exec_() if(result2==QDialog.Accepted): self.fileName=k[self.chooseItermDialog2.listBox.currentRow()] if(self.chooseItermDialog2.checkBox.isChecked()): self.myData['%s||%s' %(self.artist,self.title)]=self.fileName mydb=open('lrcShow-II.db','w') pickler=pickle.Pickler(mydb,True) pickler.dump(self.myData) mydb.close() file=open(self.fileName) lf=file.read() file.close() self.initEvent(lf) elif(result2==QDialog.Rejected): if(self.chooseItermDialog2.checkBox.isChecked()): self.myData['%s||%s' %(self.artist,self.title)]='FLAG.SKIP_SEARCHLOCAL' mydb=open('lrcShow-II.db','w') pickler=pickle.Pickler(mydb,True) pickler.dump(self.myData) mydb.close() if(flag==True): self.downLoad() else: self.showInfo('

'+_(u'欢迎使用lrcShow-II')+'

') else: pass else: if(flag==True): self.downLoad() else: self.showInfo('

'+_(u'欢迎使用lrcShow-II')+'

') def scrollContent(self):# to scoll the lrc self.num+=1 if(self.num<>len(self.tag)): if(self.lineNum==1 and self.horizontal=='yes'): self.margin=self.fixLength+self.fragmentLength[self.num-1]/2+self.fragmentLength[self.num]/2 if(self.tag[self.num]-self.tag[self.num-1]-self.seekTime<600): self.hPos+=self.margin self.horizontalScrollBar().setValue(self.hPos) else: self.terminal=self.hPos self.terminal=self.terminal+self.margin/8 self.verticalScrollBar().setValue(self.terminal) self.timerId=self.startTimer(70) else: if(self.tag[self.num]-self.tag[self.num-1]-self.seekTime<600): self.hPos=self.hPos+self.margin self.verticalScrollBar().setValue(self.hPos) if(self.lineNum<>1): self.highLight() else: self.terminal=self.hPos self.terminal=self.terminal+self.margin/5 self.verticalScrollBar().setValue(self.terminal) self.timerId=self.startTimer(80) self.mytimer.start(self.tag[self.num]-self.tag[self.num-1]-self.seekTime) if(self.seekTime<>0): self.seekTime=0 else: if(self.lineNum==1 and self.horizontal=='yes'): self.terminal=self.hPos self.terminal=self.terminal+(self.fragmentLength[-2]/2+self.fragmentLength[-1]/2+self.fixLength)/8 self.horizontalScrollBar().setValue(self.terminal) self.timerId=self.startTimer(70) else: self.terminal=self.hPos self.terminal=self.terminal+self.margin/5 self.verticalScrollBar().setValue(self.terminal) self.timerId=self.startTimer(80) def timerEvent(self,ev):# use this method, just to void "lrc scolling" looks like "lrc jumping" if(ev.timerId()==self.timerId): if(self.lineNum==1 and self.horizontal=='yes'): self.terminal=self.terminal+self.margin/8 if(self.terminal1): self.highLight() def initTime(self): time=commands.getoutput("dcop amarok player trackCurrentTimeMs") self.expectedTime = int(time) + 2500 def checkTime(self): #print("checking time") time=commands.getoutput("dcop amarok player trackCurrentTimeMs") title=commands.getoutput('dcop amarok player title') if((abs(int(time)-self.expectedTime) > 200) and title==self.title and (self.originalLrc or self.fileName or self.usltLrc)): if(self.mytimer.isActive()): self.mytimer.stop() try: self.killTimer(self.timerId) except: pass self.moveCursor(QTextCursor.Start) self.goToCurrentPara() self.expectedTime = int(time) + 2500 ########## block:def lrcAdjustMenu's function ########## def seekSlow(self): # adjust function for delay if(self.fileName): self.lrcAdjustMenu_saveToFileAction.setEnabled(True) self.seekTime=self.seekTime-200 self.totalSeekTime=self.totalSeekTime-200 def seekFast(self): # as above, but opposite if(self.fileName): self.lrcAdjustMenu_saveToFileAction.setEnabled(True) self.seekTime=self.seekTime+200 self.totalSeekTime=self.totalSeekTime+200 def saveToFile(self):# save the offset into file file=open(self.fileName) content=unicode(file.read(),self.encoder).encode('utf8') file.close() offsetList=re.findall('\[offset:.*\]',content) if(len(offsetList)<>0): try: offsetOld=int(offsetList[0][8:-1]) except: offsetOld=0 offsetNew=offsetOld+self.totalSeekTime offsetLine='[offset:%s]' %str(offsetNew) content=re.sub('\[offset:.*\]',offsetLine,content) else: offsetLine='[offset:%s]\n' %str(self.totalSeekTime) content=offsetLine+content content=unicode(content,'utf8').encode(self.encoderToWrite) file=open(self.fileName,'w') file.write(content) file.close() self.lrcAdjustMenu_saveToFileAction.setEnabled(False) self.totalSeekTime=0 self.encoder=self.encoderToWrite ########## block end ########## ########## block: def amarokControlMenu's function ########## def amarokControlMenu_playorpause(self):# as function's name if(self.amarokStatus=='stop' or self.amarokStatus=='pause'): os.system('dcop amarok player play') else: os.system('dcop amarok player pause') def amarokControlMenu_stop(self):# as function's name os.system('dcop amarok player stop') def amarokControlMenu_prev(self):# as function's name os.system('dcop amarok player prev') def amarokControlMenu_next(self):# as function's name os.system('dcop amarok player next') ########## block end ########### ########## block: def colorMenu's function ########## def colorMenu_back(self):# as function's name rgbColor=QColorDialog.getColor(self.backGroundColor) if(rgbColor.isValid()): self.backGroundColor=rgbColor self.initColor(self.backGroundColor,self.foreGroundColor,self.highLightColor) rgbString='%s,%s,%s' %(str(rgbColor.red()),str(rgbColor.green()),str(rgbColor.blue())) p=ConfigParser.ConfigParser() p.read('lrcShow-II.conf') p.set('option','backroundcolor',rgbString) p.write(open('lrcShow-II.conf', 'w')) def colorMenu_fore(self):# as function's name rgbColor=QColorDialog.getColor(self.foreGroundColor) if(rgbColor.isValid()): self.foreGroundColor=rgbColor self.initColor(self.backGroundColor,self.foreGroundColor,self.highLightColor) rgbString='%s,%s,%s' %(str(rgbColor.red()),str(rgbColor.green()),str(rgbColor.blue())) p=ConfigParser.ConfigParser() p.read('lrcShow-II.conf') p.set('option','fontcolor',rgbString) p.write(open('lrcShow-II.conf', 'w')) def colorMenu_light(self):# as function's name rgbColor=QColorDialog.getColor(self.highLightColor) if(rgbColor.isValid()): self.highLightColor=rgbColor self.initColor(self.backGroundColor,self.foreGroundColor,self.highLightColor) rgbString='%s,%s,%s' %(str(rgbColor.red()),str(rgbColor.green()),str(rgbColor.blue())) p=ConfigParser.ConfigParser() p.read('lrcShow-II.conf') p.set('option','highlightcolor',rgbString) p.write(open('lrcShow-II.conf', 'w')) def colorMenu_default(self):# as function's name self.backGroundColor=QColor(59,86,115) self.foreGroundColor=QColor(255,255,255) self.highLightColor=QColor(180,200,255) self.initColor(self.backGroundColor,self.foreGroundColor,self.highLightColor) p=ConfigParser.ConfigParser() p.read('lrcShow-II.conf') p.set('option','backroundcolor','59,86,115') p.set('option','fontcolor','255,255,255') p.set('option','highlightcolor','180,200,255') p.write(open('lrcShow-II.conf', 'w')) ########## block end ########## ########## block: def setFontAction's fuction ########## def setFontAction_(self):# as function's name if(self.fontItalic=='yes'): font,ok=QFontDialog.getFont(QFont(self.fontType,self.fontSize,self.fontWeight,True),self) else: font,ok=QFontDialog.getFont(QFont(self.fontType,self.fontSize,self.fontWeight,False),self) if ok: self.setFont(font) self.fontType=font.family() self.fontSize=font.pointSize() self.fontWeight=font.weight() if(font.italic()): self.fontItalic='yes' else: self.fontItalic='no' self.initMainEvent() self.goToCurrentPara() l=ConfigParser.ConfigParser() l.read('lrcShow-II.conf') l.set('option','fontsize',str(self.fontSize)) l.set('option','fonttype',str(self.fontType.toUtf8())) l.set('option','fontweight',str(self.fontWeight)) l.set('option','fontitalic',self.fontItalic) l.write(open('lrcShow-II.conf', 'w')) if(self.showMode=='fullscreen'): self.displayMenu_normalAction_() self.displayMenu_fullscreenAction_() ########## block end ########## ########## block: def setLineAction's fuction ########## def setLineAction_(self):# as function's name num,ok=QInputDialog.getInteger(self,_(u'设置行数'),_(u'请输入1-19的奇数,否则无效'),self.lineNum,1,19,2) if(ok and num<>self.lineNum and num in range(1,21,2)): if((num<>1 and self.lineNum<>1) or ((num==1 or self.lineNum==1) and self.horizontal=='no')): self.lineNum=num self.initMainEvent() self.goToCurrentPara() elif((num==1 or self.lineNum==1) and self.horizontal=='yes'): if(num<>1): self.displayMenu_normalAction.setEnabled(True) self.lineNum=num if(self.fileName): file=open(self.fileName) lf=file.read() file.close() self.initEvent(lf) elif(self.originalLrc): self.initEvent(self.originalLrc,True) elif(self.usltLrc): p=embedLrc.embedLrc(self.media) lrc=p.detectLrc() if(lrc<>None): self.initEvent(lrc) else: self.usltLrc=None self.checkData() else: lf='

'+self.toPlainText()+'

' self.showInfo(lf) l=ConfigParser.ConfigParser() l.read('lrcShow-II.conf') l.set('option','linenumber',str(num)) l.write(open('lrcShow-II.conf', 'w')) ########## block end ########## ########## block: def downloadMenu's fuction ########## def downloadMenu_yesAction_(self):# just change the status of auto downloading, but no downloading action would occur if(self.ifDownload=='yes'): pass else: self.downloadMenu_yesAction.setChecked(True) self.ifDownload='yes' l=ConfigParser.ConfigParser() l.read('lrcShow-II.conf') l.set('option','download',self.ifDownload) l.write(open('lrcShow-II.conf', 'w')) def downloadMenu_noAction_(self): if(self.ifDownload=='no'): pass else: self.downloadMenu_noAction.setChecked(True) self.ifDownload='no' l=ConfigParser.ConfigParser() l.read('lrcShow-II.conf') l.set('option','download',self.ifDownload) l.write(open('lrcShow-II.conf', 'w')) def downloadMenu_thisAction_(self):# downloading the lrc file from net but has 2 conditions: auto download is shut off and the lrc in window is from net try: unicode(self.originalLrc,self.netEncoder).encode(self.encoderToWrite) except UnicodeEncodeError: QMessageBox.critical(self,_(u'编码错误'),_(u'在将搜索到的歌词(%s)编码为您预设的保存编码(%s)时发生错误,此次下载被忽略!\n这一般是由于搜索到的歌词中含有无法编码的字符造成的。\n如果多次出现本对话框,强烈建议您关闭自动下载功能,另外也可以设置保存编码为gb18030或者utf8以避免这个问题。') %(self.netEncoder,self.encoderToWrite)) else: if(self.saveToMediaPath=='yes' and self.extPath): pathTmp=self.extPath else: pathTmp=self.saveLrcPath if(os.path.exists(os.path.join(pathTmp,self.nameForSave))): a=QMessageBox.question(self,_(u'询问'),_(u'同名文件已存在,是否覆盖?'),QMessageBox.Yes,QMessageBox.No) if(a==QMessageBox.Yes): try: file=open(os.path.join(pathTmp,self.nameForSave),'w') except: pass else: file.write(unicode(self.originalLrc,self.netEncoder).encode(self.encoderToWrite)) file.close() self.originalLrc=None self.downloadMenu_thisAction.setEnabled(False) self.fileName=os.path.join(pathTmp,self.nameForSave) self.encoder=self.encoderToWrite else: pass else: try: file=open(os.path.join(pathTmp,self.nameForSave),'w') except: pass else: file.write(unicode(self.originalLrc,self.netEncoder).encode(self.encoderToWrite)) file.close() self.originalLrc=None self.downloadMenu_thisAction.setEnabled(False) self.fileName=os.path.join(pathTmp,self.nameForSave) self.encoder=self.encoderToWrite ########## block end (need test) ########## ########## block: def displayMenu's function ########## def displayMenu_normalAction_(self):# normal display mode if(self.showMode=='normal' or (self.lineNum==1 and self.horizontal=='yes')): pass else: self.displayMenu_normalAction.setChecked(True) if(self.showMode=='osd'): self.showMode='normal' self.displayMenu_fullscreenAction.setEnabled(True) self.winFlags=Qt.Window if(self.displayMenu_topAction.isChecked()): self.setWindowFlags(self.winFlags|Qt.WindowStaysOnTopHint) else: self.setWindowFlags(self.winFlags) self.setWindowIcon(QIcon('../scripts/lrcShow-II/icon/logo.png')) self.show() elif(self.showMode=='fullscreen'): self.setMouseTracking(False) if(self.hideMouseTimer.isActive()): self.hideMouseTimer.stop() if(self.viewport().cursor().shape()<>Qt.ArrowCursor): self.viewport().setCursor(QCursor(Qt.ArrowCursor)) self.showMode='normal' self.displayMenu_osdAction.setEnabled(True) self.setLineAction.setEnabled(True) self.displayMenu_topAction.setEnabled(True) self.showNormal() l=ConfigParser.ConfigParser() l.read('lrcShow-II.conf') self.lineNum=int(l.get('option','linenumber')) self.resize(self.widthBefore,self.size().height()) self.move(self.posBefore) self.initMainEvent() if(self.originalLrc or self.fileName or self.usltLrc): self.goToCurrentPara() def displayMenu_fullscreenAction_(self):# fullscreen display mode, the cursor would be auto hiden if(self.showMode=='fullscreen'): pass else: self.showMode='fullscreen' self.displayMenu_fullscreenAction.setChecked(True) self.displayMenu_osdAction.setEnabled(False) self.setLineAction.setEnabled(False) self.displayMenu_topAction.setEnabled(False) self.widthBefore=self.size().width() self.posBefore=self.pos() self.showFullScreen() self.lineNum=QApplication.desktop().height()/self.margin self.initMainEvent() if(self.originalLrc or self.fileName or self.usltLrc): self.goToCurrentPara() self.setMouseTracking(True) self.currentCursorPos=QPoint(0,0) self.lastCursorPos=QPoint(0,0) self.hideMouseTimer.start(2000) def displayMenu_osdAction_(self):# osd display mode, no title bar, can't resize the window. pyqt3 version in this mode, must stay on top, pyqt4 may be not if(self.showMode=='osd'): pass else: self.showMode='osd' self.displayMenu_osdAction.setChecked(True) self.displayMenu_fullscreenAction.setEnabled(False) self.winFlags=Qt.FramelessWindowHint if(self.displayMenu_topAction.isChecked()): self.setWindowFlags(self.winFlags|Qt.WindowStaysOnTopHint) else: self.setWindowFlags(self.winFlags) self.setWindowIcon(QIcon('../scripts/lrcShow-II/icon/logo.png')) self.show() def displayMenu_topAction_(self,bool):# special display mode in pyqt4 version if(bool): self.setWindowFlags(self.winFlags|Qt.WindowStaysOnTopHint) self.show() self.topIsChecked=True else: self.setWindowFlags(self.winFlags) self.show() self.topIsChecked=False ########### block end ########## ########## block: def openLrcEditorAction's function ########## def openLrcEditorAction_(self):# as function's name if(self.fileName): self.editBox=lrcEditorQt4(self.fileName,self.encoder,self.encoderToWrite,self.shortCut_insert,self.shortCut_cancel) else: QMessageBox.information(self,_(u'提示'),_(u'当前没有使用本地歌词文件')) if(self.saveToMediaPath=='yes' and self.extPath): pathTmp=self.extPath else: pathTmp=self.saveLrcPath self.editBox=lrcEditorQt4(pathTmp,self.encoder,self.encoderToWrite,self.shortCut_insert,self.shortCut_cancel) self.editBox.show() ######## block end ########### ########## block: def setSearchEngineAction's function ######### def setSearchEngineAction_(self):# as function's name l=ConfigParser.ConfigParser() l.read('lrcShow-II.conf') engineList=QStringList() for i in glob.glob('../scripts/lrcShow-II/engines/engine_*.py'): i=os.path.basename(i)[7:-3] engineList.append(i) index=engineList.indexOf(l.get('option','searchengine')) engine,ok=QInputDialog.getItem(self,_(u'设置搜索引擎'),_(u'请选择网络搜索引擎:'),engineList,index,False) if(ok): self.searchEngine=str(engine.toUtf8()) l.set('option','searchengine',self.searchEngine) l.write(open('lrcShow-II.conf', 'w')) ########## block end ########## ########## block: def otherFunctionsMenu's function ########## def otherFunctionsMenu_searchAction_(self):# force the app to search lrc from net whatever the track has lrc self.title=commands.getoutput('dcop amarok player title') self.artist=commands.getoutput('dcop amarok player artist') self.media=commands.getoutput('dcop amarok player path') self.extInfo=os.path.splitext(os.path.basename(self.media))[0] self.extPath=os.path.dirname(self.media) if(self.asTrackName=='yes'): self.nameForSave=self.extInfo+'.lrc' else: self.nameForSave='%s - %s.lrc' %(self.artist,self.title) self.fileName=None #maybe needn't self.originalLrc=None self.usltLrc=None self.downloadMenu_thisAction.setEnabled(False) self.downLoad() def otherFunctionsMenu_reloadAction_(self):# re-do the process just like the current track is switched to if(self.amarokStatus=='playing'):# when the current track is playing self.customEvent(myEvent('engineStateChange',self.amarokStatus)) elif(self.amarokStatus=='pause'):# when the current track is pausing if(self.mytimer.isActive()): self.customEvent(myEvent('engineStateChange',self.amarokStatus)) else: self.customEvent(myEvent('startup',self.amarokStatus)) else:#it could not happen when Amarok in stop status pass def otherFunctionsMenu_cancelAction_(self):# let the lrc go hell, if has if(self.includeCancel=='yes'): d=False else: d=True self.fileName=None self.originalLrc=None self.usltLrc=None self.showInfo('

'+_(u'欢迎使用lrcShow-II')+'

',d) def otherFunctionsMenu_insertAction_(self):# send the lrc as complete lyrics into Amarok's sidebar if(self.lineNum==1 and self.horizontal=='yes'): b=re.sub('\!\@\#\$','\n',self.mainContents) else: a=re.sub('

','',self.mainContents) b=re.sub('

|
','\n',a) b=b.encode('utf8') lrc='%s' %(self.title,self.artist,b) command='dcop amarok contextbrowser showLyrics "%s"' %lrc os.system(command) os.system('dcop amarok contextbrowser showLyrics') def otherFunctionsMenu_readUsltAction_(self): p=embedLrc.embedLrc(self.media) lrc=p.detectLrc() if(lrc<>None): self.fileName=None self.originalLrc=None self.usltLrc=True self.initEvent(lrc) else: QMessageBox.information(self,_(u'提示'),_(u'当前音频文件中没有歌词')) def otherFunctionsMenu_insertUsltAction_(self): if(self.originalLrc): lrc=self.originalLrc encoding=self.netEncoder elif(self.fileName): ff=open(self.fileName) lrc=ff.read() ff.close() encoding=self.encoder elif(self.usltLrc): lrc=None QMessageBox.information(self,_(u'提示'),_(u'当前正在使用音频文件中的歌词')) else: lrc=None QMessageBox.information(self,_(u'提示'),_(u'当前没有正在使用的歌词')) if(lrc): lrc=unicode(lrc,encoding).encode('utf8') p=embedLrc.embedLrc(self.media) p.insertLrc(self.lrcTagType,lrc) def otherFunctionsMenu_deleteUsltAction_(self): p=embedLrc.embedLrc(self.media) flag=p.deleteLrc(self.lrcTagType) if flag: pass else: QMessageBox.information(self,_(u'提示'),_(u'当前音频文件的')+self.lrcTagType+_(u'标签中没有歌词')) def otherFunctionsMenu_deleteAllUsltAction_(self): typeList=['id3v2-uslt','apetag','lyrics3v2','lyrics3v1','id3v2-sylt'] existList=[] p=embedLrc.embedLrc(self.media) for i in typeList: flag=p.deleteLrc(i) if flag: existList.append(i) if(len(existList)==0): QMessageBox.information(self,_(u'提示'),_(u'当前音频文件中没有歌词')) def otherFunctionsMenu_otherSetting_(self):# configurate the app settingDialog=otherSettingQt4(self) settingDialog.itemBox.setCurrentRow(0) settingDialog.behaviorPage.minWidth.setValue(self.minWidth) if(self.noLrc=='normal'): settingDialog.behaviorPage.groupHide.normal.setChecked(True) elif(self.noLrc=='hide'): settingDialog.behaviorPage.groupHide.hide.setChecked(True) else: settingDialog.behaviorPage.groupHide.mini.setChecked(True) if(self.includeCancel=='yes'): settingDialog.behaviorPage.groupHide.includeCheckBox.setChecked(True) if(self.autoInsertAmarok=='yes'): settingDialog.normalPage.autoInsert.setChecked(True) if(self.titleBarInfo=='yes'): settingDialog.behaviorPage.autoTitleBar.setChecked(True) if(self.horizontalChange=='yes'): settingDialog.behaviorPage.switchHorizontal.setChecked(True) if(self.rememberShowMode=='yes'): settingDialog.behaviorPage.rememberLastShowMode.setChecked(True) if(self.asTrackName=='yes'): settingDialog.normalPage.asTrackName.setChecked(True) if(self.completeTag=='yes'): settingDialog.normalPage.completeTagSearch.setChecked(True) if(self.useUslt=='yes'): settingDialog.normalPage.lrcInMedia.setChecked(True) if(self.filterLyrics=='yes'): settingDialog.limitPage.filterCheckBox.setChecked(True) else: settingDialog.limitPage.filterCheckBox.setChecked(False) if(self.nullLine=='yes'): settingDialog.limitPage.nullLine.setChecked(True) if(self.saveToMediaPath=='yes'): settingDialog.lrcPathPage.saveToMediaPath.setChecked(True) if(self.searchMediaPath=='yes'): settingDialog.lrcPathPage.searchMediaPath.setChecked(True) settingDialog.limitPage.filterKeyWold.setText(unicode(self.filterRule,'utf8')) tmpPathList=map(lambda x:unicode(x,self.locale),self.path) for i in tmpPathList: settingDialog.lrcPathPage.insertItem(QTableWidgetItem(i,0)) settingDialog.lrcPathPage.savePath.setText(unicode(self.saveLrcPath,self.locale)) index=settingDialog.normalPage.strList.index(self.encoderToWrite) settingDialog.normalPage.comboBox.setCurrentIndex(index) index_=settingDialog.normalPage.strTagList.index(self.lrcTagType) settingDialog.normalPage.comboBoxType.setCurrentIndex(index_) if(self.proxy): settingDialog.normalPage.proxy.setText(self.proxy['http']) else: pass if(self.filterCap=='yes'): settingDialog.limitPage.filterCap.setChecked(True) settingResult=settingDialog.exec_() if(settingResult==QDialog.Accepted): l=ConfigParser.ConfigParser() l.read('lrcShow-II.conf') self.minWidth=settingDialog.behaviorPage.minWidth.value() self.setMinimumWidth(self.minWidth) l.set('option','minwidth',str(self.minWidth)) if(settingDialog.behaviorPage.groupHide.normal.isChecked()): self.noLrc='normal' elif(settingDialog.behaviorPage.groupHide.hide.isChecked()): self.noLrc='hide' elif(settingDialog.behaviorPage.groupHide.mini.isChecked()): self.noLrc='mini' l.set('option','nolrc',self.noLrc) if(settingDialog.behaviorPage.groupHide.includeCheckBox.isChecked()): self.includeCancel='yes' else: self.includeCancel='no' l.set('option','includecancel',self.includeCancel) if(settingDialog.normalPage.asTrackName.isChecked()): self.asTrackName='yes' try: self.nameForSave=self.extInfo+'.lrc' except: pass else: self.asTrackName='no' try: self.nameForSave='%s - %s.lrc' %(self.artist,self.title) except: pass l.set('option','astrackname',self.asTrackName) if(settingDialog.normalPage.autoInsert.isChecked()): self.autoInsertAmarok='yes' else: self.autoInsertAmarok='no' l.set('option','autoinsert',self.autoInsertAmarok) if(settingDialog.normalPage.lrcInMedia.isChecked()): self.useUslt='yes' else: self.useUslt='no' l.set('option','useuslt',self.useUslt) if(settingDialog.behaviorPage.autoTitleBar.isChecked()): self.titleBarInfo='yes' else: self.titleBarInfo='no' l.set('option','titlebarinfo',self.titleBarInfo) if(settingDialog.behaviorPage.switchHorizontal.isChecked()): self.horizontalChange='yes' else: self.horizontalChange='no' l.set('option','horizontal',self.horizontalChange) if(settingDialog.behaviorPage.rememberLastShowMode.isChecked()): self.rememberShowMode='yes' else: self.rememberShowMode='no' l.set('option','remembershowmode',self.rememberShowMode) if(settingDialog.normalPage.completeTagSearch.isChecked()): self.completeTag='yes' else: self.completeTag='no' l.set('option','completetag',self.completeTag) if(settingDialog.limitPage.filterCheckBox.isChecked() and not settingDialog.limitPage.filterKeyWold.text().isEmpty()): self.filterLyrics='yes' else: self.filterLyrics='no' l.set('option','filterlyrics',self.filterLyrics) if(settingDialog.limitPage.nullLine.isChecked()): self.nullLine='yes' else: self.nullLine='no' l.set('option','nullline',self.nullLine) if(settingDialog.limitPage.filterCap.isChecked()): self.filterCap='yes' else: self.filterCap='no' l.set('option','filtercap',self.filterCap) self.filterRule=settingDialog.limitPage.filterKeyWold.text().toUtf8() l.set('option','filterrule',str(self.filterRule)) if(settingDialog.lrcPathPage.saveToMediaPath.isChecked()): self.saveToMediaPath='yes' else: self.saveToMediaPath='no' l.set('option','savetomediapath',self.saveToMediaPath) if(settingDialog.lrcPathPage.searchMediaPath.isChecked()): self.searchMediaPath='yes' else: self.searchMediaPath='no' l.set('option','searchmediapath',self.searchMediaPath) s1='' for j in range(0,settingDialog.lrcPathPage.rowNumber): s1+='%s,' %settingDialog.lrcPathPage.table.item(j,0).text().toUtf8() s2=settingDialog.lrcPathPage.savePath.text().toUtf8() self.path=map(lambda x:unicode(x,'utf8').encode(self.locale),s1.split(',')[0:-1]) self.saveLrcPath=unicode(s2,'utf8').encode(self.locale) l.set('option','lrcpath',str(s1)) l.set('option','savelrcpath',str(s2)) self.encoderToWrite=str(settingDialog.normalPage.comboBox.currentText().toUtf8()) l.set('option','encoder',str(self.encoderToWrite)) self.lrcTagType=str(settingDialog.normalPage.comboBoxType.currentText().toUtf8()) l.set('option','lrctagtype',str(self.lrcTagType)) pp=settingDialog.normalPage.proxy.text() if(pp.isEmpty()): self.proxy=None l.set('option','proxy','no') else: self.proxy={'http':str(pp)} l.set('option','proxy',str(pp)) shortcutName=['fullscreen','osd','normal','insert','cancel','editor','save','delay','advance','fastbar'] for i in range(10): l.set('shortcuts',shortcutName[i],settingDialog.shortcutPage.shortcutValue[i]) l.write(open('lrcShow-II.conf', 'w')) (self.shortCut_fullscreen,self.shortCut_osd,self.shortCut_normal,self.shortCut_insert,self.shortCut_cancel,self.shortCut_editor,self.shortCut_save,self.shortCut_delay,self.shortCut_advance,self.shortCut_fastbar)=map(lambda x: QKeySequence.fromString(x),settingDialog.shortcutPage.shortcutValue) elif(settingResult==QDialog.Rejected): pass ########## block end ########## ########## block: def setStrategyAction's function ######### def setStrategyAction_(self):# as function's name data=self.myData.get('%s||%s' %(self.artist,self.title),False) if(data): self.relationDialog=hasRelationDialog(self) self.relationDialog.trackLabel.setText(unicode(self.artist,self.locale)+u' - '+unicode(self.title,self.locale)) if(data=='FLAG.SKIP_SEARCHLOCAL'): content=_(u'不搜索本地') elif(data=='FLAG.SKIP_SEARCHENGINE'): content=_(u'不搜索网络') elif(data=='FLAG.SKIP_ALL'): content=_(u'什么都不做') else: content=unicode(data,self.locale) self.relationDialog.relationLabel.setText(content) result3=self.relationDialog.exec_() if(result3==1): del self.myData['%s||%s' %(self.artist,self.title)] mydb=open('lrcShow-II.db','w') pickler=pickle.Pickler(mydb,True) pickler.dump(self.myData) mydb.close() else: pass else: self.relationDialog=hasNoRelationDialog(self) self.relationDialog.trackLabel.setText(unicode(self.artist,self.locale)+u' - '+unicode(self.title,self.locale)) result3=self.relationDialog.exec_() if(result3==1): if(self.relationDialog.comboBox.currentIndex()==1): content='FLAG.SKIP_SEARCHLOCAL' elif(self.relationDialog.comboBox.currentIndex()==2): content='FLAG.SKIP_SEARCHENGINE' elif(self.relationDialog.comboBox.currentIndex()==3): content='FLAG.SKIP_ALL' elif(self.relationDialog.comboBox.currentIndex()==4): content=str(self.relationDialog.pathLine.text().toLocal8Bit()) self.myData['%s||%s' %(self.artist,self.title)]=content mydb=open('lrcShow-II.db','w') pickler=pickle.Pickler(mydb,True) pickler.dump(self.myData) mydb.close() else: pass ########## block end ########## ########## block: def viewHelpAction's function ######### def viewHelpAction_(self):# open the build-in help-browser helpBrowser=helpWindow(self) helpBrowser.show() ######### block end ######### ######### block:def aboutAction's function ######### def aboutAction_(self):# about lrcShow-II QMessageBox.about(self,_(u'关于lrcShow-II'),_(u'软件版本:lrcShow-II-0.9.2\n软件简介:动态显示lrc歌词的Amarok脚本\n软件作者:三翻领,OutLikeAShoe\n授权协议:GPL-v2.0\nBug提交:xujia19@gmail.com')) ######### block end ######### ######### block:def aboutQtAction's function ####### def aboutQtAction_(self):# about Qt QMessageBox.aboutQt(self,_(u'关于Qt')) ######### block end ###################### def initMenu(self): # init the right click menu self.myMenu=QMenu() self.lrcAdjustMenu=QMenu() self.lrcAdjustMenu.setTitle(_(u'调整偏移量')) self.lrcAdjustMenu.setIcon(QIcon('../scripts/lrcShow-II/icon/adjust.png')) self.lrcAdjustMenu_delayAction=QAction(QIcon('../scripts/lrcShow-II/icon/backward.png'),_(u'歌词滞后0.2秒'),self) self.lrcAdjustMenu_advancedAction=QAction(QIcon('../scripts/lrcShow-II/icon/forward.png'),_(u'歌词提前0.2秒'),self) self.lrcAdjustMenu_saveToFileAction=QAction(QIcon('../scripts/lrcShow-II/icon/save.png'),_(u'保存偏移量'),self) self.lrcAdjustMenu.addAction(self.lrcAdjustMenu_delayAction) self.lrcAdjustMenu.addAction(self.lrcAdjustMenu_advancedAction) self.lrcAdjustMenu.addSeparator() self.lrcAdjustMenu.addAction(self.lrcAdjustMenu_saveToFileAction) self.myMenu.addMenu(self.lrcAdjustMenu) self.amarokControlMenu=QMenu() self.amarokControlMenu.setTitle(_(u'Amarok控制')) self.amarokControlMenu.setIcon(QIcon('../scripts/lrcShow-II/icon/amarok.png')) self.amarokControlMenu_playorpauseAction=QAction(QIcon('../scripts/lrcShow-II/icon/amarok_play.png'),_(u'播放'),self) self.amarokControlMenu_stopAction=QAction(QIcon('../scripts/lrcShow-II/icon/amarok_stop.png'),_(u'停止'),self) self.amarokControlMenu_prevAction=QAction(QIcon('../scripts/lrcShow-II/icon/amarok_back.png'),_(u'上一首'),self) self.amarokControlMenu_nextAction=QAction(QIcon('../scripts/lrcShow-II/icon/amarok_next.png'),_(u'下一首'),self) self.amarokControlMenu.addAction(self.amarokControlMenu_playorpauseAction) self.amarokControlMenu.addAction(self.amarokControlMenu_stopAction) self.amarokControlMenu.addAction(self.amarokControlMenu_prevAction) self.amarokControlMenu.addAction(self.amarokControlMenu_nextAction) self.myMenu.addMenu(self.amarokControlMenu) self.colorMenu=QMenu() self.colorMenu.setTitle(_(u'设置配色')) self.colorMenu.setIcon(QIcon('../scripts/lrcShow-II/icon/colors.png')) self.colorMenu_backAction=QAction(QIcon('../scripts/lrcShow-II/icon/background.png'),_(u'修改背景色...'),self) self.colorMenu_foreAction=QAction(QIcon('../scripts/lrcShow-II/icon/fontcolor.png'),_(u'修改字体色...'),self) self.colorMenu_lightAction=QAction(QIcon('../scripts/lrcShow-II/icon/highlight.png'),_(u'修改标亮色...'),self) self.colorMenu_defaultAction=QAction(QIcon('../scripts/lrcShow-II/icon/undo.png'),_(u'返回默认配色'),self) self.colorMenu.addAction(self.colorMenu_backAction) self.colorMenu.addAction(self.colorMenu_foreAction) self.colorMenu.addAction(self.colorMenu_lightAction) self.colorMenu.addSeparator() self.colorMenu.addAction(self.colorMenu_defaultAction) self.myMenu.addMenu(self.colorMenu) self.setFontAction=QAction(QIcon('../scripts/lrcShow-II/icon/font.png'),_(u'设置字体...'),self) self.myMenu.addAction(self.setFontAction) self.setLineAction=QAction(QIcon('../scripts/lrcShow-II/icon/line.png'),_(u'设置显示行数...'),self) self.myMenu.addAction(self.setLineAction) self.downloadMenu=QMenu() self.downloadMenu.setTitle(_(u'是否自动保存歌词')) self.downloadMenu.setIcon(QIcon('../scripts/lrcShow-II/icon/download.png')) self.downloadMenu_actionGroup=QActionGroup(self) self.downloadMenu_yesAction=QAction(_(u'是'),self) self.downloadMenu_yesAction.setCheckable(True) self.downloadMenu_noAction=QAction(_(u'否'),self) self.downloadMenu_noAction.setCheckable(True) self.downloadMenu_actionGroup.addAction(self.downloadMenu_yesAction) self.downloadMenu_actionGroup.addAction(self.downloadMenu_noAction) self.downloadMenu_thisAction=QAction(_(u'仅当前'),self) self.downloadMenu.addActions(self.downloadMenu_actionGroup.actions()) self.downloadMenu.addSeparator() self.downloadMenu.addAction(self.downloadMenu_thisAction) self.myMenu.addMenu(self.downloadMenu) self.displayMenu=QMenu() self.displayMenu.setTitle(_(u'设置显示模式')) self.displayMenu.setIcon(QIcon('../scripts/lrcShow-II/icon/screen.png')) self.displayMenu_actionGroup=QActionGroup(self) self.displayMenu_normalAction=QAction(QIcon('../scripts/lrcShow-II/icon/normal.png'),_(u'普通'),self) self.displayMenu_normalAction.setCheckable(True) self.displayMenu_fullscreenAction=QAction(QIcon('../scripts/lrcShow-II/icon/fullscreen.png'),_(u'全屏'),self) self.displayMenu_fullscreenAction.setCheckable(True) self.displayMenu_osdAction=QAction(QIcon('../scripts/lrcShow-II/icon/osd.png'),_(u'OSD'),self) self.displayMenu_osdAction.setCheckable(True) self.displayMenu_topAction=QAction(QIcon('../scripts/lrcShow-II/icon/top.png'),_(u'置顶'),self) self.displayMenu_topAction.setCheckable(True) self.displayMenu_actionGroup.addAction(self.displayMenu_normalAction) self.displayMenu_actionGroup.addAction(self.displayMenu_fullscreenAction) self.displayMenu_actionGroup.addAction(self.displayMenu_osdAction) self.displayMenu_normalAction.setChecked(True) self.displayMenu.addActions(self.displayMenu_actionGroup.actions()) self.displayMenu.addSeparator() self.displayMenu.addAction(self.displayMenu_topAction) self.myMenu.addMenu(self.displayMenu) self.openLrcEditorAction=QAction(QIcon('../scripts/lrcShow-II/icon/edit.png'),_(u'歌词编辑器...'),self) self.myMenu.addAction(self.openLrcEditorAction) self.setSearchEngineAction=QAction(QIcon('../scripts/lrcShow-II/icon/engine.png'),_(u'设置搜索引擎...'),self) self.myMenu.addAction(self.setSearchEngineAction) self.otherFunctionsMenu=QMenu() self.otherFunctionsMenu.setTitle(_(u'其他功能')) self.otherFunctionsMenu.setIcon(QIcon('../scripts/lrcShow-II/icon/function.png')) self.otherFunctionsMenu_searchAction=QAction(QIcon('../scripts/lrcShow-II/icon/search.png'),_(u'从网络搜索歌词'),self) self.otherFunctionsMenu_cancelAction=QAction(QIcon('../scripts/lrcShow-II/icon/cancel.png'),_(u'撤销当前歌词'),self) self.otherFunctionsMenu_reloadAction=QAction(QIcon('../scripts/lrcShow-II/icon/reload.png'),_(u'重新载入歌词'),self) self.otherFunctionsMenu.addAction(self.otherFunctionsMenu_reloadAction) self.otherFunctionsMenu.addAction(self.otherFunctionsMenu_cancelAction) self.otherFunctionsMenu_insertAction=QAction(QIcon('../scripts/lrcShow-II/icon/add_lyrics.png'),_(u'传送歌词至Amarok侧边栏'),self) self.otherFunctionsMenu_otherSetting=QAction(QIcon('../scripts/lrcShow-II/icon/configure.png'),_(u'参数设置...'),self) self.otherFunctionsMenu.addAction(self.otherFunctionsMenu_searchAction) self.otherFunctionsMenu_readUsltAction=QAction(QIcon('../scripts/lrcShow-II/icon/read_lrc.png'),_(u'从音频文件中读取歌词'),self) self.otherFunctionsMenu_insertUsltAction=QAction(QIcon('../scripts/lrcShow-II/icon/insert_tag.png'),_(u'将歌词嵌入音频文件'),self) self.otherFunctionsMenu_deleteUsltAction=QAction(QIcon('../scripts/lrcShow-II/icon/del_tags.png'),_(u'从音频文件中删除歌词'),self) self.otherFunctionsMenu_deleteAllUsltAction=QAction(QIcon('../scripts/lrcShow-II/icon/del_all_tags.png'),_(u'删除所有内嵌歌词'),self) self.otherFunctionsMenu.addAction(self.otherFunctionsMenu_insertUsltAction) self.otherFunctionsMenu.addAction(self.otherFunctionsMenu_readUsltAction) self.otherFunctionsMenu.addAction(self.otherFunctionsMenu_deleteUsltAction) self.otherFunctionsMenu.addAction(self.otherFunctionsMenu_deleteAllUsltAction) self.otherFunctionsMenu.addAction(self.otherFunctionsMenu_otherSetting) self.otherFunctionsMenu.addAction(self.otherFunctionsMenu_insertAction) self.myMenu.addMenu(self.otherFunctionsMenu) self.setStrategyAction=QAction(QIcon('../scripts/lrcShow-II/icon/relation.png'),_(u'当前音轨歌词策略...'),self) self.myMenu.addAction(self.setStrategyAction) self.helpMenu=QMenu() self.helpMenu.setTitle(_(u'帮助')) self.helpMenu.setIcon(QIcon('../scripts/lrcShow-II/icon/help.png')) self.viewHelpAction=QAction(QIcon('../scripts/lrcShow-II/icon/contents.png'),_(u'帮助文档...'),self) self.aboutQtAction=QAction(QIcon('../scripts/lrcShow-II/icon/qt.png'),_(u'关于Qt...'),self) self.aboutAction=QAction(QIcon('../scripts/lrcShow-II/icon/logo.png'),_(u'关于lrcShow-II...'),self) self.helpMenu.addAction(self.viewHelpAction) self.helpMenu.addAction(self.aboutQtAction) self.helpMenu.addAction(self.aboutAction) self.myMenu.addMenu(self.helpMenu) self.closeAction=QAction(QIcon('../scripts/lrcShow-II/icon/exit.png'),_(u'退出lrcShow-II'),self) self.myMenu.addAction(self.closeAction) def initSettingMenuBar(self): # init the fast setting bar self.toolMenuBar=QToolBar(self) self.toolMenuBar.addAction(self.lrcAdjustMenu_delayAction) self.toolMenuBar.addAction(self.lrcAdjustMenu_advancedAction) self.toolMenuBar.addAction(self.lrcAdjustMenu_saveToFileAction) self.toolMenuBar.addSeparator() self.toolMenuBar.addAction(self.amarokControlMenu_playorpauseAction) self.toolMenuBar.addAction(self.amarokControlMenu_stopAction) self.toolMenuBar.addAction(self.amarokControlMenu_prevAction) self.toolMenuBar.addAction(self.amarokControlMenu_nextAction) self.toolMenuBar.addSeparator() self.toolMenuBar.addAction(self.openLrcEditorAction) self.toolMenuBar.hide() def initColor(self,a,b,c):# to set colors pl=QPalette() for i in [QPalette.Active,QPalette.Inactive,QPalette.Disabled]: for j in [QPalette.Window,QPalette.Base]: pl.setColor(i,j,a) pl.setColor(i,QPalette.Text,b) pl.setColor(i,QPalette.Highlight,a) pl.setColor(i,QPalette.HighlightedText,c) self.setPalette(pl) def contextMenuEvent(self,ev):# show the right click menu self.myMenu.popup(ev.globalPos()) def mouseDoubleClickEvent(self,ev):# to show/hide the fast setting bar if(self.toolMenuBar.isHidden()): self.toolMenuBar.show() else: self.toolMenuBar.hide() ############# define shortcut ######################### def keyPressEvent(self,ev): if(ev.key()==self.shortCut_delay and self.lrcAdjustMenu_delayAction.isEnabled()): self.seekSlow() elif(ev.key()==self.shortCut_advance and self.lrcAdjustMenu_advancedAction.isEnabled()): self.seekFast() elif(ev.key()==self.shortCut_save and self.lrcAdjustMenu_saveToFileAction.isEnabled()): self.saveToFile() elif(ev.key()==self.shortCut_fullscreen and self.showMode=='normal'): self.displayMenu_fullscreenAction_() elif(ev.key()==self.shortCut_normal and (self.showMode=='fullscreen' or self.showMode=='osd')): self.displayMenu_normalAction_() elif(ev.key()==self.shortCut_osd and self.showMode=='normal'): self.displayMenu_osdAction_() elif(ev.key()==self.shortCut_editor): self.openLrcEditorAction_() elif(ev.key()==self.shortCut_fastbar): if(self.toolMenuBar.isHidden()): self.toolMenuBar.show() else: self.toolMenuBar.hide() def closeEvent(self,ev): point=self.pos() x=point.x() y=point.y() if(self.topIsChecked): r='yes' else: r='no' l=ConfigParser.ConfigParser() l.read('lrcShow-II.conf') l.set('option','lastposition','%s,%s' %(str(x),str(y))) l.set('option','lastshowmode',self.showMode) l.set('option','lastistop',r) l.write(open('lrcShow-II.conf', 'w')) ev.accept() def mouseReleaseEvent(self,ev):# disable this event pass def wheelEvent(self,ev):# disable this event pass def dragMoveEvent(self,ev):# disable this event pass def mousePressEvent(self,ev):# to get the coordinates for draging and moving the window self.xPos=ev.x() self.yPos=ev.y() def mouseMoveEvent(self,ev):# draging and moving the window, but in fullscreen display mode, the mouseTracking is True and this event is used to auto hide cursor if(self.showMode=='fullscreen'): self.currentCursorPos=ev.pos() if(self.viewport().cursor().shape()<>Qt.ArrowCursor): self.viewport().setCursor(QCursor(Qt.ArrowCursor)) self.hideMouseTimer.start(2000) else: if(ev.buttons()==Qt.LeftButton): a=ev.x()-self.xPos b=ev.y()-self.yPos self.move(self.x()+a,self.y()+b) def checkHideMouse(self):# this function is used to check if the cursor need to hide when a QTimer object's timeout signal is emit if(self.lastCursorPos==self.currentCursorPos): self.viewport().setCursor(QCursor(Qt.BlankCursor)) if(self.hideMouseTimer.isActive()): self.hideMouseTimer.stop() else: self.lastCursorPos=self.currentCursorPos