Beispiel #1
0
class Window(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super(QMainWindow, self).__init__()
        self.setupUi(self)

        self.statusBar.showMessage("请选择文件")

        self.AdNDP = AdNDP()
        self.AdNDP.resultSignal.connect(self.resultTextEdit.append)
        self.AdNDP.logSignal.connect(self.logTextEdit.append)
        self.AdNDP.informationSignal.connect(self.informationTextEdit.append)
        self.AdNDP.setMaximumSignal.connect(self.progressBar.setMaximum)
        self.AdNDP.setValueSignal.connect(self.progressBar.setValue)

    @pyqtSlot()
    def on_openFileAct_triggered(self):
        path = QFileDialog.getOpenFileName(
            self, "请选择初始化文件", "./example",
            "NBO Files (*.log);;All Files (*)")[0]
        # path = "./example/Li5+.log"
        if path != '':
            self.AdNDP.readFile(path)
            self.progressBar.setValue(0)
            self.startAnalysisAct.setEnabled(True)
            self.settingAct.setEnabled(True)
        else:
            QMessageBox.warning(self, "错误", "请选择文件")

    @pyqtSlot()
    def on_startAnalysisAct_triggered(self):
        self.statusBar.showMessage("分析中......")
        self.WorkThread = WorkThread(self.AdNDP)
        self.WorkThread.start()
        self.WorkThread.finishSignal.connect(self.on_workThread_finishSignal)

    def on_workThread_finishSignal(self):
        QMessageBox.about(self, "提示", "分析完成")
        self.exportFileAct.setEnabled(True)
        self.statusBar.showMessage("分析结束,共找到" + str(self.AdNDP.nboAmnt) +
                                   "个轨道")

    @pyqtSlot()
    def on_aboutAct_triggered(self):
        self.aboutWindow = AboutWindow()
        self.aboutWindow.show()

    @pyqtSlot()
    def on_exportFileAct_triggered(self):
        savePath = QFileDialog.getSaveFileName(self, "请选择保存位置", "./example",
                                               "log格式 (*.log)")[0]
        if savePath != '':
            self.AdNDP.nboPlotMolden(savePath)
            QMessageBox.about(self, "提示", "保存成功")
        else:
            QMessageBox.warning(self, "提示", "请重新选择保存位置")

    @pyqtSlot()
    def on_settingAct_triggered(self):
        self.settingWindow = SettingWindow(self.AdNDP.NAt)
        self.settingWindow.resultSignal.connect(self.AdNDP.setThreshold)
        self.settingWindow.show()

    @pyqtSlot()
    def on_clearScreenAct_triggered(self):
        self.resultTextEdit.clear()
        self.informationTextEdit.clear()
        self.logTextEdit.clear()

        self.progressBar.setValue(0)
        self.startAnalysisAct.setEnabled(False)
        self.exportFileAct.setEnabled(False)
        self.settingAct.setEnabled(False)
        self.statusBar.showMessage("清除完成,请重新选择文件......")
Beispiel #2
0
class MainWindow(MainWindow_Ui):
    def __init__(self):
        super().__init__()
        self.system_tray_icon = QSystemTrayIcon() 
        self.system_tray_icon.setIcon(QIcon.fromTheme('persepolis',QIcon(':/icon.svg') ))
        system_tray_menu = QMenu()
        system_tray_menu.addAction(self.addlinkAction)
        system_tray_menu.addAction(self.pauseAllAction)
        system_tray_menu.addAction(self.stopAllAction)
        system_tray_menu.addAction(self.minimizeAction)
        system_tray_menu.addAction(self.exitAction)
        self.system_tray_icon.setContextMenu(system_tray_menu)
        self.system_tray_icon.activated.connect(self.systemTrayPressed)
        self.system_tray_icon.show()
        self.system_tray_icon.setToolTip('Persepolis Download Manager')
        f = Open(setting_file)
        setting_file_lines = f.readlines()
        f.close()
        setting_dict_str = str(setting_file_lines[0].strip())
        setting_dict = ast.literal_eval(setting_dict_str) 
        if setting_dict['tray-icon'] != 'yes': 
            self.minimizeAction.setEnabled(False)
            self.trayAction.setChecked(False)
            self.system_tray_icon.hide()


        self.statusbar.showMessage('Please Wait ...')
        self.checkSelectedRow()

#touch download_list_file
        if not(os.path.isfile(download_list_file)):
            f = Open(download_list_file , 'w')
            f.close()

#touch download_list_file_active
        if not(os.path.isfile(download_list_file_active)):
            f = Open(download_list_file_active , 'w')
            f.close()


#lock files perventing to access a file simultaneously

#removing lock files in starting persepolis
        os.system("rm " + config_folder +"/*.lock" + "  2>/dev/null" )
        os.system("rm " + download_info_folder + "/*.lock" + "   2>/dev/null" )



#threads     
        self.threadPool=[]
#starting aria
        start_aria = StartAria2Thread()
        self.threadPool.append(start_aria)
        self.threadPool[0].start() 
        self.threadPool[0].ARIA2RESPONDSIGNAL.connect(self.startAriaMessage)

#initializing    
#add downloads to the download_table
        f_download_list_file = Open(download_list_file)
        download_list_file_lines = f_download_list_file.readlines()
        f_download_list_file.close()
            
        for line in download_list_file_lines:
            gid = line.strip()
            self.download_table.insertRow(0)
            download_info_file = download_info_folder + "/" + gid
            download_info_file_list = readList(download_info_file,'string')
            for i in range(10):
                item = QTableWidgetItem(download_info_file_list[i])
                self.download_table.setItem(0 , i , item)

        row_numbers = self.download_table.rowCount()
        for row in range(row_numbers):
            status = self.download_table.item(row , 1).text() 
            if (status != "complete" and status != "error"):
                gid = self.download_table.item(row,8).text() 
                add_link_dictionary_str = self.download_table.item(row,9).text() 
                add_link_dictionary = ast.literal_eval(add_link_dictionary_str.strip()) 
                add_link_dictionary['start_hour'] = None
                add_link_dictionary['start_minute'] = None
                add_link_dictionary['end_hour'] = None
                add_link_dictionary['end_minute'] = None
                add_link_dictionary['after_download'] = 'None'

                download_info_file = download_info_folder + "/" + gid
                download_info_file_list = readList(download_info_file,'string')

                for i in range(10):
                    if i == 1 :
                        download_info_file_list[i] = 'stopped'
                        item = QTableWidgetItem('stopped')
                        self.download_table.setItem(row , i , item )
                download_info_file_list[9] = add_link_dictionary
                writeList(download_info_file , download_info_file_list)

        self.addlinkwindows_list = []
        self.propertieswindows_list = []
        self.progress_window_list = []
        self.afterdownload_list = []
        self.progress_window_list_dict = {}

        check_download_info = CheckDownloadInfoThread()
        self.threadPool.append(check_download_info)
        self.threadPool[1].start()
        self.threadPool[1].DOWNLOAD_INFO_SIGNAL.connect(self.checkDownloadInfo)

        check_selected_row = CheckSelectedRowThread()
        self.threadPool.append(check_selected_row)
        self.threadPool[2].start()
        self.threadPool[2].CHECKSELECTEDROWSIGNAL.connect(self.checkSelectedRow)

        check_flashgot = CheckFlashgot()
        self.threadPool.append(check_flashgot)
        self.threadPool[3].start()
        self.threadPool[3].CHECKFLASHGOTSIGNAL.connect(self.checkFlashgot)
        self.threadPool[3].SHOWMAINWINDOWSIGNAL.connect(self.showMainWindow)

        self.download_table.itemDoubleClicked.connect(self.openFile)
        
    def startAriaMessage(self,message):
        global aria_startup_answer
        if message == 'yes':
            sleep (2)
            self.statusbar.showMessage('Ready...')
            aria_startup_answer = 'ready'
        else:
            self.statusbar.showMessage('Error...')
            notifySend('Persepolis can not connect to Aria2' , 'Restart Persepolis' ,10000,'critical' , systemtray = self.system_tray_icon )

    def checkDownloadInfo(self,gid):
        try:

#get download information from download_info_file according to gid and write them in download_table cells
            download_info_file = config_folder + "/download_info/" + gid
            download_info_file_list = readList(download_info_file)
            download_info_file_list_string = readList(download_info_file ,'string')
#finding row of this gid!
            for i in range(self.download_table.rowCount()):
                row_gid = self.download_table.item(i , 8).text()
                if gid == row_gid :
                    row = i 
                    break

            for i in range(10):
#check flag of download!
#It's showing that selection mode is active or not!
                if i == 0 :
                    flag = int(self.download_table.item(row , i).flags())

#remove gid of completed download from active downloads list file
                elif i == 1 :
                    status = str(download_info_file_list[i])
                    status_download_table = str(self.download_table.item(row , 1 ) . text())
                    if status == "complete":
                        f = Open(download_list_file_active)
                        download_list_file_active_lines = f.readlines()
                        f.close()
                        f = Open(download_list_file_active , "w")
                        for line in download_list_file_active_lines :
                            if line.strip() != gid :
                                f.writelines(line.strip() + "\n")
                        f.close()
                    
#update download_table cells
                item = QTableWidgetItem(download_info_file_list_string[i])
#48 means that item is checkable and enabled
                if i == 0 and flag == 48:
                    item.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled)
                    if self.download_table.item(row , i).checkState() == 2:
                        item.setCheckState(QtCore.Qt.Checked)
                    else:
                        item.setCheckState(QtCore.Qt.Unchecked)


                self.download_table.setItem(row , i , item)
                self.download_table.viewport().update()
#update progresswindow
            try :

#finding progress_window for gid            
                member_number = self.progress_window_list_dict[gid]
                progress_window = self.progress_window_list[member_number]
                #link
                add_link_dictionary = download_info_file_list[9]
                link = "<b>Link</b> : " +  str(add_link_dictionary ['link'])
                progress_window.link_label.setText(link)
                progress_window.link_label.setToolTip(link)

                #Save as
                final_download_path = add_link_dictionary['final_download_path']
                if final_download_path == None :
                    final_download_path = str(add_link_dictionary['download_path'])
                        
                save_as = "<b>Save as</b> : " + final_download_path + "/" + str(download_info_file_list[0])
                progress_window.save_label.setText(save_as)
                progress_window.save_label.setToolTip(save_as)

                #status
                progress_window.status = download_info_file_list[1]
                status = "<b>Status</b> : " + progress_window.status 
                progress_window.status_label.setText(status)
                if progress_window.status == "downloading":
                    progress_window.resume_pushButton.setEnabled(False)
                    progress_window.stop_pushButton.setEnabled(True)
                    progress_window.pause_pushButton.setEnabled(True)
                elif progress_window.status == "paused":
                    progress_window.resume_pushButton.setEnabled(True)
                    progress_window.stop_pushButton.setEnabled(True)
                    progress_window.pause_pushButton.setEnabled(False)
                elif progress_window.status == "waiting":
                    progress_window.resume_pushButton.setEnabled(False)
                    progress_window.stop_pushButton.setEnabled(True)
                    progress_window.pause_pushButton.setEnabled(False)
                elif progress_window.status == "scheduled":
                    progress_window.resume_pushButton.setEnabled(False)
                    progress_window.stop_pushButton.setEnabled(True)
                    progress_window.pause_pushButton.setEnabled(False)
                elif progress_window.status == "stopped" or progress_window.status == "error" or progress_window.status == "complete" :
#close progress_window if download status is stopped or completed or error
                    progress_window.close()
                    self.progress_window_list[member_number] = []
                    del self.progress_window_list_dict[gid]
                    if progress_window.status == "stopped":
                        notifySend("Download Stopped" , str(download_info_file_list[0]) , 10000 , 'no', systemtray = self.system_tray_icon )

                    elif progress_window.status == "error":
                        notifySend("Error - " + add_link_dictionary['error'] , str(download_info_file_list[0]) , 10000 , 'fail', systemtray = self.system_tray_icon )
               
                        add_link_dictionary['start_hour'] = None
                        add_link_dictionary['start_minute'] = None
                        add_link_dictionary['end_hour'] = None
                        add_link_dictionary['end_minute'] = None
                        add_link_dictionary['after_download'] = 'None'

                        for i in range(10):
                            if i == 9 :
                                download_info_file_list[i] = add_link_dictionary
                                
                        download_info_file_list[9] = add_link_dictionary 
                        writeList(download_info_file , download_info_file_list )


#this section is sending shutdown signal to the shutdown script(if user select shutdown for after download)
                    if os.path.isfile('/tmp/persepolis/shutdown/' + gid ) == True and progress_window.status != 'stopped':
                        answer = download.shutDown()
#KILL aria2c if didn't respond
                        if answer == 'error':
                            os.system('killall aria2c')
                        f = Open('/tmp/persepolis/shutdown/' + gid , 'w')
                        notifySend('Persepolis is shutting down','your system in 20 seconds' , 15000 ,'warning', systemtray = self.system_tray_icon )
                        f.writelines('shutdown')
                        f.close()
                    elif os.path.isfile('/tmp/persepolis/shutdown/' + gid ) == True and progress_window.status == 'stopped':
                        f = Open('/tmp/persepolis/shutdown/' + gid , 'w')
                        f.writelines('canceled')
                        f.close()

