def __restore_state(self): if self.__shared_data.parameter is not None: self.__add_selector_acc_gyr() self.__show_data('ACC_X', 'ACC_Y', 'ACC_Z') print('trigger reimport') if self.__shared_data.data_sync is not None: text_time = self.__shared_data.data_sync.split(':') time = QTime() time.setHMS(int(text_time[0]), int(text_time[1]), int(text_time[2]), int(text_time[3])) self.__sync_time_edit.setTime(time)
def MyTime(self): vbox = QVBoxLayout() time = QTime() time.setHMS(13, 15, 40) timeedit = QTimeEdit() timeedit.setFont(QtGui.QFont("Sanserif", 15)) timeedit.setTime(time) vbox.addWidget(timeedit) self.setLayout(vbox)
def insertIntervalInTimeEdits(self, interval): interval = interval.split(' - ') interval = [interval_.split('__')[0] for interval_ in interval] hourFromInterval, minuteFromInterval, secondFromInterval, millisecondFromInterval = interval[ 0].split('.') hourToInterval, minuteToInterval, secondToInterval, millisecondToInterval = interval[ 1].split('.') timeFromInterval = QTime() timeFromInterval.setHMS(int(hourFromInterval), int(minuteFromInterval), int(secondFromInterval), int(millisecondFromInterval)) timeToInterval = QTime() timeToInterval.setHMS(int(hourToInterval), int(minuteToInterval), int(secondToInterval), int(millisecondToInterval)) return timeFromInterval, timeToInterval
class TimeSettings(QDialog): def __init__(self): super(TimeSettings, self).__init__() self.name_string = NameString() self.path_string = PathString() loadUi(abspath(self.path_string.time_settings_ui_path_string), self) self.remove_time = QTime() self.remove_time.setHMS(9, 0, 0) self.timeEdit.setTime(self.remove_time) @pyqtSlot() def on_buttonBox_accepted(self): self.remove_time = self.timeEdit.time() def get_time_value(self): return self.remove_time
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
def getInterval(self): selectionInterval = str( self.intervals_listBox.selectedItems()[0].text()) fromInterval, toInterval = selectionInterval.split(' - ') intervals = [fromInterval.split('__')[0], toInterval.split('__')[0]] hourFromInterval, minuteFromInterval, secondFromInterval, millisecondFromInterval = intervals[ 0].split('.') hourToInterval, minuteToInterval, secondToInterval, millisecondToInterval = intervals[ 1].split('.') timeFromInterval = QTime() timeFromInterval.setHMS(int(hourFromInterval), int(minuteFromInterval), int(secondFromInterval), int(millisecondFromInterval)) timeToInterval = QTime() timeToInterval.setHMS(int(hourToInterval), int(minuteToInterval), int(secondToInterval), int(millisecondToInterval)) self.fromInterval_timeEdit.setTime(timeFromInterval) self.toInterval_timeEdit.setTime(timeToInterval)
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 Device: def __init__(self, s, d, c, i): self.media_listener = MediaListener() self.media_listener._self = s self.media_listener.index = i self.status_listener = StatusListener() self.status_listener._self = s self.status_listener.index = i self.connection_listener = ConnectionListener() self.connection_listener._self = s self.cast = c self.index = i self._self = s self.device = d self.live = False self.muted = False self.unmute_volume = 0 self.disconnect_volume = 0 self.paused = True self.playing = False self.stopping = False self.rebooting = False self.catt_process = None self.directory = None self.filename = None self.playback_starting = False self.playback_just_started = False self.stopping_timer = QTimer() self.starting_timer = QTimer() self.just_started_timer = QTimer() self.progress_clicked = False self.catt_read_thread = None self.progress_timer = QTimer() self.time = QTime(0, 0, 0) self.stopping_timer.timeout.connect(lambda: s.on_stopping_timeout(self)) self.starting_timer.timeout.connect(lambda: s.on_starting_timeout(self)) self.just_started_timer.timeout.connect(lambda: s.on_just_started_timeout(self)) self.stopping_timer.setSingleShot(True) self.starting_timer.setSingleShot(True) self.just_started_timer.setSingleShot(True) self.progress_timer.timeout.connect(self.on_progress_tick) def on_progress_tick(self): s = self._self self.time = self.time.addSecs(1) duration = self.device._cast.media_controller.status.duration if duration and duration != 0 and time_to_seconds(self.time) >= int(duration): # If progress is at the end, stop the device progress timer self.set_state_idle(self.index) if s.combo_box.currentIndex() == self.index: # If it is the currently selected device, update the ui self.update_ui_idle() if s.combo_box.currentIndex() == self.index: # Update the ui elements using current progress time s.progress_label.setText(self.time.toString("hh:mm:ss")) s.set_progress(time_to_seconds(self.time)) def set_state_playing(self, i, time): s = self._self s.set_time(i, int(time)) self.paused = False self.playing = True if self.live: s.stop_timer.emit(i) self.time.setHMS(0, 0, 0) else: s.start_timer.emit(i) def update_ui_playing(self, time, duration): s = self._self if duration != None: s.progress_slider.setMaximum(duration) if self.live: s.skip_forward_button.setEnabled(False) s.progress_slider.setEnabled(False) s.progress_label.setText("LIVE") s.set_icon(s.play_button, "SP_MediaPlay") else: s.skip_forward_button.setEnabled(True) s.progress_slider.setEnabled(True) s.set_icon(s.play_button, "SP_MediaPause") s.set_progress(time) s.progress_label.setText(self.time.toString("hh:mm:ss")) self.update_text() def set_state_paused(self, i, time): s = self._self s.set_time(i, int(time)) s.stop_timer.emit(i) self.paused = True self.playing = True def update_ui_paused(self, time, duration): s = self._self if duration != None: s.progress_slider.setMaximum(duration) s.set_progress(time) s.skip_forward_button.setEnabled(True) s.progress_slider.setEnabled(True) s.set_icon(s.play_button, "SP_MediaPlay") s.progress_label.setText(self.time.toString("hh:mm:ss")) self.update_text() def set_state_idle(self, i): s = self._self s.stop_timer.emit(i) self.time.setHMS(0, 0, 0) self.playing = False self.paused = True self.live = False def update_ui_idle(self): s = self._self s.set_progress(0) s.skip_forward_button.setEnabled(False) s.progress_slider.setEnabled(False) s.progress_label.setText(self.time.toString("hh:mm:ss")) s.set_icon(s.play_button, "SP_MediaPlay") self.update_text() def set_dial_value(self): s = self._self v = self.device._cast.status.volume_level * 100 s.dial.valueChanged.disconnect(s.on_dial_moved) if v != 0: self.unmute_volume = v s.dial.setValue(v) s.set_volume_label(v) s.dial.valueChanged.connect(s.on_dial_moved) def split_seconds(self, s): hours = s // 3600 minutes = (s - (hours * 3600)) // 60 seconds = s - ((hours * 3600) + (minutes * 60)) return hours, minutes, seconds def set_text(self, s, status_text, title): prefix = "" if self.live: prefix = "Streaming" if prefix and (status_text or title): prefix = prefix + " - " if status_text and title: if status_text in title: s.status_label.setText(prefix + title) elif title in status_text: s.status_label.setText(prefix + status_text) else: s.status_label.setText(prefix + status_text + " - " + title) elif status_text: s.status_label.setText(prefix + status_text) elif title: s.status_label.setText(prefix + title) elif prefix: s.status_label.setText(prefix) elif self.filename == None: s.status_label.setText("Idle") def update_text(self): title = self.device._cast.media_controller.title status_text = self.device._cast.status.status_text s = self._self if not self.playing: if self.stopping: s.status_label.setText("Stopping..") elif self.rebooting: s.status_label.setText("Rebooting..") elif ( self.playback_starting == False and self.playback_just_started == False ) or s.status_label.text() == "Stopping..": s.status_label.setText("Idle") s.set_icon(s.play_button, "SP_MediaPlay") else: self.set_text(s, status_text, title) return self.set_text(s, status_text, title) def kill_catt_process(self): if self.catt_process == None: return if self.catt_read_thread != None: self.catt_read_thread.cancel() try: os.kill(self.catt_process.pid, signal.SIGINT) self.catt_process.wait() except: pass self.catt_process = None
def time_to_qtime(t): otime = time_to_otime(t) time = QTime() time.setHMS(otime.hour, otime.minute, otime.sec, otime.msec) return time
class MyMainWindow(QMainWindow, Ui_AudioTool): def __init__(self, parent=None, backend=None, convolutioner=None): super(MyMainWindow, self).__init__(parent) self.setupUi(self) self.backend = backend self.backend.finished.connect(self.fin) self.backend.track_done.connect(self.progress_count) self.media_player = convolutioner self.media_player.custom_processing_callback(self.audio_callback) self.working = False self.audio_available = False self.playing = False self.old_preview = None self.synthesis_stage = True """ Hide samples """ self.progress_bar.hide() self.track_0.hide() self.effect_0.hide() self.root = '' """ Set up sintesis enviroment """ self.track_manager = [] self.instrument_panel = InstrumentsPopUp() self.select_file.clicked.connect(self.open_midi) self.sintetizar.clicked.connect(self.create_tracks) self.sintetizar.setDisabled(True) # No synthesis whitout midi self.available_to_play = [] """ Media player buttons """ self.media_buttons_widget.play.clicked.connect(self.play) self.media_buttons_widget.stop.clicked.connect(self.stop) """ Effects enviroment """ self.working_tracks = [] # To store on working EditedTrackWidget self.current_track = -1 self.old_effect_prop = [] self.current_effects_properties = [] self.choose_effect.addItem('') self.effects = [] for i in Effects: self.effects.append(i.value) self.choose_effect.addItem(i.value[0]) self.choose_effect.currentIndexChanged.connect(self.renew_effect) self.to_song.clicked.connect(self.effect_to_song) self.discard_effect.clicked.connect(self.clean_current_effect) self.disable_effect_enviroment() """ Reproduction thing """ self.all_tracks = [] self.all_callbacks = [] self.eddited_song = [] """ Timer things """ self.inner_timer = QTimer() self.inner_timer.timeout.connect(self.count_down_callback) self.song_time = QTime() """ Spectrogram things """ self.spectrogrammer = Spectrogrammer() self.plot_work.clicked.connect(self.sepectro_plot) self.prev_plot = None self.prev_nav = None """ Notes """ for i in Instruments: self.note_instrument.addItem(i.value[0]) self.note_add.clicked.connect(self.add_note) self.note_play.clicked.connect(self.play_notes) self.all_notes = [] self.save.clicked.connect(self.save_wav) def save_wav(self): to_save = None if self.audio_available: to_save = self.media_player.output_array.copy() else: sum = np.sum(self.all_tracks, axis=0) max = np.max(sum) if max != 0: to_save = sum / max else: to_save = sum file = self.root + '.wav' write(file, 44100, np.int16(to_save * 32767)) def play_notes(self): notas = [] for i in self.all_notes: i, l, v, ins, f = i.get_data() notas.append(note(i, l, v, ins, f)) self.backend.create_chord(notas) def add_note(self): init = self.note_time.value() long = self.note_duration.value() velocity = self.note_volume.value() instrument = self.note_instrument.currentText() freq = self.note_freq.value() note = NoteWidget(freq, instrument, velocity, init, long, self) note.delete.connect(functools.partial(self.remove_note, note)) self.all_notes.append(note) self.note_area.layout().addWidget(note) def remove_note(self, note: NoteWidget): self.all_notes.remove(note) note.close() def sepectro_plot(self): source = self.plot_track.currentText() data = [] if source == '': """ Incomplete """ return elif source == 'Plain Song': data = np.sum(self.all_tracks, axis=0) elif source == 'Edited Song': data = np.sum(self.media_player.output_array.copy(), axis=0) else: track_num = int(source.split()[-1]) useful_index = self.available_to_play.index(track_num - 1) data = self.all_tracks[useful_index] """ Ya tenemos los datos ahora hay que cortar el tramo de tiempo que se quiera """ title = source + ' init: ' + str(self.plot_time.time().minute()) + ':' + str(self.plot_time.time().second()) + \ ' + ' + str(self.plot_long.value()) + 's' init = 44100 * self.plot_time.time().minute( ) * 60 + self.plot_time.time().second() fin = init + (self.plot_long.value() * 44100) song = data[init:fin] time_array = np.arange(init, init + song.size / 44100.0, 1 / 44100.0, dtype=song.dtype) self.spectrogrammer.compute_audio_array(time_array, song) self.spectrogrammer.calculate_FFTs() mag = self.spectrogrammer.get_FFTs_magnitude() time = self.spectrogrammer.get_resampled_time_array() freq = self.spectrogrammer.get_FFTs_freq() plotter = PyQtPlotter() plotter.spectrogram(time, freq, mag, title, f_bottom=20, f_top=20000) util_canvas = plotter.canvas if self.prev_plot is not None: """ remove previous plot """ self.plot_space.removeWidget(self.prev_plot) i = self.plot_space.addWidget(util_canvas) self.plot_space.setCurrentIndex(i) nav = NavegationToolBar(util_canvas, self) if self.prev_nav is not None: self.tool_bar.removeWidget(self.prev_nav) i = self.tool_bar.addWidget(nav) self.tool_bar.setCurrentIndex(i) def count_down_callback(self): if self.media_player.processing(): self.song_time = self.song_time.addSecs(-1) self.count_down.setText(self.song_time.toString("m:ss")) else: self.playing = False self.plot_track.addItem('Edited Song') song_len = len(self.all_tracks[0]) song_len = np.ceil(song_len / 44100.0) self.song_time.setHMS(0, int(song_len / 60.0), int(song_len % 60)) self.count_down.setText(self.song_time.toString("m:ss")) self.media_player.terminate_processing() self.eddited_song = self.media_player.output_array.copy() self.media_player.clear_output() self.inner_timer.stop() self.media_buttons_widget.play.toggle() for i in self.working_tracks: i.reset() def disable_effect_enviroment(self): self.plot_track.clear() self.working = False self.audio_available = False self.old_preview = None self.synthesis_stage = True self.media_buttons_widget.play.setDisabled(True) self.media_buttons_widget.stop.setDisabled(True) self.to_track.hide() self.to_song.hide() self.choose_effect.setDisabled(True) self.discard_effect.hide() self.work_track.setText('') for tracks in self.track_manager: # Closing old midi tracks tracks.close() self.track_manager = [] for track_edits in self.working_tracks: track_edits.close_all( ) # Clean up old work / be careful with convolutioner!!! def enable_effects(self): self.synthesis_stage = False self.media_buttons_widget.play.setDisabled(False) self.media_buttons_widget.stop.setDisabled(False) #self.to_track.show() #self.to_song.show() def clean_current_effect(self): """ First change the callback to use, then reapear and to finish clean everything """ track = self.working_tracks[self.current_track].track_num - 1 useful_index = self.available_to_play.index(track) if useful_index < 0: print('Fatal ERROR') self.all_callbacks[useful_index] = self.nothing # Setting new callback self.track_manager[track].show() # Reapear in tracks self.work_track.setText("Track ...") self.choose_effect.setDisabled(True) self.working_tracks[self.current_track].close_all() self.working_tracks[self.current_track].close() self.working_tracks.pop(self.current_track) self.current_track = -1 def get_back_effect(self, track_number): who = -1 j = 0 for i in self.working_tracks: if i.track_num == track_number: who = j break else: j += 1 if who == self.current_track: """ Nothing to do """ return if self.current_track >= 0: self.working_tracks[self.current_track].go_backstage() self.choose_effect.setCurrentIndex(0) self.choose_effect.setDisabled(False) self.work_track.setText("Track " + str(track_number)) self.discard_effect.show() self.current_track = who self.working_tracks[who].show_properties() def audio_callback(self, sample): foo = [] for i in range(0, len(sample)): foo.append((sample[i], self.all_callbacks[i])) out = np.array(list(map(self.effects_to_apply, foo))) return out[:, 0], out[:, 1] def effects_to_apply(self, var): func = var[1] return func(var[0]) def effect_to_song(self): print('hola') def select_track(self, index): if not (not self.synthesis_stage and index in self.available_to_play): """ If synthesis is not ready, effects are not possible """ return if self.current_track >= 0: self.working_tracks[self.current_track].go_backstage() self.choose_effect.setCurrentIndex(0) self.track_manager[index].hide() self.choose_effect.setDisabled(False) self.work_track.setText("Track " + str(index + 1)) self.discard_effect.show() temp = EditedTrackWidget(self, self.effect_container.layout(), index + 1) self.working_tracks.append(temp) self.working_effects.layout().addWidget(temp) self.current_track = self.working_tracks.index(temp) temp.update_effect.connect( functools.partial(self.audio_procesing, index + 1)) temp.clicked.connect(self.get_back_effect) """ plot = PyQtPlotter() data = self.all_tracks[self.available_to_play.index(index)] time = np.arange(len(data))/44100.0 plot.x_vs_y(time, data,"Track "+str(index+1)) util_canvas = plot.canvas if self.prev_wave is not None: self.waveform.removeWidget(self.prev_wave) i = self.waveform.addWidget(util_canvas) self.waveform.setCurrentIndex(i) """ def audio_procesing(self, track_num): index = 0 for i in range(0, len(self.working_tracks)): if self.working_tracks[i].me(track_num): index = i break index_2 = self.available_to_play.index(track_num - 1) print(index) print(self.working_tracks) self.all_callbacks[index_2] = self.working_tracks[index].get_callback() def tracks_audio_prcesing(self, state: bool, index: int): index = index - 1 useful_index = self.available_to_play.index(index) if useful_index >= 0: """ Available ones """ if state: self.all_callbacks[useful_index] = self.mute else: self.all_callbacks[useful_index] = self.nothing def renew_effect(self, index): layout = self.effect_container.layout() if index > 0: self.old_effect_prop = [] efecto = self.effects[index - 1] propiedades = efecto[1] for prop, valor in propiedades.items(): my_item = EffectPropertyWidget(self, prop, valor[0][1], valor[1]) layout.addWidget(my_item) self.old_effect_prop.append(my_item) self.working_tracks[self.current_track].set_effect( efecto[2](), self.old_effect_prop) def open_midi(self): layout = self.track_setter.layout() self.plot_track.clear() """ Go to find new """ filename, _ = QFileDialog.getOpenFileName(self, 'Open File', '', 'Midi (*.mid)') """ If no file is selected quit """ if filename == '': return self.progress_bar.setValue(0) """ Clear previous things""" self.disable_effect_enviroment() self.root = filename.split('.')[0] name = filename.split('/')[-1] self.midi_name.setText(name) self.backend.load_midi_file(filename) tracks = self.backend.get_track_list() for i in range(0, len(tracks)): aux_track = TrackConfigWidget(self, str(i + 1), self.instrument_panel) aux_track.clicked.connect(functools.partial(self.select_track, i)) """ Aca deberia agarrar el doble ckick !!!!""" self.track_manager.append(aux_track) layout.addWidget(self.track_manager[i]) # i += 1 self.label.setText( 'Seleccione los instrumentos, y al sintetizar espere a que se pongan verdes los tracks' ) self.sintetizar.setDisabled(False) def create_tracks(self): """ working is a bool to avoid conflicts while synthesizing """ if not self.working: fin = len(self.track_manager) """ May be good looking to start a timer and do something meanwhile.. """ self.working = True absents = [] all_num = [] for i in range(0, fin): all_num.append(i) volume, instrument = self.track_manager[i].get_data() active = True if volume == 0 or instrument == '': absents.append(i) active = False self.backend.assign_instrument_to_track( i, instrument, volume / 100.0, active) if len(absents) == len(self.track_manager): print('Compilando vacio') return for a in self.track_manager: # This may be useful in future a.setStyleSheet( 'QWidget { border-style: solid; background-color: rgbrgb(81, 76, 149); border-radius: 5px;}' ) self.available_to_play = list( set(all_num).difference(set(absents))) self.progress_bar.setMaximum(len(self.available_to_play)) self.progress_bar.setValue(0) self.progress_bar.show() self.backend.start() def progress_count(self, a): self.progress_bar.setValue(self.progress_bar.value() + 1) self.track_manager[a].setStyleSheet( 'QWidget { border-style: solid; background-color: rgb(31, 172, 102); border-radius: 5px;}' ) def fin(self): #self.progress_bar.hide() self.enable_effects() self.plot_track.addItem('Plain Song') self.plot_track.addItems( ['Track ' + str(i + 1) for i in self.available_to_play]) self.working = False all_tracks = [] """ Load tracks """ for i in range(0, len(self.available_to_play)): song = np.load(path + 'BackEnd/Tracks/' + 'track' + str(i) + '.npy') all_tracks.append(song) self.all_callbacks.append( self.nothing) # Adding functions with all ones if self.media_player is not None: """ Send input to convolutioner """ self.media_player.update_input(np.array(all_tracks), np.dtype('float32')) self.all_tracks = all_tracks.copy() """ Set timer """ song_len = len(all_tracks[0]) song_len = np.ceil(song_len / 44100.0) self.song_time.setHMS(0, int(song_len / 60.0), int(song_len % 60)) self.count_down.setText(self.song_time.toString("m:ss")) self.label.setText( 'Ahora puede poner play, haciendo click sobre un track podrá seleccionalo para agregar efectos' ) def play(self): if self.media_buttons_widget.stop.isChecked(): self.media_buttons_widget.stop.toggle() if self.playing: self.media_player.terminate_processing() self.media_player.clear_output() song_len = len(self.all_tracks[0]) song_len = np.ceil(song_len / 44100.0) self.song_time.setHMS(0, int(song_len / 60.0), int(song_len % 60)) self.count_down.setText(self.song_time.toString("m:ss")) self.inner_timer.stop() for i in self.working_tracks: i.reset() self.playing = True self.media_player.start_non_blocking_processing() self.inner_timer.start(1000) def stop(self): if self.media_buttons_widget.play.isChecked(): self.media_buttons_widget.play.toggle() if not self.playing: return self.playing = False self.media_player.terminate_processing() self.media_player.clear_output() song_len = len(self.all_tracks[0]) song_len = np.ceil(song_len / 44100.0) self.song_time.setHMS(0, int(song_len / 60.0), int(song_len % 60)) self.count_down.setText(self.song_time.toString("m:ss")) self.inner_timer.stop() for i in self.working_tracks: i.reset() def preview_adjust(self, track_number): if self.old_preview is not None: if self.old_preview != track_number: """ Clear previous select """ self.track_manager[self.old_preview].setStyleSheet( 'QWidget { border-style: solid; background-color: rgb(81, 76, 149); border-radius: 5px;}' ) self.track_manager[self.old_preview].preview.toggle() """ Mark new track""" self.track_manager[track_number].setStyleSheet( 'QWidget { border-style: solid; background-color: rgb(31, 172, 102); border-radius: 5px;}' ) self.old_preview = track_number else: """ Unselect track """ self.track_manager[self.old_preview].setStyleSheet( 'QWidget { border-style: solid; background-color: rgb(81, 76, 149); border-radius: 5px;}' ) self.old_preview = None else: self.track_manager[track_number].setStyleSheet( 'QWidget { border-style: solid; background-color: rgb(31, 172, 102); border-radius: 5px;}' ) self.old_preview = track_number @staticmethod def nothing(sample): """ All deltas response, for no effect output """ return (sample, sample) @staticmethod def mute(sample): """ All deltas response, for no effect output """ out = np.array([np.zeros(len(sample))]) return (out, out)
class MainWindow(QMainWindow): def __init__(self): super().__init__() # Set window properties. self.setWindowTitle("Speed Typer") self.my_font = QFont("Helvetica [Cronyx]", 20, QFont.Bold) self.my_style = "color: rgb(255, 215, 0)" self.create_widgets() self.setGeometry(200, 200, 1000, 500) # Window color. self.p = self.palette() self.p.setColor(self.backgroundRole(), QtCore.Qt.black) self.setPalette(self.p) # Random sentence from dictionary. self.sentence = "" def create_widgets(self): """ Method: Intialize all UI widgets. """ # Button to generate sentence from dictionary. self.getSent = QPushButton("Start", self) self.getSent.setGeometry(440, 20, 100, 45) self.getSent.clicked.connect(self.generate_S) self.getSent.setFont(self.my_font) # Button to close application. self.closeBtn = QPushButton("Quit", self) self.closeBtn.setGeometry(440, 300, 100, 45) self.closeBtn.clicked.connect(self.close) self.closeBtn.setFont(self.my_font) # User attempt to type sentence. self.usrAttempt = QLineEdit(self) self.usrAttempt.setGeometry(180, 175, 600, 30) self.usrAttempt.returnPressed.connect(self.fireTimer) # Submit user attempt. self.subBtn = QPushButton("submit", self) self.subBtn.setGeometry(780, 170, 100, 45) self.subBtn.clicked.connect(self.getAccuracy) self.subBtn.setFont(self.my_font) # Label to show random sentence. self.sentLabel = QLabel("", self) self.sentLabel.setGeometry(140, 120, 800, 50) self.sentLabel.setFont(self.my_font) self.sentLabel.setStyleSheet(self.my_style) self.disclaimer = QLabel( "Once you press start, you will display a sentence and be timed. Be ready!", self) self.disclaimer.setGeometry(140, 60, 700, 50) self.disclaimer.setFont(self.my_font) self.disclaimer.setStyleSheet(self.my_style) # Labels to show accuracy and time results. self.accLabel = QLabel("", self) self.accLabel.setGeometry(250, 200, 200, 50) self.accLabel.setFont(self.my_font) self.accLabel.setStyleSheet(self.my_style) self.timerLabel = QLabel("", self) self.timerLabel.setGeometry(500, 200, 200, 50) self.timerLabel.setFont(self.my_font) self.timerLabel.setStyleSheet(self.my_style) # Timer object to record time it took for user to type. self.curr_time = QTime(00, 00, 00) self.timer = QTimer() self.timer.setInterval(1000) self.timer.timeout.connect(self.fireTimer) def generate_S(self): """ Method: Get random sentence from dictionary. """ self.disclaimer.hide() self.accLabel.hide() self.timerLabel.hide() self.timer.start() self.sentence = sentences[random.randrange(0, len(sentences) - 1)] self.sentence = self.sentence.rstrip() self.sentLabel.setText(self.sentence) self.usrAttempt.setText("") def getAccuracy(self): """ Method: Get user's attempt from UI and compute accuracy. """ self.timer.stop() attempt = self.usrAttempt.text() # Compute string comparison accuracy with SequenceMatcher func from difflib library. acc = difflib.SequenceMatcher(None, attempt, self.sentence) result = acc.ratio() * 100 result = str(round(result, 2)) # Update result labels. self.accLabel.setText(f'Accuracy: {result}%') self.timerLabel.setText(f'Time: {self.curr_time.toString("hh:mm:ss")}') self.accLabel.show() self.timerLabel.show() # Reset time for label and reset value for user-attempt line edit. self.curr_time.setHMS(00, 00, 00) def fireTimer(self): """ Method: Fire timer when user starts typing. """ self.curr_time = self.curr_time.addSecs(1)
class PomodoroWindow(CenterWindow): def __init__(self, controller, issue_key, issue_title, tray_icon): super().__init__() self.center() self.setStyleSheet(QSS) self.controller = controller self.tray_icon = tray_icon if not os.path.exists(LOGGED_TIME_DIR): os.mkdir(LOGGED_TIME_DIR) self.LOG_PATH = os.path.join( LOGGED_TIME_DIR, '{}.txt'.format(issue_key) ) self.setWindowTitle('Pomodoro Timer') self.settings = QSettings('Spherical', 'Jira Quick Reporter') pomodoro_settings = int(self.settings.value(POMODORO, 25)) long_break_settings = int(self.settings.value(LONG_BREAK, 15)) short_break_settings = int(self.settings.value(SHORT_BREAK, 5)) self.time_dict = dict( short=QTime(0, short_break_settings, 0), long=QTime(0, long_break_settings, 0), pomodoro=QTime(0, pomodoro_settings, 0) ) self.issue_key = issue_key self.issue_title = issue_title self.pomodoros_count = 0 self.current_time_name = POMODORO self.is_active_timer = False self.logged_time = QTime(0, 0, 0) self.time = self.time_dict[POMODORO] self.time_in_seconds = QTime(0, 0, 0).secsTo(self.time) self.timer_box = QVBoxLayout() self.main_box = QHBoxLayout() self.setLayout(self.main_box) self.issue_label = QLabel( '{}: {}'.format(self.issue_key, self.issue_title) ) self.issue_label.setAlignment(Qt.AlignCenter) self.issue_label.setObjectName('issue_label') self.issue_label.setWordWrap(True) self.issue_label.setSizePolicy( QSizePolicy.Expanding, QSizePolicy.Fixed ) self.pbar = QProgressBar() self.pbar.setRange(0, self.time_in_seconds) self.pbar.setValue(0) self.pbar.setTextVisible(False) self.timer = QTimer() self.timer.timeout.connect(self.handle_timer) self.time_label = QLabel() self.time_label.setObjectName('time_label') self.time_label.setText(self.time.toString('mm:ss')) self.time_label.setAlignment(Qt.AlignCenter) self.btns_box = QHBoxLayout() self.start_btn = QPushButton('Start') self.start_btn.clicked.connect(self.toggle_timer) self.stop_btn = QPushButton('Stop') self.stop_btn.clicked.connect(self.toggle_timer) self.logwork_btn = QPushButton('Log work') self.logwork_btn.clicked.connect( lambda: self.controller.open_time_log(issue_key) ) self.logwork_btn.setEnabled(False) self.btns_box.addWidget(self.start_btn) self.btns_box.addWidget(self.stop_btn) self.btns_box.addWidget(self.logwork_btn) self.pomodoros_box = QHBoxLayout() self.pomodoros_box.setSpacing(5) self.pomodoros_count_label = QLabel() self.pomodoros_count_label.setObjectName('pomodoros_count') self.timer_box.addWidget(self.issue_label) self.timer_box.addStretch() self.timer_box.addWidget(self.time_label) self.timer_box.addWidget(self.pbar, Qt.AlignCenter) self.timer_box.addLayout(self.btns_box) self.timer_box.addLayout(self.pomodoros_box) self.timer_box.addStretch() self.main_box.addLayout(self.timer_box) self.action_show_time = QAction(self) self.action_show_time.setEnabled(False) self.action_open_timer = QAction('Open timer', self) self.action_open_timer.triggered.connect(self.show) self.action_quit_timer = QAction('Quit timer', self) self.action_quit_timer.triggered.connect(self.quit) self.action_settings = QAction('Settings', self) self.settings_window = Settings(self) self.action_settings.triggered.connect(self.settings_window.show) self.action_reset = QAction('Reset timer', self) self.action_reset.triggered.connect(self.reset_timer) self.action_start_timer = QAction('Start', self) self.action_start_timer.triggered.connect(self.toggle_timer) self.action_stop_timer = QAction('Stop', self) self.action_stop_timer.triggered.connect(self.toggle_timer) self.action_log_work = QAction('Log work', self) self.action_log_work.triggered.connect( lambda: self.controller.open_time_log(issue_key) ) self.action_log_work.setEnabled(False) self.tray_icon.contextMenu().addSeparator() self.tray_icon.contextMenu().addAction(self.action_show_time) self.action_show_time.setText(self.time.toString('mm:ss')) self.tray_icon.contextMenu().addAction(self.action_open_timer) self.tray_icon.contextMenu().addAction(self.action_settings) self.tray_icon.contextMenu().addAction(self.action_quit_timer) self.tray_icon.contextMenu().addSeparator() self.tray_icon.contextMenu().addAction(self.action_start_timer) self.tray_icon.contextMenu().addAction(self.action_stop_timer) self.tray_icon.contextMenu().addAction(self.action_reset) self.tray_icon.contextMenu().addAction(self.action_log_work) def log_work_if_file_exists(self): if os.path.exists(self.LOG_PATH): reply = QMessageBox.question( self, 'Warning', 'You have not logged your work.\n Do you want to log it?', QMessageBox.Yes | QMessageBox.No ) if reply == QMessageBox.Yes: self.controller.open_time_log(self.issue_key) else: os.remove(self.LOG_PATH) def update_time_from_settings(self, minutes, time_name): if self.current_time_name != time_name: self.time_dict[time_name].setHMS(0, minutes, 0) elif not self.is_active_timer: self.time_dict[time_name].setHMS(0, minutes, 0) self.update_timer() elif self.time_dict[time_name].minute() > minutes: spent_time_seconds = self.time.secsTo(self.time_dict[time_name]) if minutes <= spent_time_seconds // 60: self.stop_timer() QSound.play(RING_SOUND_PATH) self.set_timer() else: time_diff = self.time_dict[time_name].minute() - minutes self.change_timer(minutes, -time_diff) elif self.time_dict[time_name].minute() < minutes: time_diff = minutes - self.time_dict[time_name].minute() self.change_timer(minutes, time_diff) def change_timer(self, minutes, time_diff): self.time_dict[self.current_time_name].setHMS(0, minutes, 0) self.time = self.time.addSecs(time_diff * 60) self.time_in_seconds = minutes * 60 self.pbar.setMaximum(self.time_in_seconds) self.time_label.setText(self.time.toString('mm:ss')) self.action_show_time.setText(self.time.toString('mm:ss')) def handle_timer(self): """ Updates timer label and progress bar every second until time is over """ value = self.pbar.value() if value < self.time_in_seconds: value += 1 self.pbar.setValue(value) self.time = self.time.addSecs(-1) self.time_label.setText(self.time.toString('mm:ss')) self.action_show_time.setText(self.time.toString('mm:ss')) if not value % 60: self.log_time() else: self.stop_timer() QSound.play(RING_SOUND_PATH) if self.current_time_name != POMODORO: self.tray_icon.showMessage( 'Pomodoro', 'Your break is over', msecs=2000) self.set_timer() def update_timer(self): self.time_in_seconds = QTime(0, 0, 0).secsTo(self.time) self.pbar.setMaximum(self.time_in_seconds) self.pbar.setValue(0) self.time_label.setText(self.time.toString('mm:ss')) self.action_show_time.setText(self.time.toString('mm:ss')) def set_pomodoro_timer(self): self.is_active_timer = False self.current_time_name = POMODORO self.time = self.time_dict[POMODORO] self.update_timer() def set_pomodoro_count(self): """ Set pomodoro mark and number of past pomodoros """ self.clear_pomodoros() label = QLabel() pixmap = QPixmap(POMODORO_MARK_PATH) label.setPixmap(pixmap) self.pomodoros_box.addWidget(self.pomodoros_count_label) self.pomodoros_count_label.setSizePolicy( QSizePolicy.Fixed, QSizePolicy.Expanding ) self.pomodoros_box.addWidget(label) self.pomodoros_count_label.setText(str(self.pomodoros_count)) def set_pomodoro_img(self): label = QLabel() pixmap = QPixmap(POMODORO_MARK_PATH) label.setPixmap(pixmap) if self.pomodoros_count > 1: self.pomodoros_box.itemAt( self.pomodoros_count - 2 ).widget().setSizePolicy( QSizePolicy.Fixed, QSizePolicy.Expanding ) self.pomodoros_box.addWidget(label) def clear_pomodoros(self): for _ in range(self.pomodoros_box.count()): self.pomodoros_box.itemAt(0).widget().setParent(None) def toggle_timer(self): sender = self.sender().text() if sender in ['Start', 'Resume']: self.start_timer() elif sender == 'Pause': self.pause_timer() else: self.stop_timer() self.set_pomodoro_timer() def log_time(self): self.logged_time = self.logged_time.addSecs(60) with open(self.LOG_PATH, 'w') as log_file: log_file.write(self.logged_time.toString('h:m')) def start_timer(self): self.is_active_timer = True # change style before a break if self.current_time_name != POMODORO: self.issue_label.setObjectName('issue_label_break') self.issue_label.setStyleSheet('issue_label_break') self.pbar.setObjectName('break') self.pbar.setStyleSheet('break') self.stop_btn.hide() self.start_btn.setText('Stop') self.action_start_timer.setEnabled(False) else: self.tray_icon.showMessage( 'Pomodoro', 'Focus on your task', msecs=2000 ) self.start_btn.setText('Pause') self.action_start_timer.setText('Pause') self.logwork_btn.setEnabled(False) self.action_log_work.setEnabled(False) self.timer.start(1000) def stop_timer(self): self.timer.stop() self.is_active_timer = False self.start_btn.setText('Start') self.action_start_timer.setText('Start') self.logwork_btn.setEnabled(True) self.action_log_work.setEnabled(True) if self.current_time_name != POMODORO: self.stop_btn.show() self.action_start_timer.setEnabled(True) # change style after a break self.issue_label.setObjectName('issue_label') self.issue_label.setStyleSheet('issue_label') self.pbar.setObjectName('') self.pbar.setStyleSheet('') def pause_timer(self): self.timer.stop() self.start_btn.setText('Resume') self.action_start_timer.setText('Resume') self.logwork_btn.setEnabled(True) self.action_log_work.setEnabled(True) def reset_timer(self): self.logwork_btn.setEnabled(False) self.action_log_work.setEnabled(False) self.stop_timer() self.pomodoros_count = 0 self.logged_time.setHMS(0, 0, 0) self.clear_pomodoros() self.set_pomodoro_timer() if os.path.exists(self.LOG_PATH): os.remove(self.LOG_PATH) def set_pomodoro_mark(self): if self.pomodoros_count < 5: self.set_pomodoro_img() elif self.pomodoros_count == 5: self.set_pomodoro_count() else: self.pomodoros_count_label.setText( str(self.pomodoros_count) ) def set_timer(self): """ In this method decides which timer will go next """ # if pomodoro time's up if self.current_time_name == POMODORO: self.pomodoros_count += 1 self.set_pomodoro_mark() # if four pomodoros have completed if not self.pomodoros_count % 4: self.current_time_name = LONG_BREAK else: self.current_time_name = SHORT_BREAK dialog = BreakDialog(self.current_time_name) # close dialog after 4 seconds QTimer.singleShot(4000, dialog.close) # get break name (short, long or skip) from dialog self.current_time_name = dialog.exec() if self.current_time_name != POMODORO: self.time = self.time_dict[self.current_time_name] self.update_timer() self.start_timer() return # if break time's up self.set_pomodoro_timer() def quit(self): if os.path.exists(self.LOG_PATH): reply = QMessageBox.question( self, 'Warning', 'You did not log your work. \nAre you sure you want to exit?', QMessageBox.Yes, QMessageBox.No ) if reply == QMessageBox.No: return False self.settings.setValue( POMODORO, self.time_dict[POMODORO].minute() ) self.settings.setValue( LONG_BREAK, self.time_dict[LONG_BREAK].minute() ) self.settings.setValue( SHORT_BREAK, self.time_dict[SHORT_BREAK].minute() ) self.settings.sync() self.setAttribute(Qt.WA_DeleteOnClose, True) self.close() return True def closeEvent(self, event): if self.testAttribute(Qt.WA_DeleteOnClose): self.controller.pomodoro_view = None event.accept() else: event.ignore() self.hide()