Ejemplo n.º 1
0
 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)
Ejemplo n.º 2
0
 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
Ejemplo n.º 3
0
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
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
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())
Ejemplo n.º 7
0
    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
Ejemplo n.º 8
0
 def displayTime(self):
     t = QTime(0, 0, 0)
     displayTxt = t.addMSecs(self.delta.elapsed()).toString('hh:mm:ss')
     self.newTime.emit(displayTxt)
Ejemplo n.º 9
0
 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())
Ejemplo n.º 10
0
 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"))
Ejemplo n.º 11
0
 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"))
Ejemplo n.º 12
0
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())
Ejemplo n.º 15
0
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()
Ejemplo n.º 16
0
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)
Ejemplo n.º 17
0
 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())
Ejemplo n.º 18
0
 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)
Ejemplo n.º 19
0
 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())
Ejemplo n.º 20
0
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)