#showing download compelete dialog
#check user's Preferences
                    f = Open(setting_file)
                    setting_file_lines = f.readlines()
                    f.close()
                    setting_dict_str = str(setting_file_lines[0].strip())
                    setting_dict = ast.literal_eval(setting_dict_str) 
 
                    if progress_window.status == "complete" and setting_dict['after-dialog'] == 'yes' :
                        afterdownloadwindow = AfterDownloadWindow(download_info_file_list,setting_file)
                        self.afterdownload_list.append(afterdownloadwindow)
                        self.afterdownload_list[len(self.afterdownload_list) - 1].show()
                    elif progress_window.status == "complete" and setting_dict['after-dialog'] == 'no' :
                        notifySend("Download Complete" ,str(download_info_file_list[0])  , 10000 , 'ok' , systemtray = self.system_tray_icon )



             
                #downloaded
                downloaded = "<b>Downloaded</b> : " + str(download_info_file_list[3]) + "/" + str(download_info_file_list[2])
                progress_window.downloaded_label.setText(downloaded)

                #Transfer rate
                rate = "<b>Transfer rate</b> : " + str(download_info_file_list[6])
                progress_window.rate_label.setText(rate)

                #Estimate time left
                estimate_time_left = "<b>Estimate time left</b> : " + str(download_info_file_list[7]) 
                progress_window.time_label.setText(estimate_time_left)

                #Connections
                connections = "<b>Connections</b> : " + str(download_info_file_list[5])
                progress_window.connections_label.setText(connections)


                #progressbar
                value = download_info_file_list[4]
                file_name = str(download_info_file_list[0])
                if file_name != "***":
                    windows_title = '(' + str(value) + ')' +  str(file_name)
                    progress_window.setWindowTitle(windows_title) 

                value = value[:-1]
                progress_window.download_progressBar.setValue(int(value))



            except :
                pass

        except:
            pass
                   



#contex menu
    def contextMenuEvent(self, event):
        self.tablewidget_menu = QMenu(self)
        self.tablewidget_menu.addAction(self.openFileAction)
        self.tablewidget_menu.addAction(self.openDownloadFolderAction)
        self.tablewidget_menu.addAction(self.resumeAction)
        self.tablewidget_menu.addAction(self.pauseAction)
        self.tablewidget_menu.addAction(self.stopAction)
        self.tablewidget_menu.addAction(self.removeAction)
        self.tablewidget_menu.addAction(self.deleteFileAction)
        self.tablewidget_menu.addAction(self.propertiesAction)
        self.tablewidget_menu.addAction(self.progressAction)
        self.tablewidget_menu.popup(QtGui.QCursor.pos())
#drag and drop for links
    def dragEnterEvent(self, droplink):

        text = str(droplink.mimeData().text())
      
        if ("tp:/" in text[2:6]) or ("tps:/" in text[2:7]) :
            droplink.accept()
        else:
            droplink.ignore() 

    def dropEvent(self, droplink):
        link_clipborad = QApplication.clipboard()
        link_clipborad.clear(mode=link_clipborad.Clipboard )
        link_string = droplink.mimeData().text() 
        link_clipborad.setText(str(link_string), mode=link_clipborad.Clipboard) 
        self.addLinkButtonPressed(button =link_clipborad )
    
	
    def gidGenerator(self):
        my_gid = hex(random.randint(1152921504606846976,18446744073709551615))
        my_gid = my_gid[2:18]
        my_gid = str(my_gid)
        f = Open(download_list_file_active)
        active_gid_list = f.readlines()
        f.close()
        while my_gid in active_gid_list :
            my_gid = self.gidGenerator()
        active_gids = download.activeDownloads()
        while my_gid in active_gids:
            my_gid = self.gidGenerator()
        
        return my_gid

    def selectedRow(self):
        try:
            item = self.download_table.selectedItems()
            selected_row_return = self.download_table.row(item[1]) 
            download_info = self.download_table.item(selected_row_return , 9).text()
            download_info = ast.literal_eval(download_info) 
            link = download_info['link']
            self.statusbar.showMessage(str(link))

        except :
            selected_row_return = None

        return selected_row_return 

    def checkSelectedRow(self):
        try:
            item = self.download_table.selectedItems()
            selected_row_return = self.download_table.row(item[1]) 
        except :
            selected_row_return = None

        if selected_row_return != None :
            status = self.download_table.item(selected_row_return , 1).text() 
            if status == "scheduled":
                self.resumeAction.setEnabled(False)
                self.pauseAction.setEnabled(False)
                self.stopAction.setEnabled(True)
                self.removeAction.setEnabled(False)
                self.propertiesAction.setEnabled(False)
                self.progressAction.setEnabled(True)
                self.openDownloadFolderAction.setEnabled(False)
                self.openFileAction.setEnabled(False)            
                self.deleteFileAction.setEnabled(False)

            elif status == "stopped" or status == "error" :
                self.stopAction.setEnabled(False)
                self.pauseAction.setEnabled(False)
                self.resumeAction.setEnabled(True)
                self.removeAction.setEnabled(True)
                self.propertiesAction.setEnabled(True)
                self.progressAction.setEnabled(False)
                self.openDownloadFolderAction.setEnabled(False)
                self.openFileAction.setEnabled(False)            
                self.deleteFileAction.setEnabled(False)



            elif status == "downloading":
                self.resumeAction.setEnabled(False)
                self.pauseAction.setEnabled(True)
                self.stopAction.setEnabled(True)
                self.removeAction.setEnabled(False)
                self.propertiesAction.setEnabled(False)
                self.progressAction.setEnabled(True)
                self.openDownloadFolderAction.setEnabled(False)
                self.openFileAction.setEnabled(False)            
                self.deleteFileAction.setEnabled(False)



            elif status == "waiting": 
                self.stopAction.setEnabled(True)
                self.resumeAction.setEnabled(False)
                self.pauseAction.setEnabled(False)
                self.removeAction.setEnabled(False)
                self.propertiesAction.setEnabled(False)
                self.progressAction.setEnabled(True)
                self.openDownloadFolderAction.setEnabled(False)
                self.openFileAction.setEnabled(False)            
                self.deleteFileAction.setEnabled(False)



            elif status == "complete":
                self.stopAction.setEnabled(False)
                self.resumeAction.setEnabled(False)
                self.pauseAction.setEnabled(False)
                self.removeAction.setEnabled(True)
                self.propertiesAction.setEnabled(True)
                self.progressAction.setEnabled(False)
                self.openDownloadFolderAction.setEnabled(True)
                self.openFileAction.setEnabled(True)            
                self.deleteFileAction.setEnabled(True)



            elif status == "paused":
                self.stopAction.setEnabled(True)
                self.resumeAction.setEnabled(True)
                self.pauseAction.setEnabled(False)
                self.removeAction.setEnabled(False)
                self.propertiesAction.setEnabled(False)
                self.progressAction.setEnabled(True)
                self.openDownloadFolderAction.setEnabled(False)
                self.openFileAction.setEnabled(False)            
                self.deleteFileAction.setEnabled(False)


              
 
            else:
                self.progressAction.setEnabled(False)
                self.resumeAction.setEnabled(False)
                self.stopAction.setEnabled(False)
                self.pauseAction.setEnabled(False)
                self.removeAction.setEnabled(False)
                self.propertiesAction.setEnabled(False)
                self.openDownloadFolderAction.setEnabled(False)
                self.openFileAction.setEnabled(False)            
                self.deleteFileAction.setEnabled(False)



        else:
            self.progressAction.setEnabled(False)
            self.resumeAction.setEnabled(False)
            self.stopAction.setEnabled(False)
            self.pauseAction.setEnabled(False)
            self.removeAction.setEnabled(False)
            self.propertiesAction.setEnabled(False)
            self.openDownloadFolderAction.setEnabled(False)
            self.openFileAction.setEnabled(False)            
            self.deleteFileAction.setEnabled(False)



           
    def checkFlashgot(self):
        sleep(0.5)
        flashgot_file = Open("/tmp/persepolis-flashgot")
        flashgot_line = flashgot_file.readlines()
        flashgot_file.close()
        flashgot_file.remove()
        flashgot_add_link_dictionary_str = flashgot_line[0]
        flashgot_add_link_dictionary = ast.literal_eval(flashgot_add_link_dictionary_str) 
        self.flashgotAddLink(flashgot_add_link_dictionary)


    def flashgotAddLink(self,flashgot_add_link_dictionary):
        addlinkwindow = AddLinkWindow(self.callBack , flashgot_add_link_dictionary)
        self.addlinkwindows_list.append(addlinkwindow)
        self.addlinkwindows_list[len(self.addlinkwindows_list) - 1].show()

       
            



    def addLinkButtonPressed(self ,button):
        addlinkwindow = AddLinkWindow(self.callBack)
        self.addlinkwindows_list.append(addlinkwindow)
        self.addlinkwindows_list[len(self.addlinkwindows_list) - 1].show()

    def callBack(self , add_link_dictionary):
        gid = self.gidGenerator()

        download_info_file_list = ['***','waiting','***','***','***','***','***','***',gid , add_link_dictionary]
        download_info_file = config_folder + "/download_info/" + gid
        os.system("touch " + download_info_file )
         
        writeList(download_info_file , download_info_file_list)
        
        self.download_table.insertRow(0)
        j = 0
        download_info_file_list[9] = str(download_info_file_list[9])
        for i in download_info_file_list :
            item = QTableWidgetItem(i)
            self.download_table.setItem(0,j,item)
            j = j + 1

        if self.selectAction.isChecked() == True:
            item = self.download_table.item(0 , 0)
            item.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled)
            item.setCheckState(QtCore.Qt.Unchecked)
 
        f = Open (download_list_file , "a")
        f.writelines(gid + "\n")
        f.close()


        f = Open (download_list_file_active , "a")
        f.writelines(gid + "\n")
        f.close()
        new_download = DownloadLink(gid)
        self.threadPool.append(new_download)
        self.threadPool[len(self.threadPool) - 1].start()
        self.progressBarOpen(gid) 
        if add_link_dictionary['start_hour'] == None :
            message = "Download Starts"
        else:
            message = "Download Scheduled"
        notifySend(message ,'' , 10000 , 'no', systemtray = self.system_tray_icon )

 

        
    def resumeButtonPressed(self,button):
        self.resumeAction.setEnabled(False)
        selected_row_return = self.selectedRow()
        if selected_row_return != None:
            gid = self.download_table.item(selected_row_return , 8 ).text()
            download_status = self.download_table.item(selected_row_return , 1).text()
 
                
            if download_status == "paused" :
                answer = download.downloadUnpause(gid)
                if answer == 'None':
                    notifySend("Aria2 did not respond!","Try agian!",10000,'warning' , systemtray = self.system_tray_icon )



            else:
                new_download = DownloadLink(gid)
                self.threadPool.append(new_download)
                self.threadPool[len(self.threadPool) - 1].start()
                sleep(1)
                self.progressBarOpen(gid)




        else:
            self.statusbar.showMessage("Please select an item first!")


    def stopButtonPressed(self,button):
        self.stopAction.setEnabled(False)
        selected_row_return = self.selectedRow()
        if selected_row_return != None:
            gid = self.download_table.item(selected_row_return , 8 ).text()
            answer = download.downloadStop(gid)
            if answer == 'None':
                notifySend("Aria2 did not respond!","Try agian!" , 10000 , 'critical' , systemtray = self.system_tray_icon )



           
               
        else:
            self.statusbar.showMessage("Please select an item first!")

    def pauseButtonPressed(self,button):
        self.pauseAction.setEnabled(False)
        selected_row_return = self.selectedRow()
        if selected_row_return != None:
            gid = self.download_table.item(selected_row_return , 8 ).text()
            answer = download.downloadPause(gid)
            if answer == 'None':
                notifySend("Aria2 did not respond!" , "Try agian!" , 10000 , 'critical' , systemtray = self.system_tray_icon )

        else:
            self.statusbar.showMessage("Please select an item first!")
        sleep(1)

    def removeButtonPressed(self,button):
        self.removeAction.setEnabled(False)
        global remove_flag
        if remove_flag !=3 :
            remove_flag = 1
            while remove_flag != 2 :
                sleep(0.1)
        selected_row_return = self.selectedRow()
        if selected_row_return != None:
            gid = self.download_table.item(selected_row_return , 8 ).text()
            file_name = self.download_table.item(selected_row_return , 0).text()
            status = self.download_table.item(selected_row_return , 1).text()
            sleep(0.5)
            self.download_table.removeRow(selected_row_return)

#remove gid of download from download list file
            f = Open(download_list_file)
            download_list_file_lines = f.readlines()
            f.close()
            f = Open(download_list_file , "w")
            for i in download_list_file_lines:
                if i.strip() != gid:
                    f.writelines(i.strip() + "\n")
            f.close()
#remove gid of download from active download list file
            f = Open(download_list_file_active)
            download_list_file_active_lines = f.readlines()
            f.close()
            f = Open(download_list_file_active , "w")
            for i in download_list_file_active_lines:
                if i.strip() != gid:
                    f.writelines(i.strip() + "\n")
            f.close()
#remove download_info_file
            download_info_file = download_info_folder + "/" + gid
            f = Open(download_info_file)
            f.close()
            f.remove()
