def showTime(self): # print(self.time.elapsed()) tt = QTime(0, 0, 0) tt = tt.addMSecs(self.time.elapsed()) text = tt.toString("hh:mm:ss") # print(text) self.display(text)
def positionChanged(self, position): self.positionSlider.setValue(position) # This update time label from position in ms mtime = QTime(0, 0, 0, 0) mtime = mtime.addMSecs(self.mediaPlayer.position()) self.timer.setText(mtime.toString()) return
class ShowTime(QWidget): def __init__(self): super().__init__() self.isTimeStart = False # 标记时间是否开始计时 self.setWindowTitle("QLable 显示计时时间") self.lable_time = QLabel('运行时间:', self) self.lable_time_val = QLabel('00:00:00', self) self.btn_start = QPushButton('开始显示') self.btn_stop = QPushButton('停止计时') # 布局 self.mainLayout = QGridLayout(self) self.mainLayout.addWidget(self.lable_time, 0, 0, 1, 1) self.mainLayout.addWidget(self.lable_time_val, 0, 1, 1, 2) self.mainLayout.addWidget(self.btn_start, 1, 1, 1, 1) self.mainLayout.addWidget(self.btn_stop, 1, 2, 1, 1) # 创建定时器对象和时间对象 self.timer = QTimer() # self.timeClock = QTime() # 信号与槽 self.btn_start.clicked.connect(self.timestart) self.timer.timeout.connect(self.addtime) self.btn_stop.clicked.connect(self.timestop) def timestart(self): # 启动计时 if not self.isTimeStart: self.timeClock.setHMS(0, 0, 0) # 初始时设置时间为 00:00:00 self.timer.start(1000) # 启动定时器,定时器对象每隔一秒发射一个timeout信号 self.isTimeStart = True def addtime(self): # 计时时间增一秒,并显示在QLable上 self.timeClock = self.timeClock.addMSecs(1000) # 时间增加一秒 self.lable_time_val.setText( self.timeClock.toString("hh:mm:ss")) # 标签显示时间 def timestop(self): # 停止计时 if self.isTimeStart: self.timer.stop() self.isTimeStart = False
class ShowTime(QWidget): def __init__(self, parent=None): super(ShowTime, self).__init__(parent) self.isTimeStart = False # 标记时间是否开始计时 self.lcd = QLCDNumber(self) self.lcd.setDigitCount(8) self.lcd.display("00:00:00") # 创建定时器对象和时间对象 self.timer = QTimer() # self.timeClock = QTime() # 信号与槽 # self.btn_start.clicked.connect(self.timestart) self.timer.timeout.connect(self.addtime) # self.btn_stop.clicked.connect(self.timestop) self.v_layout = QVBoxLayout() self.v_layout.addWidget(self.lcd) self.setLayout(self.v_layout) def back_to_zero(self): self.lcd.setDigitCount(8) self.lcd.display("00:00:00") def timestart(self): # 启动计时 if not self.isTimeStart: self.timeClock.setHMS(0, 0, 0) # 初始时设置时间为 00:00:00 self.timer.start(1000) # 启动定时器,定时器对象每隔一秒发射一个timeout信号 self.isTimeStart = True def addtime(self): # 计时时间增一秒,并显示在QLable上 self.timeClock = self.timeClock.addMSecs(1000) # 时间增加一秒 # self.lable_time_val.setText(self.timeClock.toString("hh:mm:ss")) # 标签显示时间 # print(self.timeClock.toString("hh:mm:ss")) self.lcd.display(self.timeClock.toString("hh:mm:ss")) # 标签显示时间 def timestop(self): # 停止计时 if self.isTimeStart: self.timer.stop() self.isTimeStart = False
class StopwatchWidget(QWidget, ClockAssets): # widget containing stopwatch and all methods associated with it def __init__(self): super().__init__() self.window_icon = "timer_assets/timer.png" self.play_icon = "timer_assets/play.png" self.pause_icon = "timer_assets/pause.png" self.reset_icon = "timer_assets/reset.png" self.stopwatch_time = QTime(0, 0, 0, 0) self.stopwatch_is_running = False self.stopwatch = QTimer() self.stopwatch.timeout.connect(self.update_stopwatch) self.init_window() def init_window(self): self.stopwatch_vbox = self.create_stopwatch_window() self.setLayout(self.stopwatch_vbox) # STOPWATCH def create_stopwatch_window(self): self.stopwatch_time_label = QLabel( self.stopwatch_time.toString("hh:mm:ss.zz")) self.stopwatch_time_label.setAlignment(Qt.AlignCenter) self.stopwatch_time_label.setFont(QFont("Arial", 20)) self.reset_stopwatch_button = QPushButton() self.reset_stopwatch_button.setIcon(QIcon(self.reset_icon)) self.reset_stopwatch_button.setFixedWidth(200) self.reset_stopwatch_button.clicked.connect(self.reset_stopwatch) self.toggle_stopwatch_button = QPushButton() self.toggle_stopwatch_button.setIcon(QIcon(self.play_icon)) self.toggle_stopwatch_button.setFixedWidth(200) self.toggle_stopwatch_button.clicked.connect(self.toggle_stopwatch) self.vbox = QVBoxLayout() self.vbox.addWidget(self.stopwatch_time_label) self.vbox.addWidget(self.reset_stopwatch_button, alignment=Qt.AlignHCenter) self.vbox.addWidget(self.toggle_stopwatch_button, alignment=Qt.AlignHCenter) self.vbox.addSpacing(20) return self.vbox def display_stopwatch_time(self): # msec displays the hundreds and tens place only msec = str(int(self.stopwatch_time.msec() / 10)) self.stopwatch_time_label.setText( self.stopwatch_time.toString(f"hh:mm:ss.{msec.ljust(2, '0')}")) def toggle_stopwatch(self): # starts stopwatch if it's not running or # stops stopwatch if it is running if self.stopwatch_is_running: self.stopwatch_is_running = False self.change_stopwatch_button_logo("play") self.stop_stopwatch() else: self.stopwatch_is_running = True self.change_stopwatch_button_logo("pause") self.start_stopwatch() # EFFECT def change_stopwatch_button_logo(self, action): # changes button logo if action == "play": self.toggle_stopwatch_button.setIcon(QIcon(self.play_icon)) elif action == "pause": self.toggle_stopwatch_button.setIcon(QIcon(self.pause_icon)) def start_stopwatch(self): # runs stopwatch self.stopwatch.start(10) def stop_stopwatch(self): # stops stopwatch self.stopwatch.stop() def update_stopwatch(self): # stopwatch's interval is every 10 ms so only the hundreds and tens digits are shown self.stopwatch_time = self.stopwatch_time.addMSecs(10) self.display_stopwatch_time() def reset_stopwatch(self): # resets stopwatch time to zero self.stopwatch_time = QTime(0, 0, 0, 0) self.display_stopwatch_time()
def positionChanged(self, position): self.positionSlider.setValue(position) mtime = QTime(0, 0, 0, 0) mtime = mtime.addMSecs(self.mediaPlayer.position()) self.lbl.setText(mtime.toString())
def writeToExcelp1(self, wb, segsLL, currsp, startTime, precisionMS): if precisionMS: timeStrFormat = "hh:mm:ss.zzz" else: timeStrFormat = "hh:mm:ss" from PyQt5.QtCore import QTime ws = wb['Time Stamps'] r = ws.max_row + 1 for segsl in segsLL: # extract segments for the current species # if species=="All", take ALL segments. if currsp=="Any sound": speciesSegs = segsl else: speciesSegs = [segsl[ix] for ix in segsl.getSpecies(currsp)] if len(speciesSegs)==0: continue if startTime is None: # if no startTime was provided, try to figure it out based on the filename DOCRecording = re.search('(\d{6})_(\d{6})', os.path.basename(segsl.filename)[:-8]) if DOCRecording: print("time stamp found", DOCRecording) startTimeFile = DOCRecording.group(2) startTimeFile = QTime(int(startTimeFile[:2]), int(startTimeFile[2:4]), int(startTimeFile[4:6])) else: startTimeFile = QTime(0,0,0) else: startTimeFile = QTime(0,0,0).addSecs(startTime) # Loop over the segments for seg in speciesSegs: # Print the filename ws.cell(row=r, column=1, value=segsl.filename) # Time limits ws.cell(row=r, column=2, value=str(startTimeFile.addMSecs(seg[0]*1000).toString(timeStrFormat))) ws.cell(row=r, column=3, value=str(startTimeFile.addMSecs(seg[1]*1000).toString(timeStrFormat))) # Freq limits if seg[3]!=0: ws.cell(row=r, column=4, value=int(seg[2])) ws.cell(row=r, column=5, value=int(seg[3])) if currsp=="Any sound": # print species and certainty and call type text = [lab["species"] for lab in seg[4]] ws.cell(row=r, column=6, value=", ".join(text)) text = [str(lab["certainty"]) for lab in seg[4]] ws.cell(row=r, column=7, value=", ".join(text)) strct = [] for lab in seg[4]: if "calltype" in lab: strct.append(str(lab["calltype"])) else: strct.append("-") ws.cell(row=r, column=8, value=", ".join(strct)) else: # only print certainty and call type strcert = [] strct = [] for lab in seg[4]: if lab["species"]==currsp: strcert.append(str(lab["certainty"])) if "calltype" in lab: strct.append(str(lab["calltype"])) else: strct.append("-") ws.cell(row=r, column=6, value=", ".join(strcert)) ws.cell(row=r, column=7, value=", ".join(strct)) r += 1
def displayTime(self): t = QTime(0, 0, 0) displayTxt = t.addMSecs(self.delta.elapsed()).toString('hh:mm:ss') self.newTime.emit(displayTxt)
def durationChanged(self, duration): self.positionSlider.setRange(0, duration) mtime = QTime(0, 0, 0, 0) mtime = mtime.addMSecs(self.mediaPlayer.duration()) self.elbl.setText(mtime.toString())
def position_changed(self, position): self.ui.horizontalSlider_Game_Time.setSliderPosition(position) time = QTime(0, 0) time = time.addMSecs(position) self.ui.label_Game_Position.setText(time.toString("m:ss"))
def duration_changed(self, duration): self.ui.horizontalSlider_Game_Time.setRange(0, duration) time = QTime(0, 0) time = time.addMSecs(duration) self.ui.label_Game_Duration.setText(time.toString("m:ss"))
class VkAudioApp(QtWidgets.QMainWindow, audio_gui.Ui_MainWindow): def __init__(self, info, cookie, keyring): super().__init__() self.setupUi(self) self.help = HelpDialog(self) self.about = AboutDialog(self) self.captchaDialog = CaptchaDialog(self) self.__title__ = self.windowTitle() self.keyring = keyring self.start_dir = os.getcwd() self.clipboard = QtWidgets.qApp.clipboard() try: self.system_tray = QtWidgets.QSystemTrayIcon(QIcon(":/images/logo.ico"), self) self.system_tray.messageClicked.connect(self._maximize_window) self.system_tray.activated.connect(self._maximize_window) self.system_tray.show() except AttributeError: self.system_tray = None self.btnConfirm.clicked.connect(self.get_audio_list) self.search.textChanged.connect(self.search_tracks) self.volumeSlider.sliderMoved.connect(self.change_volume) self.volumeSlider.valueChanged.connect(self.change_volume) self.play_status.sliderMoved.connect(self.change_position) self.pause_button.clicked.connect(self._pause) self.stop_button.clicked.connect(self._stop) self.saveAll.triggered.connect(self.save_all) self.saveWithoutLinks.triggered.connect(self.save_without_links) self.downloadAllTracks.triggered.connect(self.download_all_tracks) self.luckyMe.triggered.connect(self.play_track) self.helpDialog.triggered.connect(self.help.show) self.aboutDialog.triggered.connect(self.about.show) self.captchaDialog.accepted.connect(self.captchaDialog.close) self.exit.triggered.connect(QtWidgets.qApp.exit) self.copyTrackLink = self._create_action( "&Копировать ссылку для скачивания", ":/images/copy.png", "Копировать прямую ссылку на файл аудиозаписи", callback=self.copy_track_link, ) self.playTrack = self._create_action( "&Воспроизвести", ":/images/play.png", "Воспроизвести вудиозапись", callback=self.play_track, ) self.download = self._create_action( "&Скачать", ":/images/download.png", "Скачать выбранные ауиозаписи или всё, если ничего не выбрано", False, callback=self.download_audio_dialog, ) self.sort_by_name = self._create_action("По названию", callback=self._sort_by_name) self.sort_by_artist = self._create_action("По имени исполнителя", callback=self._sort_by_artist) self.sort_tracks.addActions([self.sort_by_name, self.sort_by_artist]) # Инициализация контекстного меню self.context_menu = QtWidgets.QMenu(self) self.context_menu.addActions([self.playTrack, self.download]) self.context_menu.addSeparator() self.context_menu.addAction(self.copyTrackLink) # Инициализация контекстного меню для системного трея self.system_tray_menu = QtWidgets.QMenu(self) self.system_tray_menu.addAction(self.exit) self.system_tray.setContextMenu(self.system_tray_menu) # Конец инициализации контекстного меню self.trackList.itemDoubleClicked.connect(self.play_track) self.trackList.customContextMenuRequested.connect(self._show_context_menu) self.albumsList.itemExpanded.connect(self.on_item_expanded) self.albumsList.customContextMenuRequested.connect(self._show_context_menu) self.albumsList.itemDoubleClicked.connect(self.play_track) self.get_audio_thread = GetAudioListThread(cookie, self) self.get_audio_thread.signal.connect(self.audio_list_received) self.get_audio_thread.str_signal.connect(self.auth_handler) self.get_audio_thread.image_signal.connect(self.captcha_handler) self.download_audio_thread = DownloadAudio() self.download_audio_thread.signal.connect(self.download_finished) self.download_audio_thread.int_signal.connect(lambda x: self.progressBar.setValue(x)) # Инициализация аудиоплеера self.current_volume = 100 self.time = QTime(0, 0) self.mediaPlayer = QMediaPlayer(self) self.mediaPlayer.stateChanged.connect(lambda x: (self.toggle_buttons(True), self.toggle_fields(True))) self.mediaPlayer.positionChanged.connect(self._position_changed) self.statusBar.showMessage("Готов к работе") if info: self.login.setText(info[0]) self.password.setText(info[1]) self.user_link.setText(info[2]) if cookie.match("*\\Temp\\*") or cookie.match("/tmp/*"): message = ( "Не удалось создать папку для хранения куки приложения по пути\n{}\n\n" "Была создана временная папка. После закрытия приложения она будет удалена. " "В следствии этого, при авторизации, если включено, " "после перезапуска приложения будет повторно запрошен " "код подтверждения входа".format(cookie) ) QtWidgets.QMessageBox.warning(self, "Предупреждение", message) self.hidden_tracks = [] self.selected = None self.tracks = None self.string = None self.albums = None self.key = None @pyqtSlot() def get_audio_list(self): self.hidden_tracks.clear() if self.saveData.isChecked(): data = self.login.text() + "|" + self.password.text() + "|" + self.user_link.text() self.keyring.set_password("vk_music_downloader", os.getlogin(), data) else: try: self.keyring.delete_password("vk_music_downloader", os.getlogin()) except PasswordDeleteError: pass self.get_audio_thread.login = self.login.text() self.get_audio_thread.password = self.password.text() self.get_audio_thread.user_link = self.user_link.text() self.get_audio_thread.statusBar = self.statusBar self.get_audio_thread.saveData = self.saveData.isChecked() self.toggle_buttons(False) self.btnConfirm.setEnabled(False) self.trackList.clear() self.albumsList.clear() self.statusBar.showMessage("Процесс получение аудиозаписей начался.\n") self.get_audio_thread.start() @pyqtSlot("PyQt_PyObject") def audio_list_received(self, result): if result and isinstance(result, tuple): self.tracks, self.string, self.albums = result self.statusBar.showMessage( "Список аудиозаписей получен." " Зажмите Ctrl для множественного выбора." "\n{}, {} шт.".format(self.string, len(self.tracks)) ) if self.system_tray: self.system_tray.showMessage(self.__title__, "Список аудиозаписей получен") self.trackList.setEnabled(True) self.albumsList.setEnabled(True) self.toggle_buttons(True) self.btnConfirm.setEnabled(True) for track in self.tracks: self.trackList.addTopLevelItem( QtWidgets.QTreeWidgetItem( self.trackList, [ "%(artist)s — %(title)s" % track, "%(title)s — %(artist)s" % track, ], ) ) for album in self.albums: root = QtWidgets.QTreeWidgetItem(self.albumsList, [album["title"]]) root.setChildIndicatorPolicy(QtWidgets.QTreeWidgetItem.ShowIndicator) root.setFlags(Qt.ItemIsEnabled) self.albumsList.addTopLevelItem(root) self.trackList.hideColumn(1) elif isinstance(result, str): if self.system_tray: self.system_tray.showMessage( self.__title__, "Во время получения аудиозаписей произошла ошибка", QtWidgets.QSystemTrayIcon.Critical, ) self.btnConfirm.setEnabled(True) self.statusBar.showMessage("Ошибка: {}".format(result)) @pyqtSlot() def save_all(self): os.chdir(self.start_dir) directory = QtWidgets.QFileDialog.getSaveFileName(self, "Сохранить всё", self.string, "Text files (*.txt)")[0] if directory and self.tracks and self.string: if not directory.endswith(".txt"): directory += ".txt" self._save_audio_list(directory) self.statusBar.showMessage("Список аудиозаписей сохранен в файл {}".format(directory)) @pyqtSlot() def save_without_links(self): os.chdir(self.start_dir) directory = QtWidgets.QFileDialog.getSaveFileName( self, "Сохранить без ссылок", self.string, "Text files (*.txt)" )[0] if directory and self.tracks and self.string: if not directory.endswith(".txt"): directory += ".txt" self._save_audio_list(directory, save_links=False) self.statusBar.showMessage( "Список аудиозаписей (без ссылок на скачивание) сохранен в файл {}".format(directory) ) @pyqtSlot() def download_audio_dialog(self): os.chdir(self.start_dir) selected = self.trackList.selectedItems() + self.albumsList.selectedItems() selected_tracks = self._get_selected_tracks(selected) directory = QtWidgets.QFileDialog.getExistingDirectory(self, "Выберите папку") if directory: self.download_audio_thread.statusBar = self.statusBar if selected_tracks: self.download_audio_thread.tracks = selected_tracks length = len(selected_tracks) else: self.download_audio_thread.tracks = self.tracks self.download_audio_thread.albums = self.albums length = self._get_tracks_count() self.download_audio_thread.directory = directory self.statusBar.showMessage("Процесс скачивания аудиозаписей начался.") self.progress_label.setEnabled(True) self.progressBar.setEnabled(True) self.progressBar.setMaximum(length) self.downloadAllTracks.setEnabled(False) self.download_audio_thread.start() @pyqtSlot() def download_all_tracks(self): self.trackList.clearSelection() self.albumsList.clearSelection() self.download_audio_dialog() @pyqtSlot("PyQt_PyObject") def download_finished(self, result): self.toggle_buttons(True) if isinstance(result, str): self.statusBar.showMessage(result) if self.system_tray: self.system_tray.showMessage(self.__title__, "Скачивание аудиозаписей завершено") else: if self.system_tray: self.system_tray.showMessage( self.__title__, "Во время скачивания аудиозаписей произошла ошибка", QtWidgets.QSystemTrayIcon.Critical, ) self.statusBar.showMessage("При скачивании произошла ошибка: {}".format(result)) self.download_audio_thread.albums = [] self.download_audio_thread.tracks = None @pyqtSlot() def play_track(self): self.selected = self.trackList.selectedItems() or self.albumsList.selectedItems() selected_tracks = self._get_selected_tracks(self.selected) if not selected_tracks: # Play random track :) track = choice(self.tracks) selected_tracks.append(track) self.selected.append(self.trackList.findItems("%(artist)s — %(title)s" % track, Qt.MatchContains)[0]) local = QUrl(selected_tracks[0]["url"]) media = QMediaContent(local) self.mediaPlayer.setMedia(media) self.mediaPlayer.play() self.toggle_fields(False) self.trackList.clearSelection() @pyqtSlot(str) def search_tracks(self, query=None): for i in self.hidden_tracks: i.setHidden(False) self.hidden_tracks.clear() result = [i.text(0) for i in self.trackList.findItems(query, Qt.MatchContains)] + [ i.text(0) for i in self.albumsList.findItems(query, Qt.MatchContains) ] for i in range(self.trackList.topLevelItemCount()): if not self.trackList.topLevelItem(i).text(0) in result: self.hidden_tracks.append(self.trackList.topLevelItem(i)) self.trackList.topLevelItem(i).setHidden(True) for i in range(self.albumsList.topLevelItemCount()): if not self.albumsList.topLevelItem(i).text(0) in result: self.hidden_tracks.append(self.albumsList.topLevelItem(i)) self.albumsList.topLevelItem(i).setHidden(True) @pyqtSlot() def copy_track_link(self): selected = self.trackList.selectedItems() or self.albumsList.selectedItems() selected_tracks = self._get_selected_tracks(selected) if selected_tracks: self.clipboard.setText(selected_tracks[0]["url"]) @pyqtSlot(int) def change_volume(self, level): self.current_volume = level self.mediaPlayer.setVolume(self.current_volume) self.statusBar.showMessage("Текущая громкость: {}".format(self.current_volume)) @pyqtSlot(int) def change_position(self, pos): self.mediaPlayer.setPosition(pos) def keyPressEvent(self, e): if e.key() == Qt.Key_Delete: self.trackList.clearSelection() self.albumsList.clearSelection() if e.key() == Qt.Key_Space: self._pause() @pyqtSlot("QTreeWidgetItem*") def on_item_expanded(self, item): if item.childCount(): return for album in self.albums: if album["title"] == item.text(0): for track in album["tracks"]: QtWidgets.QTreeWidgetItem(item, ["%(artist)s — %(title)s" % track]) def toggle_buttons(self, state: bool): self.saveAll.setEnabled(state) self.saveWithoutLinks.setEnabled(state) if not self.download_audio_thread.isRunning(): self.downloadAllTracks.setEnabled(state) self.luckyMe.setEnabled(state) def toggle_fields(self, state: bool): self.login.setEnabled(state) self.password.setEnabled(state) self.user_link.setEnabled(state) self.trackList.setEnabled(state) self.albumsList.setEnabled(state) self.saveData.setEnabled(state) self.search.setEnabled(state) self.btnConfirm.setEnabled(state) @pyqtSlot(str) def auth_handler(self, result): self.key = None num, ok = QtWidgets.QInputDialog.getText(self, "Двухфакторная аутентификация", result) if ok: self.key = num @pyqtSlot(QImage) def captcha_handler(self, image): self.key = None self.captchaDialog.imageLabel.setPixmap(QPixmap(image)) self.captchaDialog.exec_() self.key = self.captchaDialog.captchaKey.text() self.captchaDialog.captchaKey.clear() def _create_action( self, text, icon_path=None, status_tip=None, shortcut=None, set_enabled=True, callback=None, ): if icon_path: action = QtWidgets.QAction(QIcon(icon_path), text, self) else: action = QtWidgets.QAction(text, self) if status_tip: action.setStatusTip(status_tip) if shortcut: action.setShortcut(shortcut) action.setEnabled(set_enabled) action.triggered.connect(callback) return action def _get_tracks_count(self): length = len(self.tracks) for album in self.albums: length += len(album["tracks"]) return length def _get_selected_tracks(self, selected): selected_tracks = [] for element in selected: if element.treeWidget().objectName() == "trackList": for track in self.tracks: if element.text(0) in "%(artist)s — %(title)s" % track: selected_tracks.append(track) break else: for album in self.albums: if element.parent().text(0) == album["title"]: for track in album["tracks"]: if element.text(0) in "%(artist)s — %(title)s" % track: selected_tracks.append(track) break return selected_tracks def _save_audio_list(self, directory, save_links=True): with open(directory, "w", encoding="utf-8") as d: print("{}, {} шт.".format(self.string, len(self.tracks)), file=d, end=" ") if self.albums: print("{} альбомов\n".format(len(self.albums)), file=d) else: print("\n", file=d, end="") for track in self.tracks: if save_links: print("%(artist)s - %(title)s: %(url)s\n" % track, file=d) else: print("%(artist)s - %(title)s" % track, file=d) for album in self.albums: print("\nАльбом %(title)s:\n" % album, file=d) for track in album["tracks"]: if save_links: print(" %(artist)s - %(title)s: %(url)s\n" % track, file=d) else: print(" %(artist)s - %(title)s" % track, file=d) @pyqtSlot() def _pause(self): if self.mediaPlayer.state() == 1: self.mediaPlayer.pause() self.toggle_fields(False) if not self.download_audio_thread.isRunning(): self.downloadAllTracks.setEnabled(True) self.pause_button.setStyleSheet("border-radius:15px;image:url(:/images/play_button.png);") elif self.mediaPlayer.state() == 2: self.mediaPlayer.play() self.toggle_fields(False) if not self.download_audio_thread.isRunning(): self.downloadAllTracks.setEnabled(True) self.pause_button.setStyleSheet("border-radius:15px;image:url(:/images/pause_button.png);") @pyqtSlot() def _stop(self): if self.mediaPlayer.state(): self.toggle_fields(True) self.toggle_buttons(True) self.mediaPlayer.stop() @pyqtSlot("qint64") def _position_changed(self, x): if self.selected: self.statusBar.showMessage( "Воспроизводится {}: {} / {} Громкость: {}".format( self.selected[0].text(0), self.time.addMSecs(x).toString("mm:ss"), self.time.addMSecs(self.mediaPlayer.duration()).toString("mm:ss"), self.current_volume, ) ) self.play_status.setValue(x) self.play_status.setMaximum(self.mediaPlayer.duration()) @pyqtSlot("QPoint") def _show_context_menu(self, point): if self.download_audio_thread.isRunning(): self.download.setEnabled(False) self.context_menu.exec(self.trackList.mapToGlobal(point)) @pyqtSlot() def _maximize_window(self): self.raise_() self.activateWindow() self.showMaximized() self.showNormal() def _sort_by_artist(self): self.trackList.hideColumn(1) self.trackList.showColumn(0) self.trackList.sortItems(0, Qt.AscendingOrder) def _sort_by_name(self): self.trackList.hideColumn(0) self.trackList.showColumn(1) self.trackList.sortItems(1, Qt.AscendingOrder)
def handle_label(self): self.time_viewer.clear() mtime = QTime(0, 0, 0, 0) self.time = mtime.addMSecs(self.media_player.position()) self.time_viewer.setText(self.time.toString()) self.frame_viewer.setText(str(self.media_player.position()))
def on_duration_changed(self, duration): self.position_slider.setRange(0, duration) mtime = QTime(0, 0, 0, 0) mtime = mtime.addMSecs(self.media_player.duration()) self.full_time_viewer.setText(mtime.toString())
class TimerWindow(QWidget): #Button control functions def handleStartBtn(self): global isStarted isStarted = True self.statusInput.setText("Timer Started!") self.statusInput.setStyleSheet('color: grey') def handleStopBtn(self): global isStarted if isStarted: isStarted = False self.statusInput.setText("Reset Timer?") self.statusInput.setStyleSheet('color: blue') def handleResetBtn(self): global isStarted global elapseHours isStarted = False elapseHours = 0 self.stopwatchTime = QTime(0, 0, 0, 0) self.curElapse.setText("00:00:00:000 ms") self.updateTimer() def handleCloseBtn(self): print("Close Button Pressed!") self.hide() def formatTime(self): #Find current time timeNow = QTime.currentTime() fullTime = timeNow.toString("hh:mm:ss:zzz 'ms'") return fullTime def formatElapse(self): global elapseHours if self.stopwatchTime.hour() == 1: elapseHours += 1 self.stopwatchTime = self.stopwatchTime.addSecs(-3600) if elapseHours < 10: elapseHoursS = "0" + str(elapseHours) else: elapseHoursS = str(elapseHours) fullElapseS = elapseHoursS + ":" + self.stopwatchTime.toString( "mm:ss:zzz 'ms'") return fullElapseS def deductTimer(self): global totalMSecRemain totalMSecRemain -= 87 def formatTimer(self): global totalMSecRemain global isInfoShown #Return zeros if miliseconds remaining are negative if totalMSecRemain <= 0: if not isInfoShown: showInfo("Time is Up!") isInfoShown = True return "00:00:00:000 ms" #Calculate timer values totalHours = int(totalMSecRemain / 3600000) totalMin = int((totalMSecRemain % 3600000) / 60000) totalSec = int(((totalMSecRemain % 3600000) % 60000) / 1000) totalMilSec = int(((totalMSecRemain % 3600000) % 60000) % 1000) #Update timer label if totalHours == 0: totalHoursS = "00" elif totalHours < 10: totalHoursS = "0" + str(totalHours) else: totalHoursS = str(totalHours) if totalMin == 0: totalMinS = "00" elif totalMin < 10: totalMinS = "0" + str(totalMin) else: totalMinS = str(totalMin) if totalSec == 0: totalSecS = "00" elif totalSec < 10: totalSecS = "0" + str(totalSec) else: totalSecS = str(totalSec) if totalMilSec == 0: totalMilSecS = "000" elif totalMilSec < 10: totalMilSecS = "00" + str(totalMilSec) elif totalMilSec < 100: totalMilSecS = "0" + str(totalMilSec) else: totalMilSecS = str(totalMilSec) fullTimerS = totalHoursS + ":" + totalMinS + ":" + totalSecS + ":" + totalMilSecS + " ms" return fullTimerS def updateTime(self): #Update of cur time clock self.curTime.setText(self.formatTime()) #Update next two clocks if started if isStarted == True: #Update of elapsed time self.stopwatchTime = self.stopwatchTime.addMSecs(87) self.curElapse.setText(self.formatElapse()) #Update of timer clock self.deductTimer() self.curTimer.setText(self.formatTimer()) def updateTimer(self): if isStarted: return global totalMSecRemain global isInfoShown inputPresent = False isAccepted = False #Value validation try: if self.hourInputFeild.text() != "": hourInputNum = int(float(self.hourInputFeild.text())) inputPresent = True isAccepted = True else: hourInputNum = 0 if self.minInputFeild.text() != "": minInputNum = int(float(self.minInputFeild.text())) inputPresent = True isAccepted = True else: minInputNum = 0 if self.secInputFeild.text() != "": secInputNum = int(float(self.secInputFeild.text())) inputPresent = True isAccepted = True else: secInputNum = 0 self.statusInput.setText("Input Accepted!") self.statusInput.setStyleSheet('color: green') except ValueError: isAccepted = False inputPresent = True self.statusInput.setText("Input Declined") self.statusInput.setStyleSheet('color: red') if (inputPresent == False) or ((hourInputNum == 0) and (minInputNum == 0) and (secInputNum == 0)): totalMSecRemain = 1 isAccepted = False self.curTimer.setText("00:00:00:000 ms") self.statusInput.setText("Awaiting Input!") self.statusInput.setStyleSheet('color: orange') #Update timer variable if value accepted if (isAccepted == True): #Calculate timer values isInfoShown = False totalMSecRemain = (hourInputNum * 3600000) + ( minInputNum * 60000) + (secInputNum * 1000) fullTimerS = self.formatTimer() self.curTimer.setText(fullTimerS) def initWindow(self): self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) self.show() def horLine(self): hLine = QFrame() hLine.setFrameShape(QFrame.HLine) hLine.setFrameShadow(QFrame.Sunken) return hLine def __init__(self, screenW, screenH): super().__init__() self.title = "Simple Timer" self.width = 640 self.height = 480 self.left = (screenW / 2) - (self.width / 2) self.top = (screenH / 2) - (self.height / 2) #Create button horizontal layout btnBox = QHBoxLayout() btnBox.addStretch(.5) #Create button instaces self.startBtn = QPushButton('Start', self) self.startBtn.clicked.connect(self.handleStartBtn) self.stopBtn = QPushButton('Stop', self) self.stopBtn.clicked.connect(self.handleStopBtn) self.resetBtn = QPushButton('Reset', self) self.resetBtn.clicked.connect(self.handleResetBtn) self.closeBtn = QPushButton('Close', self) self.closeBtn.clicked.connect(self.handleCloseBtn) #Add buttons to layout btnBox.addWidget(self.startBtn) btnBox.addWidget(self.stopBtn) btnBox.addWidget(self.resetBtn) btnBox.addWidget(self.closeBtn) btnBox.addStretch(.5) #Create Update Calls for All Clocks self.curTimeTimer = QTimer(self) self.curTimeTimer.timeout.connect(self.updateTime) self.curTimeTimer.start(87) #Create Three Info Clocks timeFont = QFont("Ariel", 40) #Set the initial current time at start curTimeBox = QHBoxLayout() curTimeBox.addStretch(.5) self.curTime = QLabel(self.formatTime(), self) self.curTime.setFont(timeFont) curTimeBox.addWidget(self.curTime) curTimeBox.addStretch(.5) #Set the initial timer time at start curTimerBox = QHBoxLayout() curTimerBox.addStretch(.5) self.curTimer = QLabel("00:00:00:000 ms", self) self.curTimer.setFont(timeFont) curTimerBox.addWidget(self.curTimer) curTimerBox.addStretch(.5) #Set the initial elapsed time at start self.stopwatchTime = QTime(0, 0, 0, 0) curElapseBox = QHBoxLayout() curElapseBox.addStretch(.5) self.curElapse = QLabel("00:00:00:000 ms", self) self.curElapse.setFont(timeFont) curElapseBox.addWidget(self.curElapse) curElapseBox.addStretch(.5) #Create timer input feilds inputBox = QHBoxLayout() self.introInput = QLabel('Set timer to -', self) self.hourInput = QLabel(' Hours:', self) self.hourInputFeild = QLineEdit() self.minInput = QLabel(' Minutes:', self) self.minInputFeild = QLineEdit() self.secInput = QLabel(' Seconds:', self) self.secInputFeild = QLineEdit() self.statusInput = QLabel('Awaiting Input!', self) self.statusInput.setStyleSheet('color: orange') inputBox.addStretch(.2) inputBox.addWidget(self.introInput) inputBox.addStretch(.3) inputBox.addWidget(self.hourInput) inputBox.addWidget(self.hourInputFeild) inputBox.addWidget(self.minInput) inputBox.addWidget(self.minInputFeild) inputBox.addWidget(self.secInput) inputBox.addWidget(self.secInputFeild) inputBox.addStretch(.3) inputBox.addWidget(self.statusInput) inputBox.addStretch(.2) #Connect input signals to the apropriate function self.hourInputFeild.textChanged.connect(self.updateTimer) self.minInputFeild.textChanged.connect(self.updateTimer) self.secInputFeild.textChanged.connect(self.updateTimer) #Create all static labels titleFont = QFont("Courier", 20) self.curTimeTitle = QLabel('Current Time:', self) self.curTimeTitle.setFont(titleFont) self.curTimerTitle = QLabel('Time Remaining:', self) self.curTimerTitle.setFont(titleFont) self.curElapseTitle = QLabel('Elapsed Time:', self) self.curElapseTitle.setFont(titleFont) #Create and populate root layout rootBox = QVBoxLayout() rootBox.addWidget(self.curTimeTitle) rootBox.addLayout(curTimeBox) rootBox.addStretch(.165) rootBox.addWidget(self.horLine()) rootBox.addStretch(.165) rootBox.addWidget(self.curTimerTitle) rootBox.addLayout(curTimerBox) rootBox.addStretch(.165) rootBox.addWidget(self.horLine()) rootBox.addStretch(.165) rootBox.addWidget(self.curElapseTitle) rootBox.addLayout(curElapseBox) rootBox.addStretch(.165) rootBox.addWidget(self.horLine()) rootBox.addStretch(.165) rootBox.addLayout(inputBox) rootBox.addLayout(btnBox) self.setLayout(rootBox) self.initWindow()
class Ten(QWidget): def __init__(self, parent=None): super().__init__(parent) self._START = '&START' self._STOP = 'S&TOP' self._RESET = '&RESET' self._FORMAT = 'hh:mm:ss.zzz' self._widgets() self._layout() self._properties() self._connections() def _widgets(self): self.shiverTimer = QTime(0, 0, 0) self.timer = QTimer() self.timerLCDNumber = QLCDNumber() self.timerLCDNumber.setDigitCount(12) self.timerLCDNumber.display("00:00:00.000") self.stortPushButton = QPushButton(self._START) self.resetPushButton = QPushButton(self._RESET) def _layout(self): grid = QGridLayout() grid.addWidget(self.timerLCDNumber, 0, 0, 1, 2) grid.addWidget(self.stortPushButton, 1, 0) grid.addWidget(self.resetPushButton, 1, 1) self.setLayout(grid) def _properties(self): self.resize(350, 125) self.setWindowTitle('{} {}'.format(__title__, __version__)) self.setWindowFlags(Qt.MSWindowsFixedSizeDialogHint) def _connections(self): self.timer.timeout.connect(self.showStopwatch) self.stortPushButton.clicked.connect(self.on_stortPushButton_clicked) self.resetPushButton.clicked.connect(self.on_resetPushButton_clicked) def showStopwatch(self): """ Event handler for showing elapsed time, just like a stopwatch """ self.shiverTimer = self.shiverTimer.addMSecs(1) text = self.shiverTimer.toString(self._FORMAT) self.timerLCDNumber.display(text) def on_stortPushButton_clicked(self): if self.stortPushButton.text() == self._START: self.timer.start(1) # Start the timer self.stortPushButton.setText(self._STOP) else: self.timer.stop() # Stop the timer self.stortPushButton.setText(self._START) def on_resetPushButton_clicked(self): self.timer.stop() self.shiverTimer = QTime(0, 0, 0) self.timerLCDNumber.display(self.shiverTimer.toString(self._FORMAT)) if self.stortPushButton.text() == self._STOP: self.stortPushButton.setText(self._START)
def duration_changed(self, duration): self.evolution_slider.setRange(0, duration) mtime = QTime(0, 0, 0, 0) mtime = mtime.addMSecs(duration) self.total_time_label.setText(mtime.toString())
def update_time_label(self, position): #self.lbl.clear() mtime = QTime(0, 0, 0, 0) self.time = mtime.addMSecs(position) self.remaining_time_label.setText(self.time.toString()) self.evolution_slider.setValue(position)
def handle_label(self): self.lbl.clear() mtime = QTime(0, 0, 0, 0) self.time = mtime.addMSecs(self.mediaPlayer.position()) self.lbl.setText(self.time.toString())
class Ten(QWidget): def __init__(self, parent=None): super().__init__(parent) self._START = '&START' self._STOP = '&STOP' self._RESET = '&RESET' self._FORMAT = 'hh:mm:ss.zzz' self.close_shortcut = False self.stort_hotkey = DEFAULT_STORT_SHORTCUT self.reset_hotkey = DEFAULT_RESET_SHORTCUT self.quit_hotkey = DEFAULT_QUIT_SHORCUT self.opacity_value = DEFAULT_OPACITY_VALUE self._EXISTING_HOTKEYS = { 'Start/Stop': DEFAULT_STORT_SHORTCUT, 'Reset': DEFAULT_RESET_SHORTCUT, 'Quit': self.quit_hotkey } self._operations = { 'Start/Stop': self._update_stort_hotkey, 'Reset': self._update_reset_hotkey } self._read_settings() self._create_actions() self._create_menus() self._widgets() self._layout() self._properties() self._connections() self._hotkeys() def _create_actions(self): # self.tennyMenu actions self.openAction = QAction('Open Tenny', self, triggered=self.on_openTenny_action) self.stortAction = QAction('Start/Stop', self, triggered=self.stort_timer, shortcut=self.stort_hotkey) self.resetAction = QAction('Reset', self, triggered=self.reset_timer, shortcut=self.reset_hotkey) # self.setShortCutKeysMenu actions self.set_stortAction = QAction('Start/Stop', self, triggered=self.on_setShortcut_action) self.set_resetAction = QAction('Reset', self, triggered=self.on_setShortcut_action) self.set_opacityAction = QAction('Set Opacity', self, triggered=self.on_setOpacity_action) self.quitAction = QAction('Quit Tenny', self, shortcut=self.quit_hotkey, triggered=self.close) def _create_menus(self): # Sub-menu self.setShortCutKeysMenu = QMenu('Set Shortcut Keys') self.setShortCutKeysMenu.addAction(self.set_stortAction) self.setShortCutKeysMenu.addAction(self.set_resetAction) # Main menu self.tennyMenu = QMenu() self.tennyMenu.addAction(self.openAction) self.tennyMenu.addAction(self.stortAction) self.tennyMenu.addAction(self.resetAction) self.tennyMenu.addSeparator() self.tennyMenu.addMenu(self.setShortCutKeysMenu) self.tennyMenu.addAction(self.set_opacityAction) self.tennyMenu.addSeparator() self.tennyMenu.addAction(self.quitAction) def _widgets(self): self.shiverTimer = QTime(0, 0, 0) self.timer = QTimer() self.timerLCDNumber = QLCDNumber() self.stortPushButton = QPushButton(self._START) self.resetPushButton = QPushButton(self._RESET) self.set_opacityDialog = SetOpacity() self.tennySystemTray = QSystemTrayIcon() self.setShortcutMessageBox = QMessageBox(self) def _layout(self): grid = QGridLayout() grid.addWidget(self.timerLCDNumber, 0, 0, 1, 2) grid.addWidget(self.stortPushButton, 1, 0) grid.addWidget(self.resetPushButton, 1, 1) self.setLayout(grid) def _properties(self): # Main window self.setWindowIcon(QIcon(':/stopwatch-32.png')) self.resize(350, 125) self.setWindowTitle(f'{__title__}') self.setWindowOpacity(self.opacity_value) self.setWindowFlags(Qt.WindowStaysOnTopHint) self.timerLCDNumber.setDigitCount(12) self.timerLCDNumber.display("00:00:00.000") self.stortPushButton.setToolTip(self.stort_hotkey) self.resetPushButton.setToolTip(self.reset_hotkey) self.set_opacityDialog.opacityLabel.setText( f'{self.opacity_value * 100:.0f}') self.set_opacityDialog.opacitySlider.setSliderPosition( self.opacity_value * 100) # SetShortcut QMessageBox self.setShortcutMessageBox.setIcon(QMessageBox.Warning) self.setShortcutMessageBox.setWindowTitle('Set Shortcut Message') self.tennySystemTray.setIcon(QIcon(':/stopwatch-32.png')) self.tennySystemTray.setToolTip(f'{__title__} {__version__}') self.tennySystemTray.setContextMenu(self.tennyMenu) self.tennySystemTray.show() def _connections(self): self.timer.timeout.connect(self.showStopwatch) self.stortPushButton.clicked.connect(self.on_stortPushButton_clicked) self.resetPushButton.clicked.connect(self.on_resetPushButton_clicked) self.set_opacityDialog.opacitySlider.valueChanged.connect( self.on_opacitySlider_valueChanged) def _hotkeys(self): keyboard.add_hotkey(self.stort_hotkey, self.stortPushButton.click) keyboard.add_hotkey(self.reset_hotkey, self.resetPushButton.click) def _read_settings(self): """ Method for restoring Tenny's position, size and values. """ settings = QSettings('GIPSC Core Team', 'Tenny') self.restoreGeometry( settings.value('tenny_geometry', self.saveGeometry())) self.stort_hotkey = settings.value('tenny_stort_hotkey', self.stort_hotkey) self.reset_hotkey = settings.value('tenny_reset_hotkey', self.reset_hotkey) self.opacity_value = float( settings.value('tenny_opacity', self.opacity_value)) self._EXISTING_HOTKEYS.update({ 'Start/Stop': self.stort_hotkey, 'Reset': self.reset_hotkey }) def showStopwatch(self): """ Event handler for showing elapsed time, just like a stopwatch. """ self.shiverTimer = self.shiverTimer.addMSecs(1) text = self.shiverTimer.toString(self._FORMAT) self.timerLCDNumber.display(text) def on_stortPushButton_clicked(self): """ Call self.stort_timer to activate the timer. """ self.stort_timer() def stort_timer(self): """ Method that will start or stop the timer. """ if self.stortPushButton.text() == self._START: self.timer.start(1) self.stortPushButton.setText(self._STOP) else: self.timer.stop() self.stortPushButton.setText(self._START) def on_resetPushButton_clicked(self): """ Call self.reset_timer to reset the timer. """ self.reset_timer() def reset_timer(self): """ Method that will reset the timer. """ self.timer.stop() self.shiverTimer = QTime(0, 0, 0) self.timerLCDNumber.display(self.shiverTimer.toString(self._FORMAT)) if self.stortPushButton.text() == self._STOP: self.stortPushButton.setText(self._START) def on_openTenny_action(self): """ Show Tenny window if its hidden. """ if self.isHidden(): self.show() def on_setShortcut_action(self): which_action = self.sender() text = which_action.text() from src.dialog.preferences import SetShortcut dialog = SetShortcut(self) dialog.setWindowTitle(f'Set Shortcut for {text}') # [] TODO: make this block of code Pythonic, so far so good # [] TODO: show a notification via Notif area, after update_hotkey() if dialog.exec(): selected_hotkey = dialog.selected_hotkeys if selected_hotkey not in self._EXISTING_HOTKEYS.values(): update_hotkey = self._operations.get(text) update_hotkey(text, selected_hotkey) else: hotkey_owner = self._get_hotkey_owner(selected_hotkey) self._show_setShortcutMessageBox(selected_hotkey, hotkey_owner) def _get_hotkey_owner(self, user_hotkey): """ Return the current owner of an existing hotkey. """ for k, v in self._EXISTING_HOTKEYS.items(): if user_hotkey == v: return k def _show_setShortcutMessageBox(self, hotkey, owner): """ Set the text and show the message box. """ self.setShortcutMessageBox.setText( f'\'{hotkey}\' already registered as shortcut for <b>{owner}</b> button. Try again.' ) self.setShortcutMessageBox.show() def _update_stort_hotkey(self, text, selected_hotkey): keyboard.remove_hotkey(self.stort_hotkey) # Remove previous hotkey self.stort_hotkey = selected_hotkey # Update self.stort_hotkey keyboard.add_hotkey( self.stort_hotkey, self.stortPushButton.click) # Register new hotkey in keyboard self.stortPushButton.setToolTip( self.stort_hotkey) # Update tooltip for the button self.stortAction.setShortcut(self.stort_hotkey) # Update stort QAction self._EXISTING_HOTKEYS.update({text: self.stort_hotkey}) def _update_reset_hotkey(self, text, selected_hotkey): keyboard.remove_hotkey(self.reset_hotkey) self.reset_hotkey = selected_hotkey keyboard.add_hotkey(self.reset_hotkey, self.resetPushButton.click) self.resetPushButton.setToolTip(self.reset_hotkey) self.resetAction.setShortcut(self.reset_hotkey) self._EXISTING_HOTKEYS.update({text: self.reset_hotkey}) def on_setOpacity_action(self): self.set_opacityDialog.show() self.set_opacityDialog.move(self.tennyMenu.pos()) def on_opacitySlider_valueChanged(self): self.opacity_value = self.set_opacityDialog.opacitySlider.value() / 100 self.setWindowOpacity(self.opacity_value) self.set_opacityDialog.opacityLabel.setText( f'{self.opacity_value * 100:.0f}') def mousePressEvent(self, QMouseEvent): if self.set_opacityDialog.isVisible(): self.set_opacityDialog.close() def closeEvent(self, event): who_closes = self.sender() if isinstance(who_closes, QAction) or self.close_shortcut: self._write_settings() self.tennySystemTray.hide() event.accept() else: self.hide() self.tennySystemTray.showMessage('Tenny', 'You can still found me here :)', QSystemTrayIcon.Information, 3000) event.ignore() def keyPressEvent(self, event): if event.modifiers() & Qt.ControlModifier and event.key() == Qt.Key_Q: self.close_shortcut = True self.close() def _write_settings(self): """ Method for saving Tenny's position, size and values. """ settings = QSettings('GIPSC Core Team', 'Tenny') settings.setValue('tenny_geometry', self.saveGeometry()) settings.setValue('tenny_stort_hotkey', self.stort_hotkey) settings.setValue('tenny_reset_hotkey', self.reset_hotkey) settings.setValue('tenny_opacity', self.opacity_value)