def download(self, downloadItem): # noqa C901 ''' @param: downloadItem QWebEngineDownloadItem ''' downloadTimer = QTime() downloadTimer.start() self.closeDownloadTab(downloadItem) downloadPath = '' openFile = False fileName = basename(downloadItem.path()) forceAsk = downloadItem.savePageFormat() != QWebEngineDownloadItem.UnknownSaveFormat \ or downloadItem.type() == QWebEngineDownloadItem.UserRequested if self._useExternalManager: self.startExternalManager(downloadItem.url()) elif forceAsk or not self._downloadPath: (Unknown, Open, Save, ExternalManager, SavePage) = range(5) result = Unknown if downloadItem.savePageFormat( ) != QWebEngineDownloadItem.UnknownSaveFormat: # Save Page Requested result = SavePage elif downloadItem.type() == QWebEngineDownloadItem.UserRequested: # Save x as... requested result = Save else: # Ask what to do optionsDialog = DownloadOptionsDialog(fileName, downloadItem, gVar.app.activeWindow()) optionsDialog.showExternalManagerOption( self._useExternalManager) optionsDialog.setLastDownloadOption(self._lastDownloadOption) result = optionsDialog.exec_() if result == Open: openFile = True downloadPath = gVar.appTools.ensureUniqueFilename( pathjoin(DataPaths.path(DataPaths.Temp), fileName)) self._lastDownloadOption = self.OpenFile elif result == Save: downloadPath, selectedFitler = QFileDialog.getSaveFileName( gVar.app.activeWindow(), _('Save file as...'), pathjoin(self._lastDownloadPath, fileName)) if downloadPath: self._lastDownloadPath = QFileInfo( downloadPath).absolutePath() Settings().setValue('DownloadManager/lastDownloadPath', self._lastDownloadPath) self._lastDownloadOption = self.SaveFile elif result == SavePage: mhtml = _('MIME HTML Archive (*.mhtml)') htmlSingle = _('HTML Page, single (*.html)') htmlComplete = _('HTML Page, complete (*.html)') filter_ = '%s;;%s;;%s' % (mhtml, htmlSingle, htmlComplete) selectedFilter = '' downloadPath, selectedFilter = QFileDialog.getSaveFileName( gVar.app.activeWindow(), _('Save page as...'), pathjoin(self._lastDownloadPath, fileName), filter_, selectedFilter) if downloadPath: self._lastDownloadPath = QFileInfo( downloadPath).absolutePath() Settings().setValue('DownloadManager/lastDownloadPath', self._lastDownloadPath) self._lastDownloadOption = self.SaveFile format_ = QWebEngineDownloadItem.UnknownSaveFormat if selectedFilter == mhtml: format_ = QWebEngineDownloadItem.MimeHtmlSaveFormat elif selectedFilter == htmlSingle: format_ = QWebEngineDownloadItem.SingleHtmlSaveFormat elif selectedFilter == htmlComplete: format_ = QWebEngineDownloadItem.CompleteHtmlSaveFormat if format_ == QWebEngineDownloadItem.UnknownSaveFormat: downloadItem.setSavePageFormat(format_) elif result == ExternalManager: self.startExternalManager(downloadItem.url()) downloadItem.cancel() else: downloadItem.cancel() else: downloadPath = gVar.appTools.ensureUniqueFilename( pathjoin(self._downloadPath, fileName)) if not downloadPath: downloadItem.cancel() return # Set download path ad accept downloadItem.setPath(downloadPath) downloadItem.accept() # Create download item listItem = QListWidgetItem(self._ui.list) downItem = DownloadItem(listItem, downloadItem, QFileInfo(downloadPath).absolutePath(), basename(downloadPath), openFile, self) downItem.setDownTimer(downloadTimer) downItem.startDownloading() downItem.deleteItem.connect(self._deleteItem) downItem.downloadFinished.connect(self._downloadFinished) self._ui.list.setItemWidget(listItem, downItem) listItem.setSizeHint(downItem.sizeHint()) downItem.show() self._activeDownloadsCount += 1 self.downloadsCountChanged.emit()
class guiApp(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow): def __init__(self): super().__init__() self.setupUi(self) self.video_path = '2019-05-06-10-45-16-tv_30_tnf.avi' self.video_capturer = cv2.VideoCapture(self.video_path) self.video_status = 'Video is not playing' self.width = int(self.video_capturer.get(cv2.CAP_PROP_FRAME_WIDTH)) self.height = int(self.video_capturer.get(cv2.CAP_PROP_FRAME_HEIGHT)) self.out = cv2.VideoWriter(self.video_path[:-4] + '_label.avi', cv2.VideoWriter_fourcc(*'XVID'), 25.0, (self.width, self.height)) self.video_frame = None self.video_src = 'camera' self.proc_image_width = 960 self.proc_image_height = 540 self.proc_qimage = QImage() self.proc_qpixmap = QPixmap() self.tmr = QTimer(self) self.tmr.setInterval(40) self.tmr.timeout.connect(self.timeout_slot) self.tmr.start() self.time = QTime() self.time.start() self.fps_period = None self.last_timestamp = self.time.elapsed() self.enable_detector = False self.enable_detector_yolo = False self.enable_playing = False self.enable_record = False self.cnn_model_path = 'output_models/frozen_inference_graph.pb' self.cfg_yolo_path = 'output_modelsgoit/yolov2.cfg' self.weights_yolo_path = 'output_models/yolov2_last.weights' self.ssd = None self.yolo = None self.camera_id = 0 self.camera_capturer = cv2.VideoCapture(self.camera_id) self.camera_status = 'Stream is non active' self.camera_frame = None self.setWindowTitle('SKL CNN Classifier') self.checkBox_enable_detection.toggled.connect( self.checkbox_enable_detection_toggled) self.checkBox_enable_playing.toggled.connect( self.checkbox_enable_playing_toggled) self.checkBox_enable_camera.toggled.connect( self.checkbox_enable_camera_toggled) self.checkBox_enable_detection_yolo.toggled.connect( self.checkBox_enable_detection_yolo_toggled) self.checkBox_enable_record.toggled.connect( self.checkBox_enable_record_toggled) self.lineEdit_path_video.editingFinished.connect( self.lineedit_path_video_editing_finished) self.lineEdit_path_graph.editingFinished.connect( self.lineedit_path_graph_editing_finished) self.lineEdit_path_cfg_yolo.editingFinished.connect( self.lineedit_path_cfg_yolo_editing_finished) self.lineEdit_path_weight_yolo.editingFinished.connect( self.lineedit_path_weight_yolo_editing_finished) self.pushButton_load_video.clicked.connect( self.pushbutton_load_video_clicked) self.pushButton_load_graph.clicked.connect( self.pushbutton_load_graph_clicked) self.pushButton_load_cdg_yolo.clicked.connect( self.pushButton_load_cdg_yolo_clicked) self.pushButton_load_weights_yolo.clicked.connect( self.pushButton_load_weights_yolo_clicked) self.lineEdit_path_video.setText(self.video_path) self.lineEdit_path_graph.setText(self.cnn_model_path) self.lineEdit_path_cfg_yolo.setText(self.cfg_yolo_path) self.lineEdit_path_weight_yolo.setText(self.weights_yolo_path) self.checkBox_enable_camera.setChecked(True) pass def timeout_slot(self): if self.video_src == 'camera': self.refresh_camera_frame() self.proc_frame = self.camera_frame if self.video_src == 'video': self.refresh_video_frame() self.proc_frame = self.video_frame if self.proc_frame is not None: if self.enable_detector: cropimg = self.proc_frame[ 0:self.proc_frame.shape[0], int((self.proc_frame.shape[1] - self.proc_frame.shape[0]) / 2):int((self.proc_frame.shape[1] + self.proc_frame.shape[0]) / 2), :] ssd_image = self.ssd.forwardpass(cropimg) self.proc_frame[0:self.proc_frame.shape[0], int((self.proc_frame.shape[1] - self.proc_frame.shape[0]) / 2):int((self.proc_frame.shape[1] + self.proc_frame.shape[0]) / 2), :] = ssd_image cv2.rectangle(self.proc_frame, (int( (self.proc_frame.shape[1] - self.proc_frame.shape[0]) / 2), 0), (int( (self.proc_frame.shape[1] + self.proc_frame.shape[0]) / 2), self.proc_frame.shape[0]), (255, 0, 0), 2) elif self.enable_detector_yolo: cropimg = self.proc_frame[ 0:self.proc_frame.shape[0], int((self.proc_frame.shape[1] - self.proc_frame.shape[0]) / 2):int((self.proc_frame.shape[1] + self.proc_frame.shape[0]) / 2), :] yolo_image = self.yolo.detect_by_yolo(cropimg) self.proc_frame[0:self.proc_frame.shape[0], int((self.proc_frame.shape[1] - self.proc_frame.shape[0]) / 2):int((self.proc_frame.shape[1] + self.proc_frame.shape[0]) / 2), :] = yolo_image cv2.rectangle(self.proc_frame, (int( (self.proc_frame.shape[1] - self.proc_frame.shape[0]) / 2), 0), (int( (self.proc_frame.shape[1] + self.proc_frame.shape[0]) / 2), self.proc_frame.shape[0]), (255, 0, 0), 2) if self.enable_record: self.out.write(cv2.cvtColor(self.proc_frame, cv2.COLOR_RGB2BGR)) self.proc_frame = cv2.resize( self.proc_frame, (self.proc_image_width, self.proc_image_height), interpolation=cv2.INTER_CUBIC) self.proc_qimage = convert_ndarray_to_qimg(self.proc_frame) self.proc_qpixmap = QPixmap.fromImage(self.proc_qimage) if self.proc_qpixmap is not None: self.label_image.setPixmap(self.proc_qpixmap) cur_time = self.time.elapsed() self.fps_period = cur_time - self.last_timestamp self.last_timestamp = cur_time self.label_processing_time.setText(str(self.fps_period)) self.label_fps.setText(str(int(1000.0 / self.fps_period))) pass def refresh_camera_frame(self): ret, self.camera_frame = self.camera_capturer.read() if self.camera_frame is not None: self.camera_frame = cv2.cvtColor(self.camera_frame, cv2.COLOR_BGR2RGB) self.camera_status = 'Capturing in progress' else: self.camera_status = 'Error' pass def refresh_camera_stream(self): self.camera_capturer.release() self.camera_capturer = cv2.VideoCapture(self.camera_id) pass def refresh_video_frame(self): ret, self.video_frame = self.video_capturer.read() if self.video_frame is not None: self.video_frame = cv2.cvtColor(self.video_frame, cv2.COLOR_BGR2RGB) self.video_status = 'Playing in progress' else: self.video_status = 'Error' self.label_video_status.setText(self.video_status) pass def refresh_video_stream(self): self.video_capturer.release() self.video_capturer = cv2.VideoCapture(self.video_path) def lineedit_path_video_editing_finished(self): self.video_path = self.lineEdit_path_video.text() self.width = int(self.video_capturer.get(cv2.CAP_PROP_FRAME_WIDTH)) self.height = int(self.video_capturer.get(cv2.CAP_PROP_FRAME_HEIGHT)) self.out = cv2.VideoWriter(self.video_path[:-4] + '_label.avi', cv2.VideoWriter_fourcc(*'XVID'), 25.0, (self.width, self.height)) self.refresh_video_stream() pass def lineedit_path_graph_editing_finished(self): self.cnn_model_path = self.lineEdit_path_graph.text() pass def lineedit_path_cfg_yolo_editing_finished(self): self.cfg_yolo_path = self.lineEdit_path_cfg_yolo.text() pass def lineedit_path_weight_yolo_editing_finished(self): self.weights_yolo_path = self.lineEdit_path_weight_yolo.text() pass def checkbox_enable_detection_toggled(self, checked): if self.ssd is not tf_classifier: self.ssd = tf_classifier() self.ssd.select_path_to_model(self.cnn_model_path) self.enable_detector = checked pass def checkBox_enable_detection_yolo_toggled(self, checked): if self.yolo is not df_classifier: self.yolo = df_classifier() self.yolo.select_path_to_model(self.cfg_yolo_path, self.weights_yolo_path) self.enable_detector_yolo = checked pass def checkbox_enable_camera_toggled(self, checked): if checked: self.video_src = 'camera' else: self.video_src = 'none' self.switch_video_src(self.video_src) pass def checkbox_enable_playing_toggled(self, checked): if checked: self.video_src = 'video' else: self.video_src = 'none' self.switch_video_src(self.video_src) pass def checkBox_enable_record_toggled(self, checked): self.enable_record = checked pass def switch_video_src(self, new_src): if new_src == 'camera': self.checkBox_enable_playing.setChecked(False) self.checkBox_enable_camera.setChecked(True) elif new_src == 'video': self.checkBox_enable_playing.setChecked(True) self.checkBox_enable_camera.setChecked(False) else: self.checkBox_enable_playing.setChecked(False) self.checkBox_enable_camera.setChecked(False) pass def pushbutton_load_video_clicked(self): fname = QFileDialog.getOpenFileName(self, 'Select video', '')[0] self.lineEdit_path_video.setText(fname) self.video_path = self.lineEdit_path_video.text() self.refresh_video_stream() pass def pushbutton_load_graph_clicked(self): fname = QFileDialog.getOpenFileName(self, 'Select graph SSD', '')[0] self.lineEdit_path_graph.setText(fname) pass def pushButton_load_cdg_yolo_clicked(self): fname = QFileDialog.getOpenFileName(self, 'Select cfg Yolo', '')[0] self.lineEdit_path_cfg_yolo.setText(fname) pass def pushButton_load_weights_yolo_clicked(self): fname = QFileDialog.getOpenFileName(self, 'Select weights Yolo', '')[0] self.lineEdit_path_weight_yolo.setText(fname) pass
class DownloadItem(QWidget): DEBUG = True def __init__(self, item, downloadItem, path, fileName, openFile, manager): ''' @param: item QListWidgetItem @param: downloadItem QWebEngineDownloadItem @param: path QString @param: fileName QString @param: openFile bool @param: manager DownloadManager ''' super().__init__() self._ui = uic.loadUi('mc/downloads/DownloadItem.ui', self) self._item = item # QListWidgetItem self._download = downloadItem # QWebEngineDownloadItem self._path = path self._fileName = fileName self._downTimer = QTime() self._remTime = QTime() self._downUrl = downloadItem.url() self._openFile = openFile self._downloading = False self._downloadStopped = False self._currSpeed = 0.0 self._received = downloadItem.receivedBytes() self._total = downloadItem.totalBytes() if self.DEBUG: print( 'DEBUG: %s::__init__ %s %s %s %s' % (self.__class__.__name__, item, downloadItem, path, fileName)) self.setMaximumWidth(525) self._ui.button.setPixmap( QIcon.fromTheme('process-stop').pixmap(20, 20)) self._ui.fileName.setText(self._fileName) self._ui.downloadInfo.setText(_('Remaining time unavailable')) self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect( self._customContextMenuRequested) self._ui.button.clicked.connect(self._stop) manager.resized.connect(self._parentResized) def item(self): return self._item def isDownloading(self): ''' @return: bool ''' return self._downloading def isCancelled(self): ''' @return: bool ''' self._ui.downloadInfo.text().startswith(_('Cancelled')) def remainingTime(self): ''' @return: QTime ''' return self._remTime def currentSpeed(self): ''' @return: double ''' return self._currSpeed def progress(self): ''' @return: int ''' return self._ui.progressBar.value() def setDownTimer(self, timer): ''' @param: timer QTime ''' self._downTimer = timer def startDownloading(self): self._download.finished.connect(self._finished) self._download.downloadProgress.connect(self._downloadProgress) self._downloading = True if self._downTimer.elapsed() < 1: # TODO: ? self._downTimer.start() self._updateDownloadInfo(0, self._download.receivedBytes(), self._download.totalBytes()) if const.OS_LINUX: # QFileIconProvider uses only suffix on Linux iconProvider = QFileIconProvider() # QIcon fileIcon = iconProvider.icon(QFileInfo(self._fileName)) if not fileIcon.isNull(): self._ui.fileIcon.setPixmap(fileIcon.pixmap(30)) else: self._ui.fileIcon.setPixmap(self.style().standardIcon( QStyle.SP_FileIcon).pixmap(30)) else: self._ui.fileIcon.hide() @classmethod def remaingTimeToString(cls, time): ''' @param: time QTime ''' if time < QTime(0, 0, 10): return _('few seconds') elif time < QTime(0, 1): return _('%s seconds') % time.second() elif time < QTime(1, 0): return _('%s minutes') % time.minute() else: return _('%s hours') % time.hour() @classmethod def currentSpeedToString(cls, speed): ''' @param: speed double ''' if speed < 0: return _('Unknown speed') speed /= 1024 # kB if speed < 1000: return '%s kB/s' % int(speed) speed /= 1024 # MB if speed < 1000: return '%.2f MB/s' % speed speed /= 1024 # GB return '%.2f GB/s' % speed # Q_SIGNALS: deleteItem = pyqtSignal('PyQt_PyObject') # DonwloadItem downloadFinished = pyqtSignal(bool) # bool success # private Q_SLOTS: def _parentResized(self, size): ''' @param: size QSize ''' if size.width() < 200: return self.setMaximumWidth(size.width()) def _finished(self): if self.DEBUG: print('DEBUG: %s::_finished' % self.__class__.__name__) success = False host = self._download.url().host() state = self._download.state() if state == QWebEngineDownloadItem.DownloadCompleted: success = True self._ui.downloadInfo.setText( _('Done - %s (%s)') % (host, QDateTime.currentDateTime().toString( Qt.DefaultLocaleShortDate))) elif state == QWebEngineDownloadItem.DownloadInterrupted: self._ui.donwloadInfo.setText(_('Error - %s') % host) elif state == QWebEngineDownloadItem.DownloadCancelled: self._ui.downloadInfo.setText(_('Cancelled = %s') % host) self._ui.progressBar.hide() self._ui.button.hide() self._ui.frame.hide() self._item.setSizeHint(self.sizeHint()) self._downloading = False if success and self._openFile: self.__openFile() self.downloadFinished.emit(True) def _downloadProgress(self, received, total): ''' @param: received qint64 @param: total qint64 ''' if self.DEBUG: print('DEBUG: %s::_downloadProgress %s %s' % (self.__class__.__name__, received, total)) currentValue = 0 totalValue = 0 if total > 0: currentValue = received * 100 / total totalValue = 100 self._ui.progressBar.setValue(currentValue) self._ui.progressBar.setMaximum(totalValue) self._currSpeed = received * 1000.0 / self._downTimer.elapsed() self._received = received self._total = total self._updateDownloadInfo(self._currSpeed, self._received, self._total) def _stop(self): if self.DEBUG: print('DEBUG: %s::_stop' % self.__class__.__name__) self._downloadStopped = True self._ui.progressBar.hide() self._ui.button.hide() self._item.setSizeHint(self.sizeHint()) self._ui.downloadInfo.setText( _('Cancelled - %s') % self._download.url().host()) self._download.cancel() self._downloading = False self.downloadFinished.emit(False) def __openFile(self): if self._downloading: return fpath = pathjoin(self._path, self._fileName) if pathexists(fpath): QDesktopServices.openUrl(QUrl.fromLocalFile(abspath(fpath))) else: QMessageBox.warning( self._item.listWidget().parentWidget(), _("Not found"), _("Sorry, the file \n %s \n was not found!") % abspath(fpath)) def _openFolder(self): if const.OS_WIN: winFileName = '%s/%s' % (self._path, self._fileName) if self._downloading: winFileName += '.download' winFileName = winFileName.replace('/', '\\') shExArg = '/e,/select,"%s"' % winFileName system('explorer.exe ' + shExArg) else: QDesktopServices.openUrl(QUrl.fromLocalFile(self._path)) def _customContextMenuRequested(self, pos): ''' @param: pos QPoint ''' menu = QMenu() menu.addAction(QIcon.fromTheme('document-open'), _('Open File'), self.__openFile) menu.addAction(_('Open Folder'), self._openFolder) menu.addSeparator() menu.addAction(QIcon.fromTheme('edit-copy'), _('Copy Download Link'), self._copyDownloadLink) menu.addSeparator() menu.addAction(QIcon.fromTheme('process-stop'), _('Cancel downloading'), self._stop).setEnabled(self._downloading) menu.addAction(QIcon.fromTheme('list-remove'), _('Remove From List'), self._clear).setEnabled(not self._downloading) if self._downloading or self._ui.downloadInfo.text().startswith(_('Cancelled')) or \ self._ui.downloadInfo.text().startswith(_('Error')): menu.actions()[0].setEnabled(False) menu.exec_(self.mapToGlobal(pos)) def _clear(self): self.deleteItem.emit(self) def _copyDownloadLink(self): url = self._downUrl.toString() print(url) QApplication.clipboard().setText(url) # private: def _updateDownloadInfo(self, currSpeed, received, total): ''' @param: currSpeed double @param: received qint64 @param: total qint64 ''' if self.DEBUG: print('DEBUG: %s::_updateDownloadInfo %s %s %s' % (self.__class__.__name__, currSpeed, received, total)) # QString QString QString QString # | m_remTime | |m_currSize| |m_fileSize| |m_speed| # Remaining 26 minutes - 339MB of 693 MB (350kB/s) if currSpeed == 0: currSpeed = 1 estimatedTime = ((total - received) / 1024) / (currSpeed / 1024) speed = self.currentSpeedToString(currSpeed) # We have QString speed now time = QTime(0, 0, 0) time = time.addSecs(estimatedTime) remTime = self.remaingTimeToString(time) self._remTime = time currSize = gVar.appTools.fileSizeToString(received) fileSize = gVar.appTools.fileSizeToString(total) if fileSize == _('Unkown size'): self._ui.downloadInfo.setText( _('%s - unkown size (%s)') % (currSize, speed)) else: self._ui.downloadInfo.setText( _('Remaining %s - %s of %s (%s)') % (remTime, currSize, fileSize, speed)) def mouseDoubleClickEvent(self, event): ''' @param: event QMouseEvent ''' self.__openFile() event.accept()