#remove file of download form download temp folder
            if file_name != '***' and status != 'complete' :
                file_name_path = temp_download_folder + "/" +  str(file_name)
                os.system('rm "' + str(file_name_path) +'"')
                file_name_aria = file_name_path + str('.aria2')
                os.system('rm "' + str(file_name_aria) +'"')
        else:
            self.statusbar.showMessage("Please select an item first!")
        remove_flag = 0
        self.selectedRow()

    def propertiesButtonPressed(self,button):
        self.propertiesAction.setEnabled(False)
        selected_row_return = self.selectedRow()
        if selected_row_return != None :
            add_link_dictionary_str = self.download_table.item(selected_row_return , 9).text() 
            add_link_dictionary = ast.literal_eval(add_link_dictionary_str) 
            gid = self.download_table.item(selected_row_return , 8 ).text()
            propertieswindow = PropertiesWindow(self.propertiesCallback ,gid)
            self.propertieswindows_list.append(propertieswindow)
            self.propertieswindows_list[len(self.propertieswindows_list) - 1].show()

    def propertiesCallback(self,add_link_dictionary , gid ):
        download_info_file = download_info_folder + "/" + gid
        download_info_file_list = readList(download_info_file )
        download_info_file_list [9] = add_link_dictionary
        writeList(download_info_file , download_info_file_list)
            
    def progressButtonPressed(self,button):
        selected_row_return = self.selectedRow()
        if selected_row_return != None:
            gid = self.download_table.item(selected_row_return , 8 ).text()
            if gid in self.progress_window_list_dict :
                member_number = self.progress_window_list_dict[gid]
                if self.progress_window_list[member_number].isVisible() == False:
                    self.progress_window_list[member_number].show()
                else :
                    self.progress_window_list[member_number].hide()

    def progressBarOpen(self,gid):
        progress_window = ProgressWindow(parent = self,gid = gid)
        self.progress_window_list.append(progress_window)
        member_number = len(self.progress_window_list) - 1
        self.progress_window_list_dict[gid] = member_number 
        self.progress_window_list[member_number].show()
 
#close event
    def closeEvent(self, event):
        print("Please Wait...")
        self.hide()
        self.system_tray_icon.hide()
        download.shutDown()
        sleep(0.5)
        global shutdown_notification
        shutdown_notification = 1
        while shutdown_notification != 2:
            sleep (0.1)

        QCoreApplication.instance().closeAllWindows()

        QCoreApplication.instance().quit
        print("Persepolis Closed")
        sys.exit(0)

    def showTray(self,menu):
        if self.trayAction.isChecked() == True :
            self.system_tray_icon.show()
            self.minimizeAction.setEnabled(True)
        else:
            self.system_tray_icon.hide()
            self.minimizeAction.setEnabled(False)

    def systemTrayPressed(self,click):
        if click == 3 :
            self.minMaxTray(click)
            

    def minMaxTray(self,menu):
        if self.isVisible() == False:
            self.show()
            self.minimizeAction.setText('Minimize to system tray')
            self.minimizeAction.setIcon(QIcon(icons + 'minimize'))
        

        else :
            self.minimizeAction.setText('Show main Window')
            self.minimizeAction.setIcon(QIcon(icons + 'window'))
            self.hide()

    def showMainWindow(self):
        self.show()
        self.minimizeAction.setText('Minimize to system tray')
        self.minimizeAction.setIcon(QIcon(icons + 'minimize'))
 

    def stopAllDownloads(self,menu):
        active_gids = []
        for i in range(self.download_table.rowCount()):
            try:
                row_status = self.download_table.item(i , 1).text()
                if row_status == 'downloading' or row_status == 'paused' or row_status == 'waiting':
                    row_gid = self.download_table.item(i , 8).text()
                    active_gids.append(row_gid)
            except :
                pass
        for gid in active_gids:
            answer = download.downloadStop(gid)
            if answer == 'None':
                notifySend("Aria2 did not respond!" , "Try agian!" , 10000 , 'critical' , systemtray = self.system_tray_icon )


            sleep(0.3)

           

    def pauseAllDownloads(self,menu):
#get active gid of downloads from aria
        active_gids = download.activeDownloads()
#check that if gid is in download_list_file_active
        f = Open(download_list_file_active)
        download_list_file_active_lines = f.readlines()
        f.close()
        for i in range(len(download_list_file_active_lines)):
            download_list_file_active_lines[i] = download_list_file_active_lines[i].strip()

        for gid in active_gids :
            if gid in download_list_file_active_lines :
                answer = download.downloadPause(gid)
                if answer == 'None':
                    notifySend("Aria2 did not respond!" , "Try agian!" , 10000 , 'critical' , systemtray = self.system_tray_icon )

                sleep(0.3)
            

    def openPreferences(self,menu):
        self.preferenceswindow = PreferencesWindow(self)
        self.preferenceswindow.show()



    def openAbout(self,menu):
        self.about_window = AboutWindow()
        self.about_window.show()


    def openDefaultDownloadFolder(self,menu):
        f = Open(setting_file)
        setting_file_lines = f.readlines()
        f.close()
        setting_dict_str = str(setting_file_lines[0].strip())
        setting_dict = ast.literal_eval(setting_dict_str) 
        download_path = setting_dict ['download_path']
        if os.path.isdir(download_path):
            os.system("xdg-open '" + download_path + "'" )
        else:
            notifySend(str(download_path) ,'Not Found' , 5000 , 'warning' , systemtray = self.system_tray_icon )




    def openDownloadFolder(self,menu):
        selected_row_return = self.selectedRow()
        if selected_row_return != None:
            gid = self.download_table.item(selected_row_return , 8 ).text()
            download_status = self.download_table.item(selected_row_return , 1).text()
            if download_status == 'complete':
                add_link_dictionary_str = self.download_table.item(selected_row_return , 9).text() 
                add_link_dictionary = ast.literal_eval(add_link_dictionary_str) 
                if 'file_path' in add_link_dictionary :
                    file_path = add_link_dictionary ['file_path']
                    file_path_split = file_path.split('/')
                    del file_path_split[-1]
                    download_path = '/'.join(file_path_split)
                    if os.path.isdir(download_path):
                        os.system("xdg-open '" + download_path + "' &" )
                    else:
                        notifySend(str(download_path) ,'Not Found' , 5000 , 'warning' , systemtray = self.system_tray_icon )



    def openFile(self,menu):
        selected_row_return = self.selectedRow()
        if selected_row_return != None:
            gid = self.download_table.item(selected_row_return , 8 ).text()
            download_status = self.download_table.item(selected_row_return , 1).text()
            if download_status == 'complete':
                add_link_dictionary_str = self.download_table.item(selected_row_return , 9).text() 
                add_link_dictionary = ast.literal_eval(add_link_dictionary_str) 
                if 'file_path' in add_link_dictionary:
                    file_path = add_link_dictionary['file_path']
                    if os.path.isfile(file_path):
                        os.system("xdg-open '" + file_path  + "' &" )
                    else:
                        notifySend(str(file_path) ,'Not Found' , 5000 , 'warning' , systemtray = self.system_tray_icon )

    def deleteFile(self,menu):
        selected_row_return = self.selectedRow()
        global remove_flag
        remove_flag = 1
        while remove_flag != 2 :
            sleep(0.1)
#This section is checking the download status , if download was completed then download file is removing
        if selected_row_return != None:
            gid = self.download_table.item(selected_row_return , 8 ).text()
            download_status = self.download_table.item(selected_row_return , 1).text()
            if download_status == 'complete':
                add_link_dictionary_str = self.download_table.item(selected_row_return , 9).text() 
                add_link_dictionary = ast.literal_eval(add_link_dictionary_str) 
                if 'file_path' in add_link_dictionary:
                    file_path = add_link_dictionary['file_path']
                    if os.path.isfile(file_path):
                        os.system("rm '" + file_path  + "'" )
                    else:
                        notifySend(str(file_path) ,'Not Found' , 5000 , 'warning' , systemtray = self.system_tray_icon )
                    remove_flag = 3
                    self.removeButtonPressed(menu)

    def selectDownloads(self,menu):
        if self.selectAction.isChecked() == True:
#selectAllAction is checked >> activating actions and adding removeSelectedAction and deleteSelectedAction to the toolBar
            self.toolBar.clear()
            for i in self.addlinkAction,self.resumeAction, self.pauseAction , self.stopAction, self.removeSelectedAction , self.deleteSelectedAction , self.propertiesAction, self.progressAction , self.exitAction :
                self.toolBar.addAction(i)
         

            self.toolBar.insertSeparator(self.addlinkAction)
            self.toolBar.insertSeparator(self.resumeAction)     
            self.toolBar.insertSeparator(self.removeSelectedAction)
            self.toolBar.insertSeparator(self.exitAction)
            self.toolBar.addSeparator()

            for i in range(self.download_table.rowCount()):
                item = self.download_table.item(i , 0)
                item.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled)
                item.setCheckState(QtCore.Qt.Unchecked)
                self.selectAllAction.setEnabled(True)
                self.removeSelectedAction.setEnabled(True)
                self.deleteSelectedAction.setEnabled(True)
                 
        else:
#selectAction is unchecked deactivate actions and adding removeAction and deleteFileAction to the toolBar
            self.toolBar.clear()
            for i in self.addlinkAction,self.resumeAction, self.pauseAction , self.stopAction, self.removeAction , self.deleteFileAction , self.propertiesAction, self.progressAction , self.exitAction :
                self.toolBar.addAction(i)
         

            self.toolBar.insertSeparator(self.addlinkAction)
            self.toolBar.insertSeparator(self.resumeAction)     
            self.toolBar.insertSeparator(self.removeSelectedAction)
            self.toolBar.insertSeparator(self.exitAction)
            self.toolBar.addSeparator()
 
            for i in range(self.download_table.rowCount()):
                item_text = self.download_table.item(i , 0).text()
                item = QTableWidgetItem(item_text) 
                self.download_table.setItem(i , 0 , item)
                self.selectAllAction.setEnabled(False)
                self.removeSelectedAction.setEnabled(False)
                self.deleteSelectedAction.setEnabled(False)
                


    def selectAll(self,menu):
        for i in range(self.download_table.rowCount()):
            item = self.download_table.item(i , 0)
            item.setCheckState(QtCore.Qt.Checked)
 
    def removeSelected(self,menu):
        global remove_flag
        remove_flag = 1
        while remove_flag != 2 :
            sleep(0.1)

        gid_list = []
        for row in range(self.download_table.rowCount()):
            status = self.download_table.item(row , 1).text() 
            item = self.download_table.item(row , 0)
            if (item.checkState() == 2) and (status == 'complete' or status == 'error' or status == 'stopped' ):
                gid = self.download_table.item(row , 8 ).text()
                gid_list.append(gid)


        for gid in gid_list:        
            for i in range(self.download_table.rowCount()):
                row_gid = self.download_table.item(i , 8).text()
                if gid == row_gid :
                    row = i 
                    break

           
            file_name = self.download_table.item(row , 0).text()
            sleep(0.5)
            self.download_table.removeRow(row)

#remove gid of download from download list file
            f = Open(download_list_file)
            download_list_file_lines = f.readlines()
            f.close()
            f = Open(download_list_file , "w")
            for i in download_list_file_lines:
                if i.strip() != gid:
                    f.writelines(i.strip() + "\n")
            f.close()
#remove gid of download from active download list file
            f = Open(download_list_file_active)
            download_list_file_active_lines = f.readlines()
            f.close()
            f = Open(download_list_file_active , "w")
            for i in download_list_file_active_lines:
                if i.strip() != gid:
                    f.writelines(i.strip() + "\n")
            f.close()
#remove download_info_file
            download_info_file = download_info_folder + "/" + gid
            f = Open(download_info_file)
            f.close()
            f.remove()
#remove file of download form download temp folder
            if file_name != '***' and status != 'complete' :
                file_name_path = temp_download_folder + "/" +  str(file_name)
                os.system('rm "' + str(file_name_path) +'"')
                file_name_aria = file_name_path + str('.aria2')
                os.system('rm "' + str(file_name_aria) +'"')

        remove_flag = 0

    def deleteSelected(self,menu):
        global remove_flag
        remove_flag = 1
        while remove_flag != 2 :
            sleep(0.1)

        gid_list = []
        for row in range(self.download_table.rowCount()):
            status = self.download_table.item(row , 1).text() 
            item = self.download_table.item(row , 0)
            if (item.checkState() == 2) and (status == 'complete' or status == 'error' or status == 'stopped' ):
                gid = self.download_table.item(row , 8 ).text()
                gid_list.append(gid)


        for gid in gid_list:        
            for i in range(self.download_table.rowCount()):
                row_gid = self.download_table.item(i , 8).text()
                if gid == row_gid :
                    row = i 
                    break
            file_name = self.download_table.item(row , 0).text()
            add_link_dictionary_str = self.download_table.item(row , 9).text() 
            add_link_dictionary = ast.literal_eval(add_link_dictionary_str) 


            sleep(0.5)
            self.download_table.removeRow(row)
#remove gid of download from download list file
            f = Open(download_list_file)
            download_list_file_lines = f.readlines()
            f.close()
            f = Open(download_list_file , "w")
            for i in download_list_file_lines:
                if i.strip() != gid:
                    f.writelines(i.strip() + "\n")
            f.close()
