def download_button_click(self): flag = False for check_box in self.check_box_list: if check_box.isChecked(): constant.SERVICE.parse_image(self.comic_info, check_box.property("chapter_info"), self.load_download_task_signa.emit) if not flag: QMessageBox.information(self, "下载通知", "正在解析选中章节", QMessageBox.StandardButton.Yes) flag = True
def deleteRowFromTable(self): """Using the view's selection model, find out which row is selected and remove it.""" if self.selectionModel().hasSelection(): index = self.selectionModel().currentIndex() self.model.removeRow(index.row(), index) else: QMessageBox.information(self, "No Row Selected", "No row selected for deletion.")
def show_trial_over_and_die(self): QMessageBox.information( self, "Trial Over", "Your trial period is over. Please purchase Blobbackup to continue using it.", ) self.logger.info("Trial over displayed.") webbrowser.open(PAYMENT_URL) sys.exit()
def accept(self, success, message): self.set_elements_enabled(True) self.loading_dialog.hide() if not success: QMessageBox.warning(self, "Change Password Failed", message) self.logger.info("Change password failed displayed") return self.logger.info("Changed password") QMessageBox.information(self, "Password Changed", "Password successfully changed.") super().accept()
def wrapper(self, *args, **kwargs): try: return func(self, *args, **kwargs) except Exception as e: if isinstance(e, serial.serialutil.SerialException): self.disable_widgets() self.clear_servo() self.port_refresh_button_clicked(None) QMessageBox.critical(None, "Error", "Disconnected from device") else: QMessageBox.information(None, "Error", str(e))
def removeRow(self, row, index): """Remove a row the model. Call values_edited to update the totals in the Money Left Over table.""" if self._data != [] and index.row() != len(self._data) - 1: self._data.pop(row) else: QMessageBox.information(QApplication.activeWindow(), "No Row Selected", "No row selected for deletion.") self.values_edited.emit() self.layoutChanged.emit() return True
def generate(self): temp_cfg = open('_tempcfg.json', 'w') cfg = self.get_current_configuration() json.dump(cfg, temp_cfg, indent=4) temp_cfg.close() generate_header('_tempcfg.json') os.remove('_tempcfg.json') QMessageBox.information(self, "Success", "File Generated Successfully!", QMessageBox.StandardButton.Ok, QMessageBox.StandardButton.Ok)
def start_clicked(self): dir = self.download_dir.text() if not dir: QMessageBox.information(self, "错误","请输入存储目录") return if not os.path.exists(dir): os.mkdir(dir) self.thread.dir = dir url = self.url_input.text() print(url) self.thread.url = url pwd = '/'.join(os.getcwd().split('\\'))+'/'+dir btn = QPushButton("删除图片") if pwd not in self.dict: btn.clicked.connect(self.del_pic) self.dict[pwd] = btn self.tableupdate(pwd , self.thread.max_page_num , self.dict[pwd] )
def saveImage(self): """Save the image displayed in the label.""" #TODO: Add different functionality for the way in which the user can save their image. if self.image.isNull() == False: image_file, _ = QFileDialog.getSaveFileName( self, "Save Image", "", "PNG Files (*.png);;JPG Files (*.jpeg *.jpg );;Bitmap Files (*.bmp);;\ GIF Files (*.gif)") if image_file and self.image.isNull() == False: self.image.save(image_file) else: QMessageBox.information(self, "Error", "Unable to save image.", QMessageBox.Ok) else: QMessageBox.information(self, "Empty Image", "There is no image to save.", QMessageBox.Ok)
def exec(self): s = QApplication.clipboard().text() if QMessageBox.information(self, 'exec', s, QMessageBox.Ok | QMessageBox.Cancel) != QMessageBox.Ok: return try: exec(s) except BaseException as e: logger.exception(e)
def inherit_backup_history(self): email = config["meta"]["email"] if verify_password(email): password = get_password_from_keyring() choose_computer_dialog = ChooseComputerDialog( email, password, "Choose the computer to inherit backup history from.", ) if choose_computer_dialog.exec(): computer_id = choose_computer_dialog.computer_id computer = get_computer(email, password, computer_id) computer_name = computer["name"] reply = QMessageBox.information( self, "Inherit Backup History?", f"You are about to inherit the backup history of the computer '{computer_name}'. Your current computer's backups will be replaced by the backups of '{computer_name}'. This is an irreversible operation. Continue?", QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No, QMessageBox.StandardButton.No, ) if reply == QMessageBox.StandardButton.Yes: self.main_window.stop_backup() current_computer_id = config["meta"]["computer_id"] inherit_computer(email, password, computer_id, current_computer_id) QMessageBox.information( self, "Inherited Backup History", f"Successfully inherited the backup history of '{computer_name}'. Note that settings like inclusions, exclusions, schedule, etc. were not inherited.", ) save_last_backed_up( "Backup history inherited. Creating first backup of this computer." ) if computer["last_backed_up_at"]: save_selected_files( format_selected_files( int(computer["last_backed_up_num_files"]), int(computer["last_backed_up_size"]), ) ) self.main_window.toggle_backup() self.reject()
def save_to_file(self, configuration: Union[Dict[str, Any], None], out_file_path: str) -> None: if configuration is None: return try: if not out_file_path: return file = open(out_file_path, 'w') json.dump(configuration, file, indent=4) file.close() QMessageBox.information(self, 'Success', 'Configuration Saved Successfully!', QMessageBox.StandardButton.Ok, QMessageBox.StandardButton.Ok) except IOError: QMessageBox.critical(self, 'Failure', 'Unexpected Error Occurred', QMessageBox.StandardButton.Ok, QMessageBox.StandardButton.Ok)
def displayItemValues(self): """Simple method that demonstrates how to retrieve the values from the widgets.""" # Get the model index of the item (in this case the view_button) # at the viewport coordinates index = self.table_view.indexAt( self.pos()) # Get the index of the button pushed row = index.row() # Get the row of that button # Use the row value to get the index of the cells in that row, column 1 widget_index = self.table_view.model().sibling(row, 1, QModelIndex()) # Use indexWidget to get the QDateEdit widget date_edit_widget = self.table_view.indexWidget(widget_index) # Get value from the cell in column 0 for the selected row name = self.table_view.model().sibling(row, 0, QModelIndex()).data() # Display name and date in a QMessageBox QMessageBox.information( self, "User Information", f"""Name: {name}<br> <b>Birthdate: </b>{date_edit_widget.date().toString("MM/dd/yyyy")}""" )
def check_update(self, test=False): try: release = github.get_latest_release(Const.author, Const.app_name, timeout=5) Log.append(self.check_update, 'Info', release) if test or common.compare_version(Const.version, release['tag_name']): if len(release['assets']) > 0: QMessageBox.information( self.lang.title_check_update, '%s\n%s\n\n%s' % (self.lang.description_new_version, release['body'], release['assets'][0]['browser_download_url'])) else: QMessageBox.information( self.lang.title_check_update, '%s\n%s\n\n%s' % (self.lang.description_new_version, release['body'], release['assets'][0]['browser_download_url'])) except: Log.append(self.check_update, 'Warning', common.get_exception())
def quit_application(self): reply = QMessageBox.information( self, "Quit Blobbackup?", "Are you sure you want to quit Blobbackup?", QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No, QMessageBox.StandardButton.No, ) if reply == QMessageBox.StandardButton.Yes: if self.backup_thread.backup_running(): self.backup_thread.stop_backup() self.logger.info("Quit application.") sys.exit()
def openImage(self): """Load a new image into the """ image_file, _ = QFileDialog.getOpenFileName( self, "Open Image", "", "PNG Files (*.png);;JPG Files (*.jpeg *.jpg );;Bitmap Files (*.bmp);;\ GIF Files (*.gif)") if image_file: # Reset values when opening an image self.parent.zoom_factor = 1 #self.parent.scroll_area.setVisible(True) self.parent.print_act.setEnabled(True) self.parent.updateActions() # Reset all sliders self.parent.brightness_slider.setValue(0) # Get image format image_format = self.image.format() self.image = QImage(image_file) self.original_image = self.image.copy() #pixmap = QPixmap(image_file) self.setPixmap(QPixmap().fromImage(self.image)) #image_size = self.image_label.sizeHint() self.resize(self.pixmap().size()) #self.scroll_area.setMinimumSize(image_size) #self.image_label.setPixmap(pixmap.scaled(self.image_label.size(), # Qt.KeepAspectRatio, Qt.SmoothTransformation)) elif image_file == "": # User selected Cancel pass else: QMessageBox.information(self, "Error", "Unable to open image.", QMessageBox.Ok)
def restore(self): path = QFileDialog.getExistingDirectory() if path: reply = QMessageBox.information( self, "Start Restore?", f"You are about to restore to {path}. Blobbackup will OVERWRITE any conflicting files. Continue?", QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No, QMessageBox.StandardButton.No, ) if reply == QMessageBox.StandardButton.Yes: snapshot_id = self.snapshots_combo_box.currentData() self.restoring_gui_state() self.restore_thread = RestoreThread( self.email, self.password, self.computer_id, snapshot_id, path, self.snapshot_tree_widget, ) self.restore_thread.restored.connect(self.restored) self.restore_thread.failed.connect(self.restore_failed) self.restore_thread.start()
def saveGraphics(self): dbfilename = self.obsTb.dbFilename if dbfilename != None: self.session = connectDatabase(dbfilename) else: msg = QMessageBox() msg.setIcon(QMessageBox.Information) msg.setText('The database file is not defined.') msg.setInformativeText( 'In order to set the database file, open the Observation Toolbox' ) msg.setIcon(QMessageBox.Critical) msg.exec_() return if self.gView.unsavedLines == [] and self.gView.unsavedZones == [] and \ self.gView.unsavedPoints == []: QMessageBox.information(self, 'Save', 'No new graphical items to save!') return for item in self.gView.unsavedLines: x1 = round(item.line().x1(), 2) y1 = round(item.line().y1(), 2) x2 = round(item.line().x2(), 2) y2 = round(item.line().y2(), 2) line = Line(None, None, x1, y1, x2, y2) self.session.add(line) self.session.flush() label = self.generate_itemGroup([x1, x2], [y1, y2], line.idx) self.gView.scene().addItem(label) for item in self.gView.unsavedZones: xs = [] ys = [] for p in item.polygon(): xs.append(round(p.x(), 2)) ys.append(round(p.y(), 2)) zone = Zone(None, None, xs, ys) self.session.add(zone) self.session.flush() label = self.generate_itemGroup(xs, ys, zone.idx) self.gView.scene().addItem(label) for item in self.gView.unsavedPoints: x = round(item.rect().center().x(), 2) y = round(item.rect().center().y(), 2) point = Point(x, y) self.session.add(point) self.session.flush() label = self.generate_itemGroup([x], [y], point.idx) self.gView.scene().removeItem(item) self.gView.scene().addItem(label) QMessageBox.information( self, 'Save', '{} point(s), {} line(s) and {} zone(s) saved to database successfully!' .format(len(self.gView.unsavedPoints), len(self.gView.unsavedLines), len(self.gView.unsavedZones))) self.gView.unsavedLines = [] self.gView.unsavedZones = [] self.gView.unsavedPoints = [] self.session.commit()
def restored(self, target): self.reset_gui_state() QMessageBox.information(self, "Restore Complete", f"Your files have been restored to {target}.")
def loadGraphics(self): dbfilename = self.obsTb.dbFilename if dbfilename != None: self.session = connectDatabase(dbfilename) else: msg = QMessageBox() # msg.setIcon(QMessageBox.Icon.Information) msg.setText('The database file is not defined.') msg.setInformativeText( 'In order to set the database file, open the Observation Toolbox' ) msg.setIcon(QMessageBox.Icon.Critical) msg.exec() return for gitem in self.gView.scene().items(): if isinstance(gitem, QGraphicsItemGroup): self.gView.scene().removeItem(gitem) q_line = self.session.query(Line) q_zone = self.session.query(Zone) if q_line.all() == [] and q_zone.all() == []: QMessageBox.information(self, 'Warning!', 'There is no graphics to load!') return line_items = [] for line in q_line: p1 = line.points[0] p2 = line.points[1] if line.type != None: lineType = line.type.name else: lineType = None gItmGroup = self.generate_itemGroup([p1.x, p2.x], [p1.y, p2.y], str(line.idx), lineType) self.gScene.addItem(gItmGroup) line_items.append(str(line.idx)) self.obsTb.line_list_wdgt.clear() self.obsTb.line_list_wdgt.addItems(line_items) self.obsTb.line_list_wdgt.setCurrentRow(0) self.obsTb.line_newRecButton.setEnabled(False) self.obsTb.line_saveButton.setEnabled(True) self.obsTb.line_saveButton.setText('Edit line(s)') self.obsTb.line_saveButton.setIcon(QIcon('icons/edit.png')) zone_items = [] for zone in q_zone: if zone.type != None: zoneType = zone.type.name else: zoneType = None gItmGroup = self.generate_itemGroup( [point.x for point in zone.points], [point.y for point in zone.points], str(zone.idx), zoneType) self.gScene.addItem(gItmGroup) zone_items.append(str(zone.idx)) self.obsTb.zone_list_wdgt.clear() self.obsTb.zone_list_wdgt.addItems(zone_items) self.obsTb.zone_list_wdgt.setCurrentRow(0) self.obsTb.zone_newRecButton.setEnabled(False) self.obsTb.zone_saveButton.setEnabled(True) self.obsTb.zone_saveButton.setText('Edit zone(s)') self.obsTb.zone_saveButton.setIcon(QIcon('icons/edit.png'))
class B23Download(QWidget): def __init__(self): super(B23Download, self).__init__() # setup some flags self.is_fetching = False self.is_downloading = False # default output path basepath = os.path.dirname(os.path.abspath(__file__)) path = os.path.join(basepath, "videos") self.output_path = path # setup some window specific things self.setWindowTitle("Bilibili Favorite Downloader") self.setWindowIcon(QIcon("images/icon_bilibili.ico")) self.setFixedSize(705, 343) # parent layout main_layout = QVBoxLayout() main_layout.setContentsMargins(15, 15, 15, 10) self.setLayout(main_layout) # top bar layout top_layout = QHBoxLayout() # detail section mid_main_layout = QHBoxLayout() mid_right_layout = QVBoxLayout() # download section bottom_main_layout = QHBoxLayout() bottom_right_layout = QVBoxLayout() # output path link button self.output_btn = QPushButton("📂 Output Path") self.output_btn.setCursor(QCursor(Qt.CursorShape.PointingHandCursor)) self.output_btn.setToolTip(self.output_path) self.output_btn.clicked.connect(self.set_output_path) # status bar self.status_bar = QStatusBar() # message box self.message_box = QMessageBox() # setting up widgets self.url_edit = QLineEdit() self.url_edit.setPlaceholderText("🔍 Enter or paste favorite URL...") self.get_btn = QPushButton("Get") self.get_btn.setCursor(QCursor(Qt.CursorShape.PointingHandCursor)) self.get_btn.clicked.connect(self.get_details) # thumbnail pixmap = QPixmap("images/placeholder.png") self.thumb = QLabel() self.thumb.setFixedSize(250, 141) self.thumb.setScaledContents(True) self.thumb.setPixmap(pixmap) # detail widgets self.title = QLabel("Title: ") self.author = QLabel("Author: ") self.length = QLabel("Videos: ") self.publish_date = QLabel("Published: ") # progress bar self.progress_bar = QProgressBar() # download options self.download_btn = QPushButton(" Download Videos ") self.download_btn.setCursor(QCursor(Qt.CursorShape.PointingHandCursor)) self.download_btn.clicked.connect(self.get_content) self.download_btn.setEnabled(False) self.download_btn.setShortcut("Ctrl+Return") self.download_btn.setMinimumWidth(200) # add widgets and layouts top_layout.addWidget(self.url_edit) top_layout.addWidget(self.get_btn) # detail section mid_right_layout.addWidget(self.title) mid_right_layout.addWidget(self.author) mid_right_layout.addWidget(self.length) mid_right_layout.addWidget(self.publish_date) mid_main_layout.addWidget(self.thumb) mid_main_layout.addSpacing(20) mid_main_layout.addLayout(mid_right_layout) # download section bottom_right_layout.addWidget(self.download_btn) bottom_main_layout.addWidget(self.progress_bar) bottom_main_layout.addSpacing(10) bottom_main_layout.addLayout(bottom_right_layout) # status bar self.status_bar.setSizeGripEnabled(False) self.status_bar.addPermanentWidget(self.output_btn) # add content to parent layout main_layout.addLayout(top_layout) main_layout.addSpacing(20) main_layout.addLayout(mid_main_layout) main_layout.addSpacing(5) main_layout.addLayout(bottom_main_layout) main_layout.addWidget(self.status_bar) # set output path slot def set_output_path(self): # update the output path path = str( QFileDialog.getExistingDirectory(self, "Select Output Directory")) if path: self.output_path = path # update tooltip self.output_btn.setToolTip(path) # get button slot def get_details(self): text = self.url_edit.text().strip() if not text: return if text.find("fid") < 0: self.message_box.warning( self, "Error", ("Input a correct favorite URL!\n" "For example: https://space.bilibili.com/xxx/favlist?fid=xxx..." ), ) return if self.get_btn.text() == "Get": self.get_btn.setText("Stop") # indicate progress bar as busy self.progress_bar.setRange(0, 0) # set fetching flag self.is_fetching = True # setup a worker thread to keep UI responsive self.media_id = text.split("fid=")[-1].split("&")[0] self.worker = WorkerThread(self.media_id) self.worker.start() # catch the finished signal self.worker.finished.connect(self.finished_slot) # catch the response signal self.worker.worker_response.connect(self.response_slot) # catch the error signal self.worker.worker_err_response.connect(self.err_slot) elif self.get_btn.text() == "Stop": if self.is_fetching: # stop worker thread self.worker.terminate() # set back the get_btn text self.get_btn.setText("Get") elif self.is_downloading: # stop download thread self.download_thread.terminate() # show the warning message_box self.message_box.information( self, "Interrupted", "Download interrupted!\nThe process was aborted while the file was being downloaded... ", ) # reset progress bar self.progress_bar.reset() # download options slot def get_content(self): if self.is_fetching: # show the warning message self.message_box.critical( self, "Error", "Please wait!\nWait while the details are being fetched... ", ) else: # disable the download options self.download_btn.setDisabled(True) # set downloading flag self.is_downloading = True # set button to stop self.get_btn.setText("Stop") self.download_thread = DownloadThread( self.media_id, self.media_counts, self.first_page_medias, self.output_path, ) # start the thread self.download_thread.start() # catch the finished signal self.download_thread.finished.connect(self.download_finished_slot) # catch the response signal self.download_thread.download_response.connect( self.download_response_slot) # catch the complete signal self.download_thread.download_complete.connect( self.download_complete_slot) # catch the error signal self.download_thread.download_err.connect(self.download_err_slot) # handling enter key for get/stop button def keyPressEvent(self, event): self.url_edit.setFocus() if (event.key() == Qt.Key.Key_Enter.value or event.key() == Qt.Key.Key_Return.value): self.get_details() # finished slot def finished_slot(self): # remove progress bar busy indication self.progress_bar.setRange(0, 100) # unset fetching flag self.is_fetching = False # response slot def response_slot(self, res): # set back the button text self.get_btn.setText("Get") # set the actual thumbnail of requested video self.thumb.setPixmap(res.thumb_img) # slice the title if it is more than the limit if len(res.title) > 50: self.title.setText(f"Title: {res.title[:50]}...") else: self.title.setText(f"Title: {res.title}") # cache first page medias self.first_page_medias = res.medias self.media_counts = res.media_counts # set leftover details self.author.setText(f"Author: {res.author}") self.length.setText(f"Videos: {res.media_counts}") self.publish_date.setText( f'Published: {time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(res.publish_date))}' ) self.download_btn.setDisabled(False) # error slot def err_slot(self): # show the warning message self.message_box.warning( self, "Warning", "Something went wrong!\nProbably a broken link or some restricted content... ", ) # set back the button text self.get_btn.setText("Get") # download finished slot def download_finished_slot(self): # set back the button text self.get_btn.setText("Get") # now enable the download options self.download_btn.setDisabled(False) # unset downloading flag self.is_downloading = False # reset pogress bar self.progress_bar.reset() # download response slot def download_response_slot(self, per): # update progress bar self.progress_bar.setValue(per) # adjust the font color to maintain the contrast if per > 52: self.progress_bar.setStyleSheet("QProgressBar { color: #fff }") else: self.progress_bar.setStyleSheet("QProgressBar { color: #000 }") # download complete slot def download_complete_slot(self, location): # use native separators location = QDir.toNativeSeparators(location) # show the success message if (self.message_box.information( self, "Downloaded", f"Download complete!\nFile was successfully downloaded to :\n{location}\n\nOpen the downloaded file now ?", QMessageBox.StandardButtons.Open, QMessageBox.StandardButtons.Cancel, ) is QMessageBox.StandardButtons.Open): subprocess.Popen(f"explorer /select,{location}") # download error slot def download_err_slot(self): # show the error message self.message_box.critical( self, "Error", "Error!\nSomething unusual happened and was unable to download...", )
def About(self): QMessageBox.information(self, 'About', 'Menu Example 0.4')
def restore_failed(self): self.setWindowTitle("Restore Files - Blobbackup") self.set_elements_enabled(True) QMessageBox.information( self, "Restore Failed", "Blobbackup was unable to restore your files.")
class YTdownloader(QWidget): def __init__(self): super().__init__() # setup some flags self.isFetching = False self.isDownloading = False # default output path self.outputPath = f'{QDir.homePath()}/videos' # setup some window specific things self.setWindowTitle('YouTube Downloader') self.setWindowIcon(QIcon('assets/yt-icon.ico')) self.setFixedSize(705, 343) # parent layout layout = QVBoxLayout() layout.setContentsMargins(15, 15, 15, 10) self.setLayout(layout) # top bar layout topBar = QHBoxLayout() # detail section detailSec = QHBoxLayout() metaSec = QVBoxLayout() # download section downloadSec = QHBoxLayout() downloadBtn = QVBoxLayout() # output path link button self.outputBtn = QPushButton('📂 Output Path') self.outputBtn.setCursor(QCursor(Qt.CursorShape.PointingHandCursor)) self.outputBtn.setToolTip(self.outputPath) self.outputBtn.clicked.connect(self.setOutputPath) # status bar self.statusBar = QStatusBar() # message box self.message = QMessageBox() # setting up widgets self.urlBox = QLineEdit() self.urlBox.setFocusPolicy(Qt.FocusPolicy.ClickFocus or Qt.FocusPolicy.NoFocus) self.urlBox.setPlaceholderText('🔍 Enter or paste video URL...') self.button = QPushButton('Get') self.button.setDefault(True) self.button.setCursor(QCursor(Qt.CursorShape.PointingHandCursor)) self.button.clicked.connect(self.getDetails) # thumbnail pixmap = QPixmap('assets\placeholder.jpg') self.thumb = QLabel() self.thumb.setFixedSize(250, 141) self.thumb.setScaledContents(True) self.thumb.setPixmap(pixmap) # detail widgets self.title = QLabel('Title: ') self.author = QLabel('Author: ') self.length = QLabel('Duration: ') self.publish_date = QLabel('Published: ') # progress bar self.progress_bar = QProgressBar() # download options self.download = QComboBox() self.download.setPlaceholderText('Download Video') self.download.setCursor(QCursor(Qt.CursorShape.PointingHandCursor)) self.download.activated.connect(lambda: self.getContent(0)) self.download.setEnabled(False) # download audio button self.download_audio = QPushButton('Download Audio') self.download_audio.setCursor(QCursor(Qt.CursorShape.PointingHandCursor)) self.download_audio.clicked.connect(lambda: self.getContent(1)) self.download_audio.setEnabled(False) # add widgets and layouts topBar.addWidget(self.urlBox) topBar.addWidget(self.button) # detail section metaSec.addWidget(self.title) metaSec.addWidget(self.author) metaSec.addWidget(self.length) metaSec.addWidget(self.publish_date) detailSec.addWidget(self.thumb) detailSec.addSpacing(20) detailSec.addLayout(metaSec) # download section downloadBtn.addWidget(self.download) downloadBtn.addWidget(self.download_audio) downloadSec.addWidget(self.progress_bar) downloadSec.addSpacing(10) downloadSec.addLayout(downloadBtn) # status bar self.statusBar.setSizeGripEnabled(False) self.statusBar.addPermanentWidget(self.outputBtn) # add content to parent layout layout.addLayout(topBar) layout.addSpacing(20) layout.addLayout(detailSec) layout.addSpacing(5) layout.addLayout(downloadSec) layout.addWidget(self.statusBar) # setup a connection thread to keep checking internet connectivity self.connection = ConnectionThread() self.connection.start() # catch the connection response signal self.connection.con_response.connect(self.connection_slot) # connection slot def connection_slot(self, status): curMsg = self.statusBar.currentMessage() # connection succeeded if status: if curMsg == '🔴 Disconnected': self.statusBar.showMessage('🟢 Connection restored!', 3000) elif curMsg != '🟢 Connected': self.statusBar.showMessage('🟢 Connected') # connection failed elif curMsg == '🟢 Connected': self.statusBar.showMessage('🔴 Connection interrupted!', 3000) elif curMsg != '🔴 Disconnected': self.statusBar.showMessage('🔴 Disconnected') # set output path slot def setOutputPath(self): # update the output path path = str(QFileDialog.getExistingDirectory(self, "Select Output Directory")) if path: self.outputPath = path # update tooltip self.outputBtn.setToolTip(path) # get button slot def getDetails(self): curMsg = self.statusBar.currentMessage() if curMsg == '🔴 Disconnected' or curMsg == '🔴 Connection interrupted!': self.message.critical( self, 'Error', 'Connection failed!\nAre you sure you\'re connected to the internet ? ' ) elif self.button.text() == 'Get': self.button.setText('Stop') # indicate progress bar as busy self.progress_bar.setRange(0, 0) # set fetching flag self.isFetching = True # setup a worker thread to keep UI responsive self.worker = WorkerThread(self.urlBox.text()) self.worker.start() # catch the finished signal self.worker.finished.connect(self.finished_slot) # catch the response signal self.worker.worker_response.connect(self.response_slot) # catch the error signal self.worker.worker_err_response.connect(self.err_slot) elif self.button.text() == 'Stop': if self.isFetching: # stop worker thread self.worker.terminate() # set back the button text self.button.setText('Get') elif self.isDownloading: # stop download thread self.download_thread.terminate() # show the warning message self.message.information( self, 'Interrupted', 'Download interrupted!\nThe process was aborted while the file was being downloaded... ' ) # reset pogress bar self.progress_bar.reset() # download options slot def getContent(self, id): if self.isFetching: # show the warning message self.message.warning( self, 'Warning', 'Please wait!\nWait while the details are being fetched... ' ) else: # disable the download options self.download.setDisabled(True) self.download_audio.setDisabled(True) # set downloading flag self.isDownloading = True # set button to stop self.button.setText('Stop') # setup download thread if id == 0: self.download_thread = DownloadThread(self.yt, self.download.currentText()[:4], self.outputPath) else: self.download_thread = DownloadThread(self.yt, 'audio', self.outputPath) # start the thread self.download_thread.start() # catch the finished signal self.download_thread.finished.connect(self.download_finished_slot) # catch the response signal self.download_thread.download_response.connect(self.download_response_slot) # catch the complete signal self.download_thread.download_complete.connect(self.download_complete_slot) # catch the error signal self.download_thread.download_err.connect(self.download_err_slot) # finished slot def finished_slot(self): # remove progress bar busy indication self.progress_bar.setRange(0, 100) # unset fetching flag self.isFetching = False # response slot def response_slot(self, res): # set back the button text self.button.setText('Get') # save the yt object for speeding up download self.yt = res[0] # set the actual thumbnail of requested video self.thumb.setPixmap(res[1]) # slice the title if it is more than the limit if len(res[2]) > 50: self.title.setText(f'Title: {res[2][:50]}...') else: self.title.setText(f'Title: {res[2]}') # set leftover details self.author.setText(f'Author: {res[3]}') self.length.setText(f'Duration: {timedelta(seconds=res[4])}') self.publish_date.setText(f'Published: {res[5].strftime("%d/%m/%Y")}') # clear any previous items if any self.download.clear() # add resolutions as items to the download button and enable them self.download.addItems([item for item in res[6]]) self.download.setDisabled(False) self.download_audio.setDisabled(False) # error slot def err_slot(self): # show the warning message self.message.warning( self, 'Warning', 'Something went wrong!\nProbably a broken link or some restricted content... ' ) # set back the button text self.button.setText('Get') # download finished slot def download_finished_slot(self): # set back the button text self.button.setText('Get') # now enable the download options self.download.setDisabled(False) self.download_audio.setDisabled(False) # unset downloading flag self.isDownloading = False # reset pogress bar self.progress_bar.reset() # download response slot def download_response_slot(self, per): # update progress bar self.progress_bar.setValue(per) # adjust the font color to maintain the contrast if per > 52: self.progress_bar.setStyleSheet('QProgressBar { color: #fff }') else: self.progress_bar.setStyleSheet('QProgressBar { color: #000 }') # download complete slot def download_complete_slot(self, location): # use native separators location = QDir.toNativeSeparators(location) # show the success message if self.message.information( self, 'Downloaded', f'Download complete!\nFile was successfully downloaded to :\n{location}\n\nOpen the downloaded file now ?', QMessageBox.StandardButtons.Open, QMessageBox.StandardButtons.Cancel ) is QMessageBox.StandardButtons.Open: subprocess.Popen(f'explorer /select,{location}') # download error slot def download_err_slot(self): # show the error message self.message.critical( self, 'Error', 'Error!\nSomething unusual happened and was unable to download...' )
def about(self): QMessageBox.information(self, 'About', 'Basic Editor 0.3')