#remove gid of download from active download list file
            f = Open(download_list_file_active)
            download_list_file_active_lines = f.readlines()
            f.close()
            f = Open(download_list_file_active , "w")
            for i in download_list_file_active_lines:
                if i.strip() != gid:
                    f.writelines(i.strip() + "\n")
            f.close()


#remove download_info_file
            download_info_file = download_info_folder + "/" + gid
            f = Open(download_info_file)
            f.close()
            f.remove()

#remove file of download form download temp folder
            if file_name != '***' and status != 'complete' :
                file_name_path = temp_download_folder + "/" +  str(file_name)
                os.system('rm "' + str(file_name_path) +'"')
                file_name_aria = file_name_path + str('.aria2')
                os.system('rm "' + str(file_name_aria) +'"')

#remove download file
            if status == 'complete':
                if 'file_path' in add_link_dictionary:
                    file_path = add_link_dictionary['file_path']
                    if os.path.isfile(file_path):
                        os.system("rm '" + file_path  + "'" )
                    else:
                        notifySend(str(file_path) ,'Not Found' , 5000 , 'warning' , systemtray = self.system_tray_icon )

        remove_flag = 0
Beispiel #3
0
class MainWindow(MainWindow_Ui):
    def __init__(self):
        super().__init__()
        self.statusbar.showMessage('Please Wait ...')

#threads     
        self.threadPool=[]
#starting aria
        start_aria = StartAria2Thread()
        self.threadPool.append(start_aria)
        self.threadPool[0].start() 
        self.threadPool[0].ARIA2RESPONDSIGNAL.connect(self.startAriaMessage)

#initializing    

#add downloads to the download_table
        f_download_list_file = Open(download_list_file)
        download_list_file_lines = f_download_list_file.readlines()
        f_download_list_file.close()
            
        for line in download_list_file_lines:
            gid = line.strip()
            self.download_table.insertRow(0)
            download_info_file = download_info_folder + "/" + gid
            f = Open(download_info_file)
            download_info_file_lines = f.readlines()
            f.close()
            for i in range(10):
                item = QTableWidgetItem(download_info_file_lines[i].strip())
                self.download_table.setItem(0 , i , item)

        row_numbers = self.download_table.rowCount()
        for row in range(row_numbers):
            status = self.download_table.item(row , 1).text() 
            if (status != "complete" and status != "error"):
                gid = self.download_table.item(row,8).text() 
                add_link_dictionary_str = self.download_table.item(row,9).text() 
                add_link_dictionary = ast.literal_eval(add_link_dictionary_str.strip()) 
                add_link_dictionary['start_hour'] = None
                add_link_dictionary['start_minute'] = None
                add_link_dictionary['end_hour'] = None
                add_link_dictionary['end_minute'] = None
                add_link_dictionary['after_download'] = 'None'

                download_info_file = download_info_folder + "/" + gid
                f = Open(download_info_file)
                download_info_file_lines = f.readlines()
                f.close()

                f = Open(download_info_file , "w")
                for i in range(10):
                    if i == 1 :
                        f.writelines("stopped" + "\n")
                        item = QTableWidgetItem('stopped')
                        self.download_table.setItem(row , i , item )
                    elif i == 9 :
                        f.writelines(str(add_link_dictionary) + "\n")
                        item = QTableWidgetItem(str(add_link_dictionary))
                        self.download_table.setItem(row,i , item)
                    else:
                        f.writelines(download_info_file_lines[i].strip() + "\n")

                f.close()
        self.addlinkwindows_list = []
        self.propertieswindows_list = []
        self.progress_window_list = []
        self.progress_window_list_dict = {}

        check_download_info = CheckDownloadInfoThread()
        self.threadPool.append(check_download_info)
        self.threadPool[1].start()
        self.threadPool[1].DOWNLOAD_INFO_SIGNAL.connect(self.checkDownloadInfo)

        check_selected_row = CheckSelectedRowThread()
        self.threadPool.append(check_selected_row)
        self.threadPool[2].start()
        self.threadPool[2].CHECKSELECTEDROWSIGNAL.connect(self.checkSelectedRow)

        check_flashgot = CheckFlashgot()
        self.threadPool.append(check_flashgot)
        self.threadPool[3].start()
        self.threadPool[3].CHECKFLASHGOTSIGNAL.connect(self.checkFlashgot)

        

 

        self.system_tray_icon = QSystemTrayIcon() 
        self.system_tray_icon.setIcon(QIcon('icon'))
        system_tray_menu = QMenu()
        system_tray_menu.addAction(self.addlinkAction)
        system_tray_menu.addAction(self.pauseAllAction)
        system_tray_menu.addAction(self.stopAllAction)
        system_tray_menu.addAction(self.minimizeAction)
        system_tray_menu.addAction(self.exitAction)
        self.system_tray_icon.setContextMenu(system_tray_menu)
        self.system_tray_icon.activated.connect(self.systemTrayPressed)
        self.system_tray_icon.show()

    def startAriaMessage(self,message):
        global aria_startup_answer
        if message == 'yes':
            sleep (2)
            self.statusbar.showMessage('Ready...')
            aria_startup_answer = 'ready'
        else:
            self.statusbar.showMessage('Error...')
            notifySend('Persepolis can not connect to Aria2' , 'Restart Persepolis' ,10000,'critical' )

    def checkDownloadInfo(self,gid):
        try:
#get download information from download_info_file according to gid and write them in download_table cells
            download_info_file = config_folder + "/download_info/" + gid
            f = Open(download_info_file)
            download_info_file_lines = f.readlines()
            f.close()
#finding row of this gid!
            for i in range(self.download_table.rowCount()):
                row_gid = self.download_table.item(i , 8).text()
                if gid == row_gid :
                    row = i 
                    break

            for i in range(10):
#remove gid of completed download from active downloads list file
                if i == 1 :
                    status = download_info_file_lines[i].strip()
                    status = str(status)
                    status_download_table = str(self.download_table.item(row , 1 ) . text())

                    if status == "complete":
                        f = Open(download_list_file_active)
                        download_list_file_active_lines = f.readlines()
                        f.close()
                        f = Open(download_list_file_active , "w")
                        for line in download_list_file_active_lines :
                            if line.strip() != gid :
                                f.writelines(line.strip() + "\n")
                        f.close()
                    
#update download_table cells
                item = QTableWidgetItem(download_info_file_lines[i].strip())
                self.download_table.setItem(row , i , item)
                self.download_table.viewport().update()
#update progresswindow
            try :
            
                member_number = self.progress_window_list_dict[gid]
                progress_window = self.progress_window_list[member_number]
                #link
                add_link_dictionary_str = str(download_info_file_lines[9].strip())
                add_link_dictionary = ast.literal_eval(add_link_dictionary_str) 
                link = "<b>Link</b> : " +  str(add_link_dictionary ['link'])
                progress_window.link_label.setText(link)
                progress_window.setToolTip(link)

                #Save as
                final_download_path = add_link_dictionary['final_download_path']
                if final_download_path == None :
                    final_download_path = str(add_link_dictionary['download_path'])
                        
                save_as = "<b>Save as</b> : " + final_download_path + "/" + str(download_info_file_lines[0].strip())
                progress_window.save_label.setText(save_as)
                file_name = str(download_info_file_lines[0].strip())
                if file_name != "***":
                    progress_window.setWindowTitle(file_name ) 

                #status
                progress_window.status = download_info_file_lines[1].strip()
                status = "<b>status</b> : " + progress_window.status 
                progress_window.status_label.setText(status)
                if progress_window.status == "downloading":
                    progress_window.resume_pushButton.setEnabled(False)
                    progress_window.stop_pushButton.setEnabled(True)
                    progress_window.pause_pushButton.setEnabled(True)
                elif progress_window.status == "paused":
                    progress_window.resume_pushButton.setEnabled(True)
                    progress_window.stop_pushButton.setEnabled(True)
                    progress_window.pause_pushButton.setEnabled(False)
                elif progress_window.status == "waiting":
                    progress_window.resume_pushButton.setEnabled(False)
                    progress_window.stop_pushButton.setEnabled(False)
                    progress_window.pause_pushButton.setEnabled(False)
                elif progress_window.status == "scheduled":
                    progress_window.resume_pushButton.setEnabled(False)
                    progress_window.stop_pushButton.setEnabled(True)
                    progress_window.pause_pushButton.setEnabled(False)
                elif progress_window.status == "stopped" or progress_window.status == "error" or progress_window.status == "complete" :
                    progress_window.close()
                    self.progress_window_list[member_number] = []
                    del self.progress_window_list_dict[gid]
                    if progress_window.status == "complete":
                        notifySend("Download Complete" ,str(download_info_file_lines[0])  , 10000 , 'ok' )
                    elif progress_window.status == "stopped":
                        notifySend("Download Stopped" , str(download_info_file_lines[0]) , 10000 , 'no')

                    elif progress_window.status == "error":
                        notifySend("Download Error" , str(download_info_file_lines[0]) , 10000 , 'fail')
               
                        add_link_dictionary['start_hour'] = None
                        add_link_dictionary['start_minute'] = None
                        add_link_dictionary['end_hour'] = None
                        add_link_dictionary['end_minute'] = None
                        add_link_dictionary['after_download'] = 'None'

                        f = Open(download_info_file , "w")
                        for i in range(10):
                            if i == 9 :
                                f.writelines(str(add_link_dictionary) + "\n")
                            else:
                                f.writelines(download_info_file_lines[i].strip() + "\n")

                        f.close()
                    
                    if os.path.isfile('/tmp/persepolis/shutdown/' + gid ) == True and progress_window.status != 'stopped':
                        answer = download.shutDown()
                        if answer == 'error':
                            os.system('killall aria2c')
                        f = Open('/tmp/persepolis/shutdown/' + gid , 'w')
                        f.writelines('shutdown')
                        f.close()
                    elif os.path.isfile('/tmp/persepolis/shutdown/' + gid ) == True and progress_window.status == 'stopped':
                        f = Open('/tmp/persepolis/shutdown/' + gid , 'w')
                        f.writelines('canceled')
                        f.close()



             
                #downloaded
                downloaded = "<b>Downloaded</b> : " + str(download_info_file_lines[3].strip()) + "/" + str(download_info_file_lines[2].strip())
                progress_window.downloaded_label.setText(downloaded)

                #Transfer rate
                rate = "<b>Transfer rate</b> : " + str(download_info_file_lines[6].strip())
                progress_window.rate_label.setText(rate)

                #Estimate time left
                estimate_time_left = "<b>Estimate time left</b> : " + str(download_info_file_lines[7].strip()) 
                progress_window.time_label.setText(estimate_time_left)

                #Connections
                connections = "<b>Connections</b> : " + str(download_info_file_lines[5].strip())
                progress_window.connections_label.setText(connections)


                #progressbar
                value = download_info_file_lines[4].strip()
                value = value[:-1]
                progress_window.download_progressBar.setValue(int(value))
            except :
                pass
        except:
            pass
                   



#contex menu
    def contextMenuEvent(self, event):
        self.tablewidget_menu = QMenu(self)
        self.tablewidget_menu.addAction(self.resumeAction)
        self.tablewidget_menu.addAction(self.pauseAction)
        self.tablewidget_menu.addAction(self.stopAction)
        self.tablewidget_menu.addAction(self.removeAction)
        self.tablewidget_menu.addAction(self.propertiesAction)
        self.tablewidget_menu.addAction(self.progressAction)
        self.tablewidget_menu.popup(QtGui.QCursor.pos())
#drag and drop for links
    def dragEnterEvent(self, droplink):

        text = str(droplink.mimeData().text())
      
        if ("tp:/" in text[2:6]) or ("tps:/" in text[2:7]) :
            droplink.accept()
        else:
            droplink.ignore() 

    def dropEvent(self, droplink):
        link_clipborad = QApplication.clipboard()
        link_clipborad.clear(mode=link_clipborad.Clipboard )
        link_string = droplink.mimeData().text() 
        link_clipborad.setText(str(link_string), mode=link_clipborad.Clipboard) 
        self.addLinkButtonPressed(button =link_clipborad )
    
	
    def gidGenerator(self):
        my_gid = hex(random.randint(1152921504606846976,18446744073709551615))
        my_gid = my_gid[2:18]
        my_gid = str(my_gid)
        f = Open(download_list_file_active)
        active_gid_list = f.readlines()
        f.close()
        while my_gid in active_gid_list :
            my_gid = self.gidGenerator()
        active_gids = download.activeDownloads()
        while my_gid in active_gids:
            my_gid = self.gidGenerator()
        
        return my_gid

    def selectedRow(self):
        try:
            item = self.download_table.selectedItems()
            selected_row_return = self.download_table.row(item[1]) 
            download_info = self.download_table.item(selected_row_return , 9).text()
            download_info = ast.literal_eval(download_info) 
            link = download_info['link']
            self.statusbar.showMessage(str(link))

        except :
            selected_row_return = None

        return selected_row_return 

    def checkSelectedRow(self):
        try:
            item = self.download_table.selectedItems()
            selected_row_return = self.download_table.row(item[1]) 
        except :
            selected_row_return = None

        if selected_row_return != None :
            status = self.download_table.item(selected_row_return , 1).text() 
            if status == "scheduled":
                self.resumeAction.setEnabled(False)
                self.pauseAction.setEnabled(False)
                self.stopAction.setEnabled(True)
                self.removeAction.setEnabled(False)
                self.propertiesAction.setEnabled(False)
                self.progressAction.setEnabled(True)
            elif status == "stopped" or status == "error" :
                self.stopAction.setEnabled(False)
                self.pauseAction.setEnabled(False)
                self.resumeAction.setEnabled(True)
                self.removeAction.setEnabled(True)
                self.propertiesAction.setEnabled(True)
                self.progressAction.setEnabled(False)
            elif status == "downloading":
                self.resumeAction.setEnabled(False)
                self.pauseAction.setEnabled(True)
                self.stopAction.setEnabled(True)
                self.removeAction.setEnabled(False)
                self.propertiesAction.setEnabled(False)
                self.progressAction.setEnabled(True)
            elif status == "waiting": 
                self.stopAction.setEnabled(False)
                self.resumeAction.setEnabled(False)
                self.pauseAction.setEnabled(False)
                self.removeAction.setEnabled(False)
                self.propertiesAction.setEnabled(False)
                self.progressAction.setEnabled(True)
            elif status == "complete":
                self.stopAction.setEnabled(False)
                self.resumeAction.setEnabled(False)
                self.pauseAction.setEnabled(False)
                self.removeAction.setEnabled(True)
                self.propertiesAction.setEnabled(True)
                self.progressAction.setEnabled(False)
            elif status == "paused":
                self.stopAction.setEnabled(True)
                self.resumeAction.setEnabled(True)
                self.pauseAction.setEnabled(False)
                self.removeAction.setEnabled(False)
                self.propertiesAction.setEnabled(False)
                self.progressAction.setEnabled(True)
                
 
            else:
                self.resumeAction.setEnabled(True)
                self.stopAction.setEnabled(True)
                self.pauseAction.setEnabled(True)
                self.propertiesAction.setEnabled(True)
        else:
            self.resumeAction.setEnabled(True)
            self.stopAction.setEnabled(True)
            self.pauseAction.setEnabled(True)
            self.removeAction.setEnabled(True)
            self.propertiesAction.setEnabled(True)

           
    def checkFlashgot(self):
        sleep(0.5)
        flashgot_file = Open("/tmp/persepolis-flashgot")
        flashgot_line = flashgot_file.readlines()
        flashgot_file.close()
        flashgot_file.remove()
        flashgot_add_link_dictionary_str = flashgot_line[0]
        flashgot_add_link_dictionary = ast.literal_eval(flashgot_add_link_dictionary_str) 
        self.flashgotAddLink(flashgot_add_link_dictionary)


    def flashgotAddLink(self,flashgot_add_link_dictionary):
        addlinkwindow = AddLinkWindow(self.callBack , flashgot_add_link_dictionary)
        self.addlinkwindows_list.append(addlinkwindow)
        self.addlinkwindows_list[len(self.addlinkwindows_list) - 1].show()

       
            



    def addLinkButtonPressed(self ,button):
        addlinkwindow = AddLinkWindow(self.callBack)
        self.addlinkwindows_list.append(addlinkwindow)
        self.addlinkwindows_list[len(self.addlinkwindows_list) - 1].show()

    def callBack(self , add_link_dictionary):
        gid = self.gidGenerator()

        download_info_file_list = ['***','waiting','***','***','***','***','***','***',gid , str(add_link_dictionary)]
        download_info_file = config_folder + "/download_info/" + gid
        os.system("touch " + download_info_file )
        f = Open(download_info_file , "w")
        for i in range(10):
            f.writelines(download_info_file_list[i] + "\n")

        f.close()
        
        self.download_table.insertRow(0)
        j = 0
        for i in download_info_file_list :
            item = QTableWidgetItem(i)
            self.download_table.setItem(0,j,item)
            j = j + 1

        f = Open (download_list_file , "a")
        f.writelines(gid + "\n")
        f.close()


        f = Open (download_list_file_active , "a")
        f.writelines(gid + "\n")
        f.close()
        new_download = DownloadLink(gid)
        self.threadPool.append(new_download)
        self.threadPool[len(self.threadPool) - 1].start()
        self.progressBarOpen(gid) 
        if add_link_dictionary['start_hour'] == None :
            message = "Download Starts"
        else:
            message = "Download Scheduled"
        notifySend(message ,'' , 10000 , 'no')

 

        
    def resumeButtonPressed(self,button):
        selected_row_return = self.selectedRow()
        if selected_row_return != None:
            gid = self.download_table.item(selected_row_return , 8 ).text()
            download_status = self.download_table.item(selected_row_return , 1).text()
 
                
            if download_status == "paused" :
                answer = download.downloadUnpause(gid)
                if answer == 'None':
                    notifySend("Aria2 did not respond!","Try agian!",10000,'warning' )



            else:
                new_download = DownloadLink(gid)
                self.threadPool.append(new_download)
                self.threadPool[len(self.threadPool) - 1].start()
                sleep(1)
                self.progressBarOpen(gid)



        else:
            self.statusbar.showMessage("Please select an item first!")


    def stopButtonPressed(self,button):
        selected_row_return = self.selectedRow()
        if selected_row_return != None:
            gid = self.download_table.item(selected_row_return , 8 ).text()
            answer = download.downloadStop(gid)
            if answer == 'None':
                notifySend("Aria2 did not respond!","Try agian!" , 10000 , 'critical' )



           
               
        else:
            self.statusbar.showMessage("Please select an item first!")

    def pauseButtonPressed(self,button):
        selected_row_return = self.selectedRow()
        if selected_row_return != None:
            gid = self.download_table.item(selected_row_return , 8 ).text()
            answer = download.downloadPause(gid)
            if answer == 'None':
                notifySend("Aria2 did not respond!" , "Try agian!" , 10000 , 'critical' )

        else:
            self.statusbar.showMessage("Please select an item first!")
        sleep(1)

    def removeButtonPressed(self,button):
        self.removeAction.setEnabled(False)
        selected_row_return = self.selectedRow()
        if selected_row_return != None:
            gid = self.download_table.item(selected_row_return , 8 ).text()
            try:
                file_name = self.download_table.item(selected_row_return , 0).text()
            except:
                file_name = None 
            sleep(0.5)
            self.download_table.removeRow(selected_row_return)

#remove gid of download from download list file
            f = Open(download_list_file)
            download_list_file_lines = f.readlines()
            f.close()
            f = Open(download_list_file , "w")
            for i in download_list_file_lines:
                if i.strip() != gid:
                    f.writelines(i.strip() + "\n")
            f.close()
#remove gid of download from active download list file
            f = Open(download_list_file_active)
            download_list_file_active_lines = f.readlines()
            f.close()
            f = Open(download_list_file_active , "w")
            for i in download_list_file_active_lines:
                if i.strip() != gid:
                    f.writelines(i.strip() + "\n")
            f.close()
#remove download_info_file
            download_info_file = download_info_folder + "/" + gid
            f = Open(download_info_file)
            f.close()
            f.remove()
#remove file of download form download temp folder
            if file_name != None :
                file_name_path = temp_download_folder + "/" +  str(file_name)
                os.system('rm "' + str(file_name_path) +'"')
                file_name_aria = file_name_path + str('.aria2')
                os.system('rm "' + str(file_name_aria) +'"')
        else:
            self.statusbar.showMessage("Please select an item first!")
        self.selectedRow()

    def propertiesButtonPressed(self,button):
        selected_row_return = self.selectedRow()
        if selected_row_return != None :
            add_link_dictionary_str = self.download_table.item(selected_row_return , 9).text() 
            add_link_dictionary = ast.literal_eval(add_link_dictionary_str) 
            gid = self.download_table.item(selected_row_return , 8 ).text()
            propertieswindow = PropertiesWindow(self.propertiesCallback ,gid)
            self.propertieswindows_list.append(propertieswindow)
            self.propertieswindows_list[len(self.propertieswindows_list) - 1].show()

    def propertiesCallback(self,add_link_dictionary , gid ):
        download_info_file = download_info_folder + "/" + gid
        f = Open(download_info_file)
        download_info_file_lines = f.readlines()
        f.close()
        f = Open(download_info_file , "w")
        for i in range(10):
            if i == 9 :
                f.writelines(str(add_link_dictionary) + "\n")
            else:
                f.writelines(download_info_file_lines[i].strip() + "\n")

        f.close()
            
    def progressButtonPressed(self,button):
        selected_row_return = self.selectedRow()
        if selected_row_return != None:
            gid = self.download_table.item(selected_row_return , 8 ).text()
            member_number = self.progress_window_list_dict[gid]
            if self.progress_window_list[member_number].isVisible() == False:
                self.progress_window_list[member_number].show()
            else :
                self.progress_window_list[member_number].hide()

    def progressBarOpen(self,gid):
            progress_window = ProgressWindow(gid)
            self.progress_window_list.append(progress_window)
            member_number = len(self.progress_window_list) - 1
            self.progress_window_list_dict[gid] = member_number 
            self.progress_window_list[member_number].show()
 

#close event
    def closeEvent(self, event):
        self.hide()
        self.system_tray_icon.hide()
        download.shutDown()
        sleep(0.5)
        global shutdown_notification
        shutdown_notification = 1
        while shutdown_notification != 2:
            sleep (0.1)

        QCoreApplication.instance().closeAllWindows()
        for qthread in self.threadPool :
            try:
                qthread.exit(0)
                sleep(0.1)
                answer = qthread.isRunning()
                print(answer)
            except:
                print("not quit")


        QCoreApplication.instance().quit
        print("Persepolis Closed")

    def systemTrayPressed(self,click):
        if click == 3 :
            self.minMaxTray(click)
            

    def minMaxTray(self,menu):
        if self.isVisible() == False:
            self.minimizeAction.setText('Minimize to system tray')
            self.minimizeAction.setIcon(QIcon(icons + 'minimize'))
            self.show()

        else :
            self.hide()
            self.minimizeAction.setText('Show main Window')
            self.minimizeAction.setIcon(QIcon(icons + 'window'))

    def stopAllDownloads(self,menu):
        active_gids = []
        for i in range(self.download_table.rowCount()):
            try:
                row_status = self.download_table.item(i , 1).text()
                if row_status == 'downloading' or row_status == 'paused' or row_status == 'waiting':
                    row_gid = self.download_table.item(i , 8).text()
                    active_gids.append(row_gid)
            except :
                pass
        for gid in active_gids:
            answer = download.downloadStop(gid)
            if answer == 'None':
                notifySend("Aria2 did not respond!" , "Try agian!" , 10000 , 'critical' )


            sleep(0.3)

           

    def pauseAllDownloads(self,menu):
#get active gid of downloads from aria
        active_gids = download.activeDownloads()
#check that if gid is in download_list_file_active
        f = Open(download_list_file_active)
        download_list_file_active_lines = f.readlines()
        f.close()
        for i in range(len(download_list_file_active_lines)):
            download_list_file_active_lines[i] = download_list_file_active_lines[i].strip()

        for gid in active_gids :
            if gid in download_list_file_active_lines :
                answer = download.downloadPause(gid)
                if answer == 'None':
                    notifySend("Aria2 did not respond!" , "Try agian!" , 10000 , 'critical' )

                sleep(0.3)
            

    def openPreferences(self,menu):
        self.preferenceswindow = PreferencesWindow()
        self.preferenceswindow.show()


    def openAbout(self,menu):
        self.about_window = AboutWindow()
        self.about_window.show()
Beispiel #4
0
class RootPainter(QtWidgets.QMainWindow):

    closed = QtCore.pyqtSignal()

    def __init__(self, sync_dir):
        super().__init__()
        self.sync_dir = sync_dir
        self.instruction_dir = sync_dir / 'instructions'
        self.send_instruction = partial(send_instruction,
                                        instruction_dir=self.instruction_dir,
                                        sync_dir=sync_dir)
        self.tracking = False
        self.image_pixmap_holder = None
        self.seg_pixmap_holder = None
        self.annot_pixmap_holder = None

        self.image_visible = True
        self.seg_visible = False
        self.annot_visible = True
        self.pre_segment_count = 0
        self.im_width = None
        self.im_height = None

        self.initUI()

    def mouse_scroll(self, event):
        scroll_up = event.angleDelta().y() > 0
        modifiers = QtWidgets.QApplication.keyboardModifiers()
        alt_down = (modifiers & QtCore.Qt.AltModifier)
        shift_down = (modifiers & QtCore.Qt.ShiftModifier)

        if alt_down or shift_down:
            # change by 10% (nearest int) or 1 (min)
            increment = max(1, int(round(self.scene.brush_size / 10)))
            if scroll_up:
                self.scene.brush_size += increment
            else:
                self.scene.brush_size -= increment
            self.scene.brush_size = max(1, self.scene.brush_size)
            self.update_cursor()
        else:
            if scroll_up:
                self.graphics_view.zoom *= 1.1
            else:
                self.graphics_view.zoom /= 1.1
            self.graphics_view.update_zoom()

    def initUI(self):
        if len(sys.argv) < 2:
            self.init_missing_project_ui()
            return

        fname = sys.argv[1]
        if os.path.splitext(fname)[1] == '.seg_proj':
            proj_file_path = os.path.abspath(sys.argv[1])
            self.open_project(proj_file_path)
        else:
            # only warn if -psn not in the args. -psn is in the args when
            # user opened app in a normal way by clicking on the Application icon.
            if not '-psn' in sys.argv[1]:
                QtWidgets.QMessageBox.about(
                    self, 'Error', sys.argv[1] + ' is not a valid '
                    'segmentation project (.seg_proj) file')
            self.init_missing_project_ui()

    def open_project(self, proj_file_path):
        # extract json
        with open(proj_file_path, 'r') as json_file:
            settings = json.load(json_file)
            self.dataset_dir = self.sync_dir / 'datasets' / PurePath(
                settings['dataset'])

            self.proj_location = self.sync_dir / PurePath(settings['location'])
            self.image_fnames = settings['file_names']
            self.seg_dir = self.proj_location / 'segmentations'
            self.log_dir = self.proj_location / 'logs'
            self.train_annot_dir = self.proj_location / 'annotations' / 'train'
            self.val_annot_dir = self.proj_location / 'annotations' / 'val'

            self.model_dir = self.proj_location / 'models'

            self.message_dir = self.proj_location / 'messages'

            self.proj_file_path = proj_file_path

            # If there are any annotations which have already been saved
            # then go through the annotations in the order specified
            # by self.image_fnames
            # and set fname (current image) to be the last image with annotation
            last_with_annot = last_fname_with_annotations(
                self.image_fnames, self.train_annot_dir, self.val_annot_dir)
            if last_with_annot:
                fname = last_with_annot
            else:
                fname = self.image_fnames[0]

            # manual override for the image to show
            if 'image_index' in settings:
                fname = self.image_fnames[settings['image_index']]

            # set first image from project to be current image
            self.image_path = os.path.join(self.dataset_dir, fname)
            self.update_window_title()
            self.seg_path = os.path.join(self.seg_dir, fname)
            self.annot_path = get_annot_path(fname, self.train_annot_dir,
                                             self.val_annot_dir)
            self.init_active_project_ui()
            self.track_changes()

    def update_file(self, fpath):
        # Save current annotation (if it exists) before moving on
        self.save_annotation()

        # save current annotation first
        fname = os.path.basename(fpath)
        # set first image from project to be current image
        self.image_path = os.path.join(self.dataset_dir, fname)
        self.png_fname = os.path.splitext(fname)[0] + '.png'
        self.seg_path = os.path.join(self.seg_dir, self.png_fname)
        self.annot_path = get_annot_path(self.png_fname, self.train_annot_dir,
                                         self.val_annot_dir)
        self.update_image()

        self.scene.history = []
        self.scene.redo_list = []

        self.update_seg()
        self.update_annot()

        self.segment_current_image()
        self.update_window_title()

    def update_image(self):
        # Will also update self.im_width and self.im_height
        assert os.path.isfile(
            self.image_path), f"Cannot find file {self.image_path}"
        image_pixmap = QtGui.QPixmap(self.image_path)
        im_size = image_pixmap.size()
        im_width, im_height = im_size.width(), im_size.height()
        assert im_width > 0, self.image_path
        assert im_height > 0, self.image_path
        self.graphics_view.image = image_pixmap  # for resize later
        self.im_width = im_width
        self.im_height = im_height

        self.scene.setSceneRect(-15, -15, im_width + 30, im_height + 30)

        # Used to replace the segmentation or annotation when they are not visible.
        self.blank_pixmap = QtGui.QPixmap(self.im_width, self.im_height)
        self.blank_pixmap.fill(Qt.transparent)

        self.black_pixmap = QtGui.QPixmap(self.im_width, self.im_height)
        self.black_pixmap.fill(Qt.black)

        if self.image_pixmap_holder:
            self.image_pixmap_holder.setPixmap(image_pixmap)
        else:
            self.image_pixmap_holder = self.scene.addPixmap(image_pixmap)
        if not self.image_visible:
            self.image_pixmap_holder.setPixmap(self.black_pixmap)

    def update_seg(self):
        # if seg file is present then load.
        if os.path.isfile(self.seg_path):
            self.seg_mtime = os.path.getmtime(self.seg_path)
            self.seg_pixmap = QtGui.QPixmap(self.seg_path)
            self.nav.next_image_button.setText('Save && Next >')
            if hasattr(self, 'vis_widget'):
                self.vis_widget.seg_checkbox.setText('Segmentation (S)')
            self.nav.next_image_button.setEnabled(True)
        else:
            self.seg_mtime = None
            # otherwise use blank
            self.seg_pixmap = QtGui.QPixmap(self.im_width, self.im_height)
            self.seg_pixmap.fill(Qt.transparent)
            painter = QtGui.QPainter()
            painter.begin(self.seg_pixmap)
            font = QtGui.QFont()
            font.setPointSize(48)
            painter.setFont(font)
            painter.setPen(QtGui.QPen(QtGui.QColor(255, 255, 255)))
            painter.setBrush(
                QtGui.QBrush(QtGui.QColor(255, 255, 255), Qt.SolidPattern))
            if sys.platform == 'win32':
                # For some reason the text has a different size
                # and position on windows
                # so change the background rectangle also.
                painter.drawRect(0, 0, 657, 75)
            else:
                painter.drawRect(10, 10, 465, 55)
            painter.setPen(QtGui.QPen(QtGui.QColor(0, 0, 0, 150)))
            painter.drawText(16, 51, 'Loading segmentation')
            painter.end()
            self.nav.next_image_button.setText('Loading Segmentation...')
            if hasattr(self, 'vis_widget'):
                self.vis_widget.seg_checkbox.setText('Segmentation (Loading)')
            self.nav.next_image_button.setEnabled(False)

        if self.seg_pixmap_holder:
            self.seg_pixmap_holder.setPixmap(self.seg_pixmap)
        else:
            self.seg_pixmap_holder = self.scene.addPixmap(self.seg_pixmap)
        if not self.seg_visible:
            self.seg_pixmap_holder.setPixmap(self.blank_pixmap)

    def update_annot(self):
        # if annot file is present then load
        if self.annot_path and os.path.isfile(self.annot_path):
            self.annot_pixmap = QtGui.QPixmap(self.annot_path)
        else:
            # otherwise use blank
            self.annot_pixmap = QtGui.QPixmap(self.im_width, self.im_height)
            self.annot_pixmap.fill(Qt.transparent)
        if self.annot_pixmap_holder:
            self.annot_pixmap_holder.setPixmap(self.annot_pixmap)
        else:
            self.annot_pixmap_holder = self.scene.addPixmap(self.annot_pixmap)
        self.scene.annot_pixmap_holder = self.annot_pixmap_holder
        self.scene.annot_pixmap = self.annot_pixmap
        self.scene.history.append(self.scene.annot_pixmap.copy())

        if not self.annot_visible:
            self.annot_pixmap_holder.setPixmap(self.blank_pixmap)

    def segment_image(self, image_fnames):
        # send instruction to segment the new image.
        content = {
            "dataset_dir": self.dataset_dir,
            "seg_dir": self.seg_dir,
            "file_names": image_fnames,
            "message_dir": self.message_dir,
            "model_dir": self.model_dir
        }
        self.send_instruction('segment', content)

    def segment_current_image(self):
        dir_path, _ = os.path.split(self.image_path)
        path_list = self.nav.get_path_list(dir_path)
        cur_index = path_list.index(self.image_path)
        to_segment_paths = path_list[cur_index:1 + cur_index +
                                     self.pre_segment_count]
        to_segment_paths = [
            f for f in to_segment_paths
            if os.path.isfile(os.path.join(self.seg_dir, f))
        ]
        to_segment_fnames = [os.path.basename(p) for p in to_segment_paths]
        self.segment_image(to_segment_fnames)

    def show_open_project_widget(self):
        options = QtWidgets.QFileDialog.Options()
        default_loc = self.sync_dir / 'projects'
        file_path, _ = QtWidgets.QFileDialog.getOpenFileName(
            self,
            "Load project file",
            str(default_loc),
            "Segmentation project file (*.seg_proj)",
            options=options)

        if file_path:
            self.open_project(file_path)

    def show_create_project_widget(self):
        print("Open the create project widget..")
        self.create_project_widget = CreateProjectWidget(self.sync_dir)
        self.create_project_widget.show()
        self.create_project_widget.created.connect(self.open_project)

    def init_missing_project_ui(self):
        ## Create project menu
        # project has not yet been selected or created
        # need to open minimal interface which allows users
        # to open or create a project.

        menu_bar = self.menuBar()
        self.menu_bar = menu_bar
        self.menu_bar.clear()
        self.project_menu = menu_bar.addMenu("Project")

        # Open project
        self.open_project_action = QtWidgets.QAction(QtGui.QIcon(""),
                                                     "Open project", self)
        self.open_project_action.setShortcut("Ctrl+O")

        self.project_menu.addAction(self.open_project_action)
        self.open_project_action.triggered.connect(
            self.show_open_project_widget)

        # Create project
        self.create_project_action = QtWidgets.QAction(QtGui.QIcon(""),
                                                       "Create project", self)
        self.create_project_action.setShortcut("Ctrl+C")
        self.project_menu.addAction(self.create_project_action)
        self.create_project_action.triggered.connect(
            self.show_create_project_widget)

        # Network Menu
        self.network_menu = menu_bar.addMenu('Network')
        # # segment folder
        self.segment_folder_btn = QtWidgets.QAction(QtGui.QIcon('missing.png'),
                                                    'Segment folder', self)

        def show_segment_folder():
            self.segment_folder_widget = SegmentFolderWidget(
                self.sync_dir, self.instruction_dir)
            self.segment_folder_widget.show()

        self.segment_folder_btn.triggered.connect(show_segment_folder)
        self.network_menu.addAction(self.segment_folder_btn)

        self.add_measurements_menu(menu_bar)
        self.add_extras_menu(menu_bar)
        self.add_about_menu(menu_bar)

        ### Add project btns to open window (so it shows something useful)
        project_btn_widget = QtWidgets.QWidget()
        self.setCentralWidget(project_btn_widget)

        layout = QtWidgets.QHBoxLayout()
        project_btn_widget.setLayout(layout)
        open_project_btn = QtWidgets.QPushButton('Open existing project')
        open_project_btn.clicked.connect(self.show_open_project_widget)
        layout.addWidget(open_project_btn)

        create_project_btn = QtWidgets.QPushButton('Create new project')
        create_project_btn.clicked.connect(self.show_create_project_widget)
        layout.addWidget(create_project_btn)

        create_dataset_btn = QtWidgets.QPushButton('Create training dataset')

        def show_create_dataset():
            self.create_dataset_widget = CreateDatasetWidget(self.sync_dir)
            self.create_dataset_widget.show()

        create_dataset_btn.clicked.connect(show_create_dataset)
        layout.addWidget(create_dataset_btn)

        self.setWindowTitle("RootPainter")
        self.resize(layout.sizeHint())

    def add_extras_menu(self, menu_bar, project_open=False):
        extras_menu = menu_bar.addMenu('Extras')
        comp_btn = QtWidgets.QAction(QtGui.QIcon('missing.png'),
                                     'Extract composites', self)
        comp_btn.triggered.connect(self.show_extract_comp)
        extras_menu.addAction(comp_btn)

        conv_to_rve_btn = QtWidgets.QAction(
            QtGui.QIcon('missing.png'),
            'Convert segmentations for RhizoVision Explorer', self)
        conv_to_rve_btn.triggered.connect(self.show_conv_to_rve)
        extras_menu.addAction(conv_to_rve_btn)

        if project_open:
            extend_dataset_btn = QtWidgets.QAction(QtGui.QIcon('missing.png'),
                                                   'Extend dataset', self)

            def update_dataset_after_check():
                was_extended, file_names = check_extend_dataset(
                    self, self.dataset_dir, self.image_fnames,
                    self.proj_file_path)
                if was_extended:
                    self.image_fnames = file_names
                    self.nav.all_fnames = file_names
                    self.nav.update_nav_label()

            extend_dataset_btn.triggered.connect(update_dataset_after_check)
            extras_menu.addAction(extend_dataset_btn)

    def add_about_menu(self, menu_bar):
        about_menu = menu_bar.addMenu('About')
        license_btn = QtWidgets.QAction(QtGui.QIcon('missing.png'), 'License',
                                        self)
        license_btn.triggered.connect(self.show_license_window)
        about_menu.addAction(license_btn)

        about_btn = QtWidgets.QAction(QtGui.QIcon('missing.png'),
                                      'RootPainter', self)
        about_btn.triggered.connect(self.show_about_window)
        about_menu.addAction(about_btn)

    def show_license_window(self):
        self.license_window = LicenseWindow()
        self.license_window.show()

    def show_about_window(self):
        self.about_window = AboutWindow()
        self.about_window.show()

    def update_window_title(self):
        proj_dirname = os.path.basename(self.proj_location)
        self.setWindowTitle(f"RootPainter {proj_dirname}"
                            f" {os.path.basename(self.image_path)}")

    def init_active_project_ui(self):
        # container for both nav and graphics view.
        container = QtWidgets.QWidget()
        container_layout = QtWidgets.QVBoxLayout()
        container_layout.setContentsMargins(0, 0, 0, 0)
        container.setLayout(container_layout)
        self.setCentralWidget(container)

        self.graphics_view = CustomGraphicsView()
        self.graphics_view.zoom_change.connect(self.update_cursor)

        container_layout.addWidget(self.graphics_view)
        scene = GraphicsScene()
        scene.parent = self
        self.graphics_view.setScene(scene)
        self.graphics_view.mouse_scroll_event.connect(self.mouse_scroll)

        # Required so graphics scene can track mouse up when mouse is not pressed
        self.graphics_view.setMouseTracking(True)
        self.scene = scene
        self.nav = NavWidget(self.image_fnames)
        self.update_file(self.image_path)

        # bottom bar
        bottom_bar = QtWidgets.QWidget()
        bottom_bar_layout = QtWidgets.QHBoxLayout()
        # left, top, right, bottom
        bottom_bar_layout.setContentsMargins(20, 0, 20, 20)
        bottom_bar_layout.setSpacing(0)
        bottom_bar.setLayout(bottom_bar_layout)

        container_layout.addWidget(bottom_bar)

        # Bottom bar left
        self.vis_widget = VisibilityWidget()
        self.vis_widget.setMaximumWidth(200)
        self.vis_widget.setMinimumWidth(200)
        self.vis_widget.seg_checkbox.stateChanged.connect(
            self.seg_checkbox_change)
        self.vis_widget.annot_checkbox.stateChanged.connect(
            self.annot_checkbox_change)
        self.vis_widget.im_checkbox.stateChanged.connect(
            self.im_checkbox_change)
        bottom_bar_layout.addWidget(self.vis_widget)

        # bottom bar right
        bottom_bar_r = QtWidgets.QWidget()
        bottom_bar_r_layout = QtWidgets.QVBoxLayout()
        bottom_bar_r.setLayout(bottom_bar_r_layout)
        bottom_bar_layout.addWidget(bottom_bar_r)

        # Nav
        self.nav.file_change.connect(self.update_file)

        self.nav.image_path = self.image_path
        self.nav.update_nav_label()

        # info label
        info_container = QtWidgets.QWidget()
        info_container_layout = QtWidgets.QHBoxLayout()
        info_container_layout.setAlignment(Qt.AlignCenter)
        info_label = QtWidgets.QLabel()
        info_label.setText("")
        info_container_layout.addWidget(info_label)
        # left, top, right, bottom
        info_container_layout.setContentsMargins(0, 0, 0, 0)
        info_container.setLayout(info_container_layout)
        self.info_label = info_label

        bottom_bar_r_layout.addWidget(info_container)
        bottom_bar_r_layout.addWidget(self.nav)

        self.add_menu()

        self.resize(container_layout.sizeHint())

        self.update_cursor()

        def view_fix():
            """ hack for linux bug """
            self.update_cursor()
            self.graphics_view.fit_to_view()

        QtCore.QTimer.singleShot(100, view_fix)

    def track_changes(self):
        if self.tracking:
            return
        print('Starting watch for changes')
        self.tracking = True

        def check():
            # check for any messages
            messages = os.listdir(str(self.message_dir))
            for m in messages:
                if hasattr(self, 'info_label'):
                    self.info_label.setText(m)
                try:
                    # Added try catch because this error happened (very rarely)
                    # PermissionError: [WinError 32]
                    # The process cannot access the file because it is
                    # being used by another process
                    os.remove(os.path.join(self.message_dir, m))
                except Exception as e:
                    print('Caught exception when trying to detele msg', e)
            if hasattr(self, 'seg_path') and os.path.isfile(self.seg_path):
                try:
                    # seg mtime is not actually used any more.
                    new_mtime = os.path.getmtime(self.seg_path)
                    # seg_mtime is None before the seg is loaded.
                    if not self.seg_mtime:
                        print('load seg from file.')
                        self.seg_pixmap = QtGui.QPixmap(self.seg_path)
                        self.seg_mtime = new_mtime
                        self.nav.next_image_button.setText('Save && Next >')
                        self.nav.next_image_button.setEnabled(True)
                        if self.seg_visible:
                            self.seg_pixmap_holder.setPixmap(self.seg_pixmap)
                        if hasattr(self, 'vis_widget'):
                            self.vis_widget.seg_checkbox.setText(
                                'Segmentation (S)')
                except Exception as e:
                    print('Error: when trying to load segmention ' + str(e))
                    # sometimes problems reading file.
                    # don't worry about this exception
            else:
                print('no seg found', end=",")
            QtCore.QTimer.singleShot(500, check)

        QtCore.QTimer.singleShot(500, check)

    def close_project_window(self):
        self.close()
        self.closed.emit()

    def add_menu(self):
        menu_bar = self.menuBar()
        menu_bar.clear()

        self.project_menu = menu_bar.addMenu("Project")

        self.close_project_action = QtWidgets.QAction(QtGui.QIcon(""),
                                                      "Close project", self)
        self.project_menu.addAction(self.close_project_action)
        self.close_project_action.triggered.connect(self.close_project_window)

        edit_menu = menu_bar.addMenu("Edit")
        # Undo
        undo_action = QtWidgets.QAction(QtGui.QIcon(""), "Undo", self)
        undo_action.setShortcut("Z")
        edit_menu.addAction(undo_action)
        undo_action.triggered.connect(self.scene.undo)

        # Redo
        redo_action = QtWidgets.QAction(QtGui.QIcon(""), "Redo", self)
        redo_action.setShortcut("Ctrl+Shift+Z")
        edit_menu.addAction(redo_action)
        redo_action.triggered.connect(self.scene.redo)

        options_menu = menu_bar.addMenu("Options")
        # pre segment count
        pre_segment_count_action = QtWidgets.QAction(QtGui.QIcon(""),
                                                     "Pre-Segment", self)
        options_menu.addAction(pre_segment_count_action)
        pre_segment_count_action.triggered.connect(
            self.open_pre_segment_count_dialog)

        # change brush colors
        change_foreground_color_action = QtWidgets.QAction(
            QtGui.QIcon(""), "Foreground brush colour", self)
        options_menu.addAction(change_foreground_color_action)
        change_foreground_color_action.triggered.connect(
            self.change_foreground_color)
        change_background_color_action = QtWidgets.QAction(
            QtGui.QIcon(""), "Background brush colour", self)
        options_menu.addAction(change_background_color_action)
        change_background_color_action.triggered.connect(
            self.change_background_color)

        brush_menu = menu_bar.addMenu("Brushes")
        foreground_color_action = QtWidgets.QAction(QtGui.QIcon(""),
                                                    "Foreground", self)
        foreground_color_action.setShortcut("Q")
        brush_menu.addAction(foreground_color_action)
        foreground_color_action.triggered.connect(self.set_foreground_color)

        background_color_action = QtWidgets.QAction(QtGui.QIcon(""),
                                                    "Background", self)
        background_color_action.setShortcut("W")
        brush_menu.addAction(background_color_action)
        background_color_action.triggered.connect(self.set_background_color)

        eraser_color_action = QtWidgets.QAction(QtGui.QIcon(""), "Eraser",
                                                self)
        eraser_color_action.setShortcut("E")
        brush_menu.addAction(eraser_color_action)
        eraser_color_action.triggered.connect(self.set_eraser_color)

        ## View menu
        # Fit to view
        view_menu = menu_bar.addMenu('View')
        fit_to_view_btn = QtWidgets.QAction(QtGui.QIcon('missing.png'),
                                            'Fit to View', self)
        fit_to_view_btn.setShortcut('Ctrl+F')
        fit_to_view_btn.setStatusTip('Fit image to view')
        fit_to_view_btn.triggered.connect(self.graphics_view.fit_to_view)
        view_menu.addAction(fit_to_view_btn)

        # Actual size
        actual_size_view_btn = QtWidgets.QAction(QtGui.QIcon('missing.png'),
                                                 'Actual size', self)
        actual_size_view_btn.setShortcut('Ctrl+A')
        actual_size_view_btn.setStatusTip('Show image at actual size')
        actual_size_view_btn.triggered.connect(
            self.graphics_view.show_actual_size)
        view_menu.addAction(actual_size_view_btn)

        toggle_seg_visibility_btn = QtWidgets.QAction(
            QtGui.QIcon('missing.png'), 'Toggle segmentation visibility', self)
        toggle_seg_visibility_btn.setShortcut('S')
        toggle_seg_visibility_btn.setStatusTip('Show or hide segmentation')
        toggle_seg_visibility_btn.triggered.connect(self.show_hide_seg)
        view_menu.addAction(toggle_seg_visibility_btn)

        toggle_annot_visibility_btn = QtWidgets.QAction(
            QtGui.QIcon('missing.png'), 'Toggle annotation visibility', self)
        toggle_annot_visibility_btn.setShortcut('A')
        toggle_annot_visibility_btn.setStatusTip('Show or hide annotation')
        toggle_annot_visibility_btn.triggered.connect(self.show_hide_annot)
        view_menu.addAction(toggle_annot_visibility_btn)

        toggle_image_visibility_btn = QtWidgets.QAction(
            QtGui.QIcon('missing.png'), 'Toggle image visibility', self)
        toggle_image_visibility_btn.setShortcut('I')
        toggle_image_visibility_btn.setStatusTip('Show or hide image')
        toggle_image_visibility_btn.triggered.connect(self.show_hide_image)
        view_menu.addAction(toggle_image_visibility_btn)

        def zoom_in():
            self.graphics_view.zoom *= 1.1
            self.graphics_view.update_zoom()

        def zoom_out():
            self.graphics_view.zoom /= 1.1
            self.graphics_view.update_zoom()

        zoom_in_btn = QtWidgets.QAction(QtGui.QIcon('missing.png'), 'Zoom in',
                                        self)
        zoom_in_btn.setShortcut('+')
        zoom_in_btn.setStatusTip('Zoom in')
        zoom_in_btn.triggered.connect(zoom_in)
        view_menu.addAction(zoom_in_btn)

        zoom_out_btn = QtWidgets.QAction(QtGui.QIcon('missing.png'),
                                         'Zoom out', self)
        zoom_out_btn.setShortcut('-')
        zoom_out_btn.setStatusTip('Zoom out')
        zoom_out_btn.triggered.connect(zoom_out)
        view_menu.addAction(zoom_out_btn)

        # Network Menu
        network_menu = menu_bar.addMenu('Network')

        # start training
        start_training_btn = QtWidgets.QAction(QtGui.QIcon('missing.png'),
                                               'Start training', self)
        start_training_btn.triggered.connect(self.start_training)
        network_menu.addAction(start_training_btn)

        # stop training
        stop_training_btn = QtWidgets.QAction(QtGui.QIcon('missing.png'),
                                              'Stop training', self)
        stop_training_btn.triggered.connect(self.stop_training)
        network_menu.addAction(stop_training_btn)

        # # segment folder
        segment_folder_btn = QtWidgets.QAction(QtGui.QIcon('missing.png'),
                                               'Segment folder', self)

        def show_segment_folder():
            self.segment_folder_widget = SegmentFolderWidget(
                self.sync_dir, self.instruction_dir)
            self.segment_folder_widget.show()

        segment_folder_btn.triggered.connect(show_segment_folder)
        network_menu.addAction(segment_folder_btn)

        # segment current image
        # segment_image_btn = QtWidgets.QAction(QtGui.QIcon('missing.png'),
        #                                       'Segment current image', self)
        # segment_image_btn.triggered.connect(self.segment_current_image)
        # network_menu.addAction(segment_image_btn)
        self.add_measurements_menu(menu_bar)
        self.add_extras_menu(menu_bar, project_open=True)

    def add_measurements_menu(self, menu_bar):
        # Measurements
        measurements_menu = menu_bar.addMenu('Measurements')
        # object count
        object_count_btn = QtWidgets.QAction(QtGui.QIcon('missing.png'),
                                             'Extract count', self)

        def show_extract_count():
            self.extract_count_widget = ExtractCountWidget()
            self.extract_count_widget.show()

        object_count_btn.triggered.connect(show_extract_count)
        measurements_menu.addAction(object_count_btn)

        # length
        length_btn = QtWidgets.QAction(QtGui.QIcon('missing.png'),
                                       'Extract length', self)

        def show_extract_length():
            self.extract_length_widget = ExtractLengthWidget()
            self.extract_length_widget.show()

        length_btn.triggered.connect(show_extract_length)
        measurements_menu.addAction(length_btn)

        # region props
        region_props_btn = QtWidgets.QAction(QtGui.QIcon('missing.png'),
                                             'Extract region properties', self)

        def show_extract_region_props():
            self.extract_regions_widget = ExtractRegionsWidget()
            self.extract_regions_widget.show()

        region_props_btn.triggered.connect(show_extract_region_props)
        measurements_menu.addAction(region_props_btn)

    def show_extract_comp(self):
        self.extract_comp_widget = ExtractCompWidget()
        self.extract_comp_widget.show()

    def show_conv_to_rve(self):
        """ show window to convert segmentations
            to RhizoVision Explorer compatible format """
        self.convert_to_rve_widget = ConvertSegForRVEWidget()
        self.convert_to_rve_widget.show()

    def stop_training(self):
        self.info_label.setText("Stopping training...")
        content = {"message_dir": self.message_dir}
        self.send_instruction('stop_training', content)

    def start_training(self):
        self.info_label.setText("Starting training...")
        content = {
            "model_dir": self.model_dir,
            "dataset_dir": self.dataset_dir,
            "train_annot_dir": self.train_annot_dir,
            "val_annot_dir": self.val_annot_dir,
            "seg_dir": self.seg_dir,
            "log_dir": self.log_dir,
            "message_dir": self.message_dir
        }
        self.send_instruction('start_training', content)

    def seg_checkbox_change(self, state):
        checked = (state == QtCore.Qt.Checked)
        if checked is not self.seg_visible:
            self.show_hide_seg()

    def annot_checkbox_change(self, state):
        checked = (state == QtCore.Qt.Checked)
        if checked is not self.annot_visible:
            self.show_hide_annot()

    def im_checkbox_change(self, state):
        checked = (state == QtCore.Qt.Checked)
        if checked is not self.image_visible:
            self.show_hide_image()

    def show_hide_seg(self):
        # show or hide the current segmentation.
        if self.seg_visible:
            self.seg_pixmap_holder.setPixmap(self.blank_pixmap)
            self.seg_visible = False
        else:
            self.seg_pixmap_holder.setPixmap(self.seg_pixmap)
            self.seg_visible = True
        self.vis_widget.seg_checkbox.setChecked(self.seg_visible)

    def show_hide_image(self):
        # show or hide the current image.
        # Could be useful to help inspect the segmentation or annotation
        if self.image_visible:
            self.image_pixmap_holder.setPixmap(self.black_pixmap)
            self.image_visible = False
        else:
            self.image_pixmap_holder.setPixmap(self.graphics_view.image)
            self.image_visible = True
        self.vis_widget.im_checkbox.setChecked(self.image_visible)

    def show_hide_annot(self):
        # show or hide the current annotations.
        # Could be useful to help inspect the background image
        if self.annot_visible:
            self.annot_pixmap_holder.setPixmap(self.blank_pixmap)
            self.annot_visible = False
        else:
            self.scene.annot_pixmap_holder.setPixmap(self.scene.annot_pixmap)
            self.annot_visible = True
        self.vis_widget.annot_checkbox.setChecked(self.annot_visible)

    def set_foreground_color(self, _event):
        self.scene.brush_color = self.scene.foreground_color
        self.update_cursor()

    def change_foreground_color(self, _event):
        foreground_set = (
            self.scene.brush_color == self.scene.foreground_color)
        show_alpha_option = QtWidgets.QColorDialog.ColorDialogOption(1)
        new_color = QtWidgets.QColorDialog.getColor(
            self.scene.foreground_color, options=show_alpha_option)

        if new_color.isValid():
            self.scene.foreground_color = new_color

        if foreground_set:
            self.scene.brush_color = self.scene.foreground_color
            self.update_cursor()

    def change_background_color(self, _event):
        background_set = (
            self.scene.brush_color == self.scene.background_color)
        show_alpha_option = QtWidgets.QColorDialog.ColorDialogOption(1)
        new_color = QtWidgets.QColorDialog.getColor(
            self.scene.background_color, options=show_alpha_option)

        if new_color.isValid():
            self.scene.background_color = new_color

        if background_set:
            self.scene.brush_color = self.scene.background_color
            self.update_cursor()

    def set_background_color(self, _event):
        self.scene.brush_color = self.scene.background_color
        self.update_cursor()

    def set_eraser_color(self, _event):
        self.scene.brush_color = self.scene.eraser_color
        self.update_cursor()

    def update_cursor(self):
        brush_w = self.scene.brush_size * self.graphics_view.zoom * 0.93
        brush_w = max(brush_w, 3)

        canvas_w = max(brush_w, 30)
        pm = QtGui.QPixmap(canvas_w, canvas_w)
        pm.fill(Qt.transparent)
        painter = QtGui.QPainter(pm)

        painter.drawPixmap(canvas_w, canvas_w, pm)

        brush_rgb = self.scene.brush_color.toRgb()
        r, g, b = brush_rgb.red(), brush_rgb.green(), brush_rgb.blue()
        cursor_color = QtGui.QColor(r, g, b, 120)

        painter.setPen(
            QtGui.QPen(cursor_color, 3, Qt.SolidLine, Qt.RoundCap,
                       Qt.RoundJoin))
        ellipse_x = int(round(canvas_w / 2 - (brush_w) / 2))
        ellipse_y = int(round(canvas_w / 2 - (brush_w) / 2))
        ellipse_w = brush_w
        ellipse_h = brush_w

        painter.drawEllipse(ellipse_x, ellipse_y, ellipse_w, ellipse_h)
        painter.setPen(
            QtGui.QPen(QtGui.QColor(0, 0, 0, 180), 2, Qt.SolidLine,
                       Qt.FlatCap))

        # Draw black to show where cursor is even when brush is small
        painter.drawLine(0, (canvas_w / 2), canvas_w * 2, (canvas_w / 2))
        painter.drawLine((canvas_w / 2), 0, (canvas_w / 2), canvas_w * 2)
        painter.end()

        cursor = QtGui.QCursor(pm)
        self.setCursor(cursor)

    def open_pre_segment_count_dialog(self):
        new_count, ok = QtWidgets.QInputDialog.getInt(
            self, "", "Select Pre-Segment count", self.pre_segment_count, 0,
            100, 1)
        if ok:
            self.pre_segment_count = new_count
        # For some reason the events get confused and
        # scroll+pan gets switched on here.
        # Check if control key is up to disble it.
        modifiers = QtWidgets.QApplication.keyboardModifiers()
        if not modifiers & QtCore.Qt.ControlModifier:
            self.graphics_view.setDragMode(QtWidgets.QGraphicsView.NoDrag)

    def save_annotation(self):
        if self.scene.annot_pixmap:
            self.annot_path = maybe_save_annotation(
                self.proj_location, self.scene.annot_pixmap, self.annot_path,
                self.png_fname, self.train_annot_dir, self.val_annot_dir)
Beispiel #5
0
class Window(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super(Window, self).__init__()
        self.setupUi(self)

        # -------setupUi------------
        self.originImgFigure = ImgFigure()
        self.enhancedImgFigure = ImgFigure()

        self.originImgLayout = QHBoxLayout(self.originBox)
        self.enhancedImgLayout = QHBoxLayout(self.enhancedBox)
        self.originImgLayout.addWidget(self.originImgFigure)
        self.enhancedImgLayout.addWidget(self.enhancedImgFigure)

        self.statusBar.showMessage("请选择文件")
        self.progressBar = QProgressBar()
        self.statusBar.addPermanentWidget(self.progressBar)
        # self.progressBar.setVisible(False)

        self.showProgressBarAct.triggered['bool'].connect(
            self.progressBar.setVisible)

        self.showToolBarAct.setChecked(True)
        self.showProgressBarAct.setChecked(True)
        # -------setupUi------------

        self.alpha = 1
        self.gamma = 0.7
        self.weigh = 1

        self.settingWindow = SettingWindow()
        self.settingWindow.changeParameterSignal.connect(self.changeParameter)

        self._illuMapWindowFlag = False

        with open("./resource/config/.history", 'r') as fp:
            self.action1 = self.recentOpenMenu.addAction(fp.readline())
            self.action1.triggered.connect(
                lambda: self.openImage(self.action1.text()))
            self.action2 = self.recentOpenMenu.addAction(fp.readline())
            self.action2.triggered.connect(
                lambda: self.openImage(self.action2.text()))
            self.action3 = self.recentOpenMenu.addAction(fp.readline())
            self.action3.triggered.connect(
                lambda: self.openImage(self.action3.text()))

    @pyqtSlot()
    def on_openAct_triggered(self):
        # imgPath = "./data/13.jpg"
        imgPath = QFileDialog.getOpenFileName(self, "请选择图片", "/",
                                              "All Files (*)")[0]
        self.openImage(imgPath)

    def openImage(self, imgPath):
        self.imgPath = imgPath.strip()
        if imgPath != '':
            self.originImg = imread(self.imgPath)
            self.originImgFigure.axes.imshow(self.originImg)
            self.originImgFigure.draw()
            self.statusBar.showMessage("当前图片路径: " + self.imgPath)

            self.historyFile()
            self.progressBar.setValue(0)
            self.enhanceAct.setEnabled(True)
        else:
            QMessageBox.warning(self, "提示", "请重新选择图片")

    def historyFile(self):
        with open("./resource/config/.history", 'r+') as fp:
            history = fp.readlines()
            history = self.imgPath + '\n' + history[0] + history[1]
            fp.seek(0, 0)
            fp.truncate()
            fp.write(history)

    def changeParameter(self, alpha, gamma, weigh):
        self.alpha = alpha
        self.gamma = gamma
        self.weigh = weigh

    @pyqtSlot()
    def on_enhanceAct_triggered(self):
        self.progressBar.setValue(0)
        # self.progressBar.setVisible(True)
        self.workThread = WorkThread(self.imgPath, self.progressBar,
                                     self.alpha, self.gamma)
        self.workThread.start()
        self.workThread.finishSignal.connect(self.on_workThread_finishSignal)

    def on_workThread_finishSignal(self, T, R):
        self.T = T
        self.R = R
        self.statusBar.showMessage("当前图片路径: " + self.imgPath + "   图像增强成功")
        # self.imgFigure.T_axes.imshow(self.T, )
        self.enhancedImgFigure.axes.imshow(self.R)

        self.progressBar.setValue(self.progressBar.maximum())
        # self.progressBar.setVisible(False)

        self.enhancedImgFigure.draw()
        self.saveAct.setEnabled(True)
        self.saveAsAct.setEnabled(True)
        self.saveIlluMapAct.setEnabled(True)
        self.denoiseAct.setEnabled(True)
        self.illuMapAct.setEnabled(True)

    @pyqtSlot()
    def on_saveAsAct_triggered(self):
        savePath = QFileDialog.getSaveFileName(
            self, "请选择保存位置", "/", "BMP格式 (*.bmp);;JPG格式 (*.jpg)")[0]
        if savePath != '':
            imsave(savePath, self.R)
            QMessageBox.about(self, "提示", "保存成功")
        else:
            QMessageBox.warning(self, "提示", "请重新选择保存位置")

    @pyqtSlot()
    def on_saveAct_triggered(self):
        savePath = self.imgPath
        imsave(savePath, self.R)
        QMessageBox.about(self, "提示", "保存成功")

    @pyqtSlot()
    def on_clearAct_triggered(self):
        self.originImgFigure.axes.cla()
        self.originImgFigure.draw()
        self.enhancedImgFigure.axes.cla()
        self.enhancedImgFigure.draw()

        self.enhanceAct.setEnabled(False)
        self.saveIlluMapAct.setEnabled(False)
        self.saveAsAct.setEnabled(False)
        self.saveAct.setEnabled(False)
        self.denoiseAct.setEnabled(False)

    @pyqtSlot()
    def on_quitAct_triggered(self):
        qApp.quit()

    @pyqtSlot()
    def on_denoiseAct_triggered(self):
        self.R = restoration.denoise_tv_bregman(self.R, self.weigh)
        self.enhancedImgFigure.axes.imshow(self.R)
        self.enhancedImgFigure.draw()
        QMessageBox.about(self, "提示", "去噪成功")

    @pyqtSlot()
    def on_saveIlluMapAct_triggered(self):
        savePath = QFileDialog.getSaveFileName(
            self, "请选择保存位置", "/", "BMP格式 (*.bmp);;JPG格式 (*.jpg)")[0]
        if savePath != '':
            if self._illuMapWindowFlag == True:
                color = self.illuMapWindow.colorComboBox.currentText()
                color = self.illuMapWindow.colorMap[color]
                imsave(savePath, self.T, cmap=get_cmap(color))
            else:
                imsave(savePath, self.T, cmap=get_cmap('OrRd_r'))
            QMessageBox.about(self, "提示", "保存成功")
        else:
            QMessageBox.warning(self, "提示", "请重新选择保存位置")

        # -------------其他界面-------------

    @pyqtSlot()
    def on_aboutAct_triggered(self):
        self.aboutWindow = AboutWindow()
        self.aboutWindow.show()

    @pyqtSlot()
    def on_illuMapAct_triggered(self):
        self.illuMapWindow = IlluMapWindow()
        self._illuMapWindowFlag = True
        self.illuMapWindow.saveIlluMapBtn.clicked.connect(
            self.on_saveIlluMapAct_triggered)
        self.illuMapWindow.confirmBtn.clicked.connect(
            self.on_confirmBtn_triggered)
        self.illuMapWindow.figure.axes.imshow(self.T, cmap=get_cmap('OrRd_r'))
        self.illuMapWindow.figure.draw()
        self.illuMapWindow.show()

    def on_confirmBtn_triggered(self):
        color = self.illuMapWindow.colorComboBox.currentText()
        color = self.illuMapWindow.colorMap[color]
        self.illuMapWindow.figure.axes.imshow(self.T, cmap=get_cmap(color))
        self.illuMapWindow.figure.draw()

    @pyqtSlot()
    def on_settingAct_triggered(self):
        self.settingWindow.smoothnessSlider.setValue(
            int(401 - 100 * self.alpha))
        self.settingWindow.brightnessSlider.setValue(int(100 * self.gamma))
        self.settingWindow.denosieSlider.setValue(int(100 * self.weigh))
        self.settingWindow.show()