class Downloader(QObject): finished = pyqtSignal() def __init__(self, queue): """ Class that spawns the separate download threads. This is a separate class so it can be moved to its own thread and run simultaneously with post extraction. :param queue: The download queue in which extracted content is placed """ super().__init__() self.queue = queue self.run = True self.settings = QSettings("SomeGuySoftware", "RedditDownloader") self.download_pool = QThreadPool() self.download_pool.setMaxThreadCount( self.settings.value('thread_limit', 4, type=int)) def download(self): """Spawns the download pool threads""" while self.run: post = self.queue.get() if post is not None: self.download_pool.start(post) else: self.run = False self.download_pool.waitForDone() self.finished.emit() def stop(self): self.run = False self.download_pool.clear()
class InterfaceMorse(QMainWindow): def __init__(self): super(InterfaceMorse, self).__init__() self.threadpool = QThreadPool() if erreur: self.creerErreur(str(erreur)) # initialisation de la fenetre self.setWindowTitle("Texte vers morse") self.ui = uic.loadUi('views/interface.ui') self.setFixedWidth(719) self.setFixedHeight(328) self.config = config(self) # récupération des éléments interactifs self.texteMorse = self.ui.findChildren(QTextEdit, 'texteMorse')[0] self.envoyer = self.ui.findChildren(QPushButton, 'envoyer')[0] effacer = self.ui.findChildren(QPushButton, 'effacer')[0] self.configuration = self.ui.findChildren(QPushButton, 'configuration')[0] quitter = self.ui.findChildren(QPushButton, 'quitter')[0] self.barreDeStatus = self.ui.findChildren(QLineEdit, 'barreDeStatus')[0] self.controller = ControllerMorse(self) self.setCentralWidget(self.ui) self.show() # liaison avec les controllers des boutons self.envoyer.clicked.connect( lambda checked: self.threadpool.start(self.controller)) self.configuration.clicked.connect(lambda checked: self.config.show()) effacer.clicked.connect(lambda checked: self.texteMorse.setText("")) quitter.clicked.connect(quit) def creerErreur(self, messageErreur): """ Permet de générer une erreur critique. Lorsqu'on la ferme, le programme s'arrête. Parameters ---------- messageErreur : str Le message qui sera affiché dans la fenêtre d'erreur. Si le paramètre n'est pas de type str, "Vérifiez les logs" se met par défaut. """ if not isinstance(messageErreur, str): messageErreur = "Vérifiez les logs." erreur = QMessageBox(QMessageBox.Critical, "Erreur", "Erreur critique", QMessageBox.Close) erreur.setInformativeText(messageErreur) ret = erreur.exec() if ret == QMessageBox.Close: self.close() self.threadpool.clear() exit()
class PROCESS(QObject): queue_finished = pyqtSignal(int) prog_finished = pyqtSignal(tuple) stoped = pyqtSignal(int, int) # 1: start, 0: finished, 2: error | queue state = pyqtSignal(int, str) def __init__(self, parent=None): QObject.__init__(self, parent) self.process = QProcess() self.process.setProcessChannelMode(QProcess.MergedChannels) self.process.finished.connect(self.emit_finished) self.process.stateChanged.connect(self.emit_state) self.process_type = 0 # 0 process, 1 runnable self.threadpool = QThreadPool() self.worker = Worker() self.worker.signals.state.connect(self.emit_state) self.queue = None def emit_state(self, state): self.state.emit(state, self.prog_name) def emit_finished(self, exitcode, exitstatus): self.prog_finished.emit((self.prog_name, exitcode, exitstatus)) def set_queue(self, queue): self.queue = queue def start_process(self): try: obj = self.queue.get(False) self.prog_name = list(obj.keys())[0] if callable(list(obj.values())[0][0]): self.process_type = 1 funct = list(obj.values())[0][0] args = list(obj.values())[0][1] self.worker.insert_function(funct, args, self.prog_name) self.threadpool.start(self.worker) else: self.process_type = 0 self.process.start( list(obj.values())[0][0], list(obj.values())[0][1]) except Empty: self.queue_finished.emit(self.queue.name) def force_finished(self): # for process (programs) self.stoped.emit(1, self.queue.name) if self.process_type == 0: self.process.terminate() if not self.process.waitForFinished(1000): self.process.kill() else: if self.threadpool.activeThreadCount(): self.threadpool.clear() self.threadpool.waitForDone() with self.queue.mutex: self.queue.queue.clear() self.stoped.emit(0, self.queue.name)
class UNABScripts(QMainWindow): """Main Application Window Defines shape, icon, name and closing method Args: QMainWindow ([]): Inherits from QMainWindow Class """ def __init__(self): super().__init__() self.setGeometry(300, 200, 350, 600) self.setFixedSize(350, 600) self.setWindowTitle("App Tutores v1.1.0") self.setWindowIcon(QIcon("./icon.png")) self.threadpool = QThreadPool() if gui_language == "en_US": self.lang_dict = en_US else: self.lang_dict = es_ES data = None try: with open("savefile.json", "r") as file: data = load( file, object_hook=lambda d: { int(k) if k.lstrip("-").isdigit() else k: v for k, v in d.items() }, ) except IOError: logging.info("No Such File, creating one at exit") self.tabs_widget = TabsWidget(self, data) self.setCentralWidget(self.tabs_widget) self.show() def closeEvent(self, *args, **kwargs): """closeEvent overloading to save config data """ data = self.tabs_widget.save_data() with open("savefile.json", "w") as file: dump(data, file) self.threadpool.clear()
class TaskConsumer(metaclass=SingletonMeta): def __init__(self) -> None: self.lock = threading.Lock() self.q = list() self.thread_pool = QThreadPool() self.thread_pool.setMaxThreadCount(1) def set_thread_pool(self, tp): self.thread_pool = tp def insert_task(self, task: Task) -> None: """ Insert task if whether its not in queue or its status is either done or failed. :param task: :return: """ with self.lock: self.__remove_finished_task() if not any(task.task_type == each.task_type for each in self.q): self.q.append(task) def get_task(self) -> Task: with self.lock: self.__remove_finished_task() if self.q: for each in self.q: if each.task_type == TaskTypes.SERIAL_OPEN: return each return self.q[0] else: return None def consume_task(self) -> None: task = self.get_task() if task and self.thread_pool.activeThreadCount() == 0: self.thread_pool.start(task) def clear_task_queue(self) -> None: self.q.clear() self.thread_pool.clear() def __remove_finished_task(self) -> None: clr_lst = [ index for index, task in enumerate(self.q) if task.status > TaskStatus.RUNNING ] for index in clr_lst: del self.q[index]
class Downloader(QObject): finished = pyqtSignal() download_count_signal = pyqtSignal(int) send_downloaded = pyqtSignal(dict) def __init__(self, queue, thread_limit): """ Class that spawns the separate download threads. This is a separate class so it can be moved to its own thread and run simultaneously with post extraction. :param queue: The download queue in which extracted content is placed """ super().__init__() self.logger = logging.getLogger('DownloaderForReddit.%s' % __name__) self.queue = queue self.download_count = 0 self.run = True self.download_pool = QThreadPool() self.download_pool.setMaxThreadCount(thread_limit) def download(self): """Spawns the download pool threads""" self.logger.info('Downloader started') while self.run: post = self.queue.get() if post is not None: post.download_complete_signal.complete.connect( self.send_download_dict) self.download_pool.start(post) self.download_count += 1 else: self.run = False self.download_pool.waitForDone() self.logger.info('Downloader finished', extra={'download_count': self.download_count}) self.download_count_signal.emit(self.download_count) self.finished.emit() def send_download_dict(self, download_dict): self.send_downloaded.emit(download_dict) def stop(self): self.run = False self.download_pool.clear()
class PackageMonitor(QThread): signal = pyqtSignal() def __init__(self): super().__init__() self.pool = QThreadPool() self.pool.globalInstance() self.pool.setMaxThreadCount(3) def run(self): flag = True while flag: count = self.pool.activeThreadCount() if count <= 0: # 打包完成,发完成信号,重置flag,终止线程 self.signal.emit() flag = False else: # 打包进行中,线程休眠 QThread.sleep(3) def add_runnable(self, runnable): self.pool.start(runnable) def clear(self): self.pool.clear()
class Window(QMainWindow, ClipableObserver): def __init__(self, brres_files=[]): super().__init__() self.open_files = [] self.brres = None self.image_updater = {} # maps brres to list of subscribers self.cwd = os.getcwd() self.__init_threads() self.locked_files = set( ) # lock files that are pending conversion etc... # AutoFix.get().set_pipe(self) self.__init_UI() self.shell_is_shown = False self.shell = None for file in brres_files: self.open(file.name) AutoFix.get().info('Initialized main window', 5) self.show() def __init_threads(self): AutoFix.get().info('Starting threads...', 5) self.threadpool = QThreadPool() # for multi-threading self.threadpool.setMaxThreadCount(5) self.converter = converter = ConvertManager.get() converter.signals.on_conversion_finish.connect( self.on_conversion_finish) self.image_manager = image_manager = ImageManager.get() if image_manager.enabled: image_manager.signals.on_image_update.connect(self.on_image_update) self.threadpool.start(image_manager) else: AutoFix.get().warn( 'Image Manager disabled, do you have Wiimms SZS Tools installed?' ) self.threadpool.start(converter) log_pipe = LoggerPipe() log_pipe.info_sig.connect(self.info) log_pipe.warn_sig.connect(self.warn) log_pipe.error_sig.connect(self.error) def __init_menus(self): # Files # Exit exit_act = QAction('&Exit', self) exit_act.setShortcut('Ctrl+q') exit_act.setStatusTip('Exit Application') exit_act.triggered.connect(self.close) # Open open_act = QAction('&Open', self) open_act.setShortcut('Ctrl+o') open_act.setStatusTip('Open a Brres file') open_act.triggered.connect(self.open_dialog) # Save save_act = QAction('&Save', self) save_act.setShortcut('Ctrl+s') save_act.setStatusTip('Save file') save_act.triggered.connect(self.save) # Save as save_as = QAction('Save &As', self) save_as.setStatusTip('Save file as') save_as.triggered.connect(self.save_as_dialog) # import import_act = QAction('&Import', self) import_act.setShortcut('Ctrl+i') import_act.setStatusTip('Import file') import_act.triggered.connect(self.import_file_dialog) # export export_act = QAction('&Export', self) export_act.setShortcut('Ctrl+e') export_act.setStatusTip('Export file') export_act.triggered.connect(self.export_file_dialog) # File Menu menu = self.menuBar() fileMenu = menu.addMenu('&File') fileMenu.addAction(open_act) fileMenu.addAction(save_act) fileMenu.addAction(save_as) fileMenu.addSeparator() fileMenu.addAction(import_act) fileMenu.addAction(export_act) fileMenu.addSeparator() fileMenu.addAction(exit_act) # Tools shell_Act = QAction('&Interactive Shell', self) shell_Act.setShortcut('Ctrl+Shift+I') shell_Act.setStatusTip('Run interactive commands') shell_Act.triggered.connect(self.open_interactive_shell) kcl_calc_Act = QAction('&KCL Calculator', self) kcl_calc_Act.setShortcut('Ctrl+k') kcl_calc_Act.setStatusTip('KCL Flag Calculator') kcl_calc_Act.triggered.connect(self.open_kcl_calculator) toolMenu = menu.addMenu('&Tools') toolMenu.addAction(shell_Act) toolMenu.addAction(kcl_calc_Act) # Help report_Act = QAction('&Report Issue', self) report_Act.setStatusTip('Report an issue') report_Act.triggered.connect(self.report_issue) website_Act = QAction('&Website', self) website_Act.setStatusTip('Visit website') website_Act.triggered.connect(self.open_website) about_Act = QAction('&About', self) about_Act.setStatusTip('Information about ABMatt') about_Act.triggered.connect(self.about_abmatt) help_menu = menu.addMenu('&Help') help_menu.addAction(report_Act) help_menu.addAction(website_Act) help_menu.addSeparator() help_menu.addAction(about_Act) def open_website(self): webbrowser.open('https://github.com/Robert-N7/abmatt') def report_issue(self): webbrowser.open('https://github.com/Robert-N7/abmatt/issues') def about_abmatt(self): self.box = QMessageBox() bit_size = '64-Bit' if sys.maxsize > 2**32 else '32-Bit' self.box.setText( f'ABMatt Version {load_config.VERSION} {platform.platform()} {bit_size}' ) self.box.setWindowTitle('ABMatt') self.box.show() def open_kcl_calculator(self): self.calculator = KCLCalculator() def open_interactive_shell(self): if not self.shell_is_shown: if self.shell is None: self.shell = InteractiveCmd() self.left.addWidget(self.shell) else: self.shell.show() self.shell_is_shown = True else: self.shell_is_shown = False self.shell.hide() def locate_material(self, brres_path): return self.material_browser.locate_material(brres_path) def __init_child_UI(self, top_layout): # left vert_widget = QWidget(self) # policy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.MinimumExpanding) # policy.setHorizontalStretch(2) # vert_widget.setSizePolicy(policy) top_layout.addWidget(vert_widget) self.left = vert_layout = QVBoxLayout() vert_widget.setLayout(vert_layout) widget = QWidget(self) vert_layout.addWidget(widget) center_layout = QHBoxLayout() widget.setLayout(center_layout) self.logger = QPlainTextEdit(self) self.logger.setReadOnly(True) self.logger.setFixedHeight(100) vert_layout.addWidget(self.logger) self.treeview = BrresTreeView(self) self.treeview.setMinimumWidth(300) center_layout.addWidget(self.treeview) self.poly_editor = PolyEditor(self) center_layout.addWidget(self.poly_editor) # center_widget.setGeometry(0, 0, 300, 300) # right # top_layout.addSpacing(30) self.material_browser = MaterialTabs(self) policy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.MinimumExpanding) policy.setHorizontalStretch(1) self.material_browser.setSizePolicy(policy) top_layout.addWidget(self.material_browser) # self.material_browser.setFixedWidth(300) def __init_UI(self): self.setWindowTitle('ANoobs Brres Material Tool') self.resize(1000, 700) self.__init_menus() main_layout = QHBoxLayout() self.__init_child_UI(main_layout) widget = QWidget() widget.setLayout(main_layout) self.setCentralWidget(widget) self.statusBar().showMessage('Ready') def on_image_update(self, brres_dir): # simply gives it back to the image manager to update observers self.image_manager.notify_image_observers(*brres_dir) def on_update_polygon(self, poly): enable_edits = poly.parent.parent not in self.locked_files self.poly_editor.on_update_polygon(poly, enable_edits=enable_edits) def emit(self, message, head=None, tail=None): message = message.replace('\n', '<br/>').replace(' ', ' ') if head: message = head + message if tail: message += tail self.logger.appendHtml(message) def get_brres_by_fname(self, fname): path = os.path.abspath(fname) for x in self.open_files: if os.path.abspath(x.name) == path: return x def set_brres(self, brres): if brres != self.brres: self.brres = brres def open_dialog(self): fname, filter = QFileDialog.getOpenFileName(self, 'Open file', self.cwd, "Brres files (*.brres)") if fname: self.open(fname) def on_node_update(self, node): self.treeview.on_brres_update(node) def on_rename_update(self, node, old_name): if type(node) == Brres: self.treeview.on_brres_rename(old_name, node.name) self.material_browser.on_name_update() def on_child_update(self, child): self.treeview.on_brres_update(child.parent) def open(self, fname, force_update=False): self.cwd = os.path.dirname(fname) opened = self.get_brres_by_fname(fname) if opened: if not force_update: return self.set_brres(opened) else: opened = Brres.get_brres(fname) self.open_files.append(opened) opened.register_observer(self) # either it's newly opened or forcing update self.set_brres(opened) self.treeview.on_brres_update(opened) self.material_browser.add_brres_materials_to_scene(opened) def save(self): if len(self.open_files): last = None for x in self.open_files: # A precaution against overwriting old models # overwrite = True if not x.has_new_model else Brres.OVERWRITE if x.save(overwrite=True): last = x if last is not None: self.update_status('Wrote file {}'.format(last.name)) def save_as_dialog(self): if self.brres: fname, filter = QFileDialog.getSaveFileName( self, 'Save as', self.cwd, 'Brres files (*.brres)') if fname: self.cwd = os.path.dirname(fname) self.brres.save(fname, overwrite=True) self.update_status('Wrote file {}'.format(fname)) else: AutoFix.get().error('No Brres file selected.') def import_texture(self, filename): raise NotImplementedError() def on_material_select(self, material): self.material_browser.on_material_select(material) def import_file(self, fname, brres_name=None, brres=None, mdl0=None): if mdl0 is not None: brres = mdl0.parent if not brres: if brres_name is not None: brres = self.get_brres_by_fname(brres_name) elif self.brres and os.path.splitext(os.path.basename(self.brres.name))[0] == \ os.path.splitext(os.path.basename(fname))[0]: brres = self.brres self.cwd, name = os.path.split(fname) base_name, ext = os.path.splitext(name) lower = ext.lower() if lower == '.dae': converter = DaeConverter2(brres, fname, mdl0=mdl0) elif lower == '.obj': converter = ObjConverter(brres, fname, mdl0=mdl0) # elif lower in ('.png', '.jpg', '.bmp', '.tga'): # return self.import_texture(fname) else: self.statusBar().showMessage('Unknown extension {}'.format(ext)) return # converter.load_model() # self.on_conversion_finish(converter) self.update_status('Added {} to queue...'.format(fname)) self.lock_file(converter.brres) self.converter.enqueue(converter) def lock_file(self, brres): self.locked_files.add(brres) self.poly_editor.on_brres_lock(brres) def unlock_file(self, brres): try: self.locked_files.remove(brres) except KeyError: pass self.poly_editor.on_brres_unlock(brres) def on_conversion_finish(self, converter): self.open(converter.brres.name, force_update=True) self.unlock_file(converter.brres) self.update_status('Finished Converting {}'.format( converter.brres.name)) def import_file_dialog(self, brres=None, mdl0=None): fname, filter = QFileDialog.getOpenFileName(self, 'Import model', self.cwd, '(*.dae *.obj)') if fname: self.import_file(fname, brres=brres, mdl0=mdl0) def export_file_dialog(self, brres=None, mdl0=None): if mdl0 is not None: brres = mdl0.parent multiple_models = False if not brres: brres = self.brres if not brres: AutoFix.get().error('Nothing to export!') return elif mdl0 is None: if len(brres.models) > 1: multiple_models = True fname, fil = QFileDialog.getSaveFileName(self, 'Export model', self.cwd, 'Model files (*.dae *.obj)') if fname: self.cwd, name = os.path.split(fname) base_name, ext = os.path.splitext(name) lower = ext.lower() if lower == '.obj': klass = ObjConverter elif lower == '.dae': klass = DaeConverter2 else: self.statusBar().showMessage( 'Unknown extension {}'.format(ext)) return if multiple_models: for x in brres.models: export_name = os.path.join(self.cwd, base_name + '-' + x.name + ext) converter = klass(brres, export_name, encode=False, mdl0=x) self.update_status('Added {} to queue...'.format(x.name)) self.converter.enqueue(converter) else: if mdl0 is None: mdl0 = brres.models[0] converter = klass(brres, fname, encode=False, mdl0=mdl0) self.update_status('Added {} to queue...'.format(mdl0.name)) self.converter.enqueue(converter) def close_file(self, brres=None): if brres is None: brres = self.brres if brres.is_modified: m = QMessageBox(QMessageBox.Warning, 'Save Before Closing', f'Save {brres.name} before closing?', buttons=QMessageBox.Yes | QMessageBox.No, parent=self) if m.exec_() == QMessageBox.Yes: brres.save(overwrite=True) if brres in self.open_files: self.open_files.remove(brres) brres.unregister(self) brres.close(try_save=False) self.brres = None self.poly_editor.on_brres_lock(brres) self.treeview.on_file_close(brres) def shouldExitAnyway(self, result): return result == QMessageBox.Ok def closeEvent(self, event): self.material_browser.on_close() files_to_save = [] for x in self.open_files: if x.is_modified: files_to_save.append(x) if Brres.OVERWRITE: for x in files_to_save: x.close() elif files_to_save: self.files_to_save = files_to_save fnames = ', '.join([x.name for x in files_to_save]) m = QMessageBox(QMessageBox.Warning, 'Confirm Exit?', f'Exit without saving {fnames}?', buttons=QMessageBox.Yes | QMessageBox.No, parent=self) if m.exec_() == QMessageBox.No: event.ignore() return for x in files_to_save: x.close() self.threadpool.clear() self.image_manager.stop() self.converter.stop() event.accept() def info(self, message): self.emit(message, '<p style="color:Blue;">', '</p>') def warn(self, message): self.emit(message, '<p style="color:Red;">', '</p>') def error(self, message): self.emit(message, '<p style="color:Red;">', '</p>') def update_status(self, message): self.statusBar().showMessage(message)
class Main_Window_class(QDialog): PLOTS_NUMBER = 3 EFFECTS_NUMBER = 4 def __init__(self): super().__init__() self.nlabels = 6 self.slider_step = 1 self.slider_default = 0 self.slider_max = 50 self.slider_min = -50 # Коэффициент ослабления эхо эффекта self.echo_coefficient = 1 # Задержка в фреймах self.echo_shift = 1000 # "Жесткий" предел овердрайва за которым волна обрезается self.soft_clipping_hard_limit = 14000 # "Мягкий" предел овердрайва за которым волна сглаживается self.soft_clipping_linear_limit = 12000 # -3 dB self.music_is_playing = False self.threadpool = QThreadPool() self.nchannels = None # number of channels self.sampwidth = None # number of bytes per sample self.framerate = None # number of frames per second self.nframes = None # total number of frames self.comptype = None # compression type self.compname = None # compression type name self.elem_per_hertz = None self.coefficient = 1000 # коэффициент прореживания, для уменьшения частоты дискретизации self.buffer_size = None self.buffer_cnt = 0 self.music_worker = None self.min_freq = 0 self.max_freq = None self.channels = [] self.spectrum = None self.spectrum_original = None self.channels_original = [] self.spectrum_hard_clipping = None self.channels_hard_clipping = [] self.spectrum_soft_clipping = None self.channels_soft_clipping = None self.spectrum_envelop = None self.channels_envelop = [] self.spectrum_echo = None self.channels_echo = [] self.app_name = 'Эквалайзер' self.buttons_labels = ['Воспроизвести', 'Пауза', 'Остановить'] self.bands = [[], []] self.labels = [] self.ui_labels = [] self.sliders = [] self.sliders_workers = [None for _ in range(self.nlabels)] self.sliders_old_values = [ self.slider_default for _ in range(self.nlabels) ] self.LCD_numbers = [] self.canvases = [] self.effects = [ self.doing_hard_clipping, self.doing_envelop, self.doing_echo, self.doing_soft_clipping ] self.effects_checkboxes_labels = [ 'Жесткий клиппинг (дисторшн)', 'Энвелоп', 'Эхо', 'Мягкий клиппинг (овердрайв)' ] self.effects_checkboxes = [] self.effects_checkboxes_workers = [] self.play_button, self.stop_button, self.pause_button = None, None, None self.redraw_mutex = threading.Lock() self.run_ui() def run_ui(self): self.pull_music() self.create_interface() def pull_music(self): path_to_pull = QFileDialog.getOpenFileName(self, 'Выберите .wav файл')[0] wav = wave.open(path_to_pull, mode='r') # nchannels - число каналов .wav файла # sampwidth - число байт на сэмпл # framerate - число фреймов в секунду # nframes - общее число фреймов # comptype - тип сжатия # compname - имя типа сжатия (self.nchannels, self.sampwidth, self.framerate, self.nframes, self.comptype, self.compname) = wav.getparams() # Теорема Котельникова, в дискретном сигнале представлены частоты от нуля до framerate // 2 self.max_freq = self.framerate // 2 self.buffer_size = self.framerate # считываем все фреймы content = wav.readframes(self.nframes) # и сохраняем в массив с нужным типом элемента samples = np.fromstring(content, dtype=IntTypes.types[self.sampwidth]) # разбиваем на каналы, например, \xe2\xff\xe3\xfа — это фрейм 16-битного wav-файла. Значит, \xe2\xff — сэмпл # первого (левого) канала, а \xe3\xfа for i in range(self.nchannels): self.channels.append(samples[i::self.nchannels]) # сохраняем оригинальные каналы self.channels_original = self.channels.copy() # создаем worker'ов, который создадут измененные дорожки с примененными эффектами for i in range(self.EFFECTS_NUMBER): worker = Worker(self.effects[i], self.channels) self.effects_checkboxes_workers.append(worker) self.threadpool.start(worker) # Выполняем быстрое дискретное преобразование Фурье, для получения спектра self.spectrum = np.fft.rfft(self.channels_original) self.spectrum_original = self.spectrum.copy() # запускаем pygame pygame.mixer.pre_init(frequency=self.framerate, size=-8 * self.sampwidth, channels=self.nchannels) pygame.init() def create_bands(self): """Создает подписи к слайдерам""" step = (self.max_freq - self.min_freq) // 2**self.nlabels self.bands[0].append(self.min_freq) self.bands[1].append(self.min_freq + step) for i in range(1, self.nlabels - 1): self.bands[0].append(self.bands[1][i - 1]) self.bands[1].append(self.bands[0][i] + 2**i * step) self.bands[0].append(self.bands[1][self.nlabels - 2]) self.bands[1].append(self.max_freq) for i in range(self.nlabels): self.labels.append(f'{self.bands[0][i]} - {str(self.bands[1][i])}') def create_labels(self): for label in self.labels: self.ui_labels.append(QLabel(label, self)) def create_lcd_numbers(self): for _ in range(self.nlabels): self.LCD_numbers.append(QLCDNumber(self)) def create_sliders(self): for i in range(self.nlabels): slider = QSlider(Qt.Vertical, self) slider.setMinimum(self.slider_min) slider.setMaximum(self.slider_max) slider.setValue(self.slider_default) slider.setFocusPolicy(Qt.StrongFocus) slider.setTickPosition(QSlider.TicksBothSides) slider.setSingleStep(self.slider_step) slider.valueChanged[int].connect(self.slider_change_value) slider.valueChanged[int].connect(self.LCD_numbers[i].display) self.sliders.append(slider) def create_checkboxes(self): for i in range(self.EFFECTS_NUMBER): checkbox = QCheckBox(self.effects_checkboxes_labels[i], self) checkbox.setChecked(False) checkbox.stateChanged.connect(self.checkbox_clicked_listener) self.effects_checkboxes.append(checkbox) def create_buttons(self): self.play_button = QPushButton(self.buttons_labels[0], self) self.pause_button = QPushButton(self.buttons_labels[1], self) self.stop_button = QPushButton(self.buttons_labels[2], self) self.play_button.clicked.connect(self.button_clicked_listener) self.pause_button.clicked.connect(self.button_clicked_listener) self.stop_button.clicked.connect(self.button_clicked_listener) def create_graphics(self): self.create_lcd_numbers() self.create_sliders() self.create_bands() self.create_labels() self.create_checkboxes() self.create_buttons() self.elem_per_hertz = self.spectrum.shape[1] // (self.max_freq - self.min_freq) plots_labels = [('Частота, Гц', 'Амплитуда'), ('Частота, Гц', 'Амплитуда'), ('Время, с', 'Амплитуда')] plots_sources = [ (self.channels[0][::self.coefficient], ), (np.fft.rfftfreq(self.nframes, 1. / self.framerate)[::self.coefficient], np.abs(self.spectrum[0][::self.coefficient]) / self.nframes), (np.fft.rfftfreq(self.nframes, 1. / self.framerate)[::self.coefficient], np.abs(self.spectrum[0][::self.coefficient]) / self.nframes) ] for i in range(self.PLOTS_NUMBER): figure = plt.figure() subplot = figure.add_subplot(1, 1, 1) subplot.plot(*plots_sources[i]) subplot.set_xlabel(plots_labels[i][0]) subplot.set_ylabel(plots_labels[i][1]) figure.align_xlabels() figure.align_ylabels() canvas = FigureCanvas(figure) navigation_tool = NavigationToolbar(canvas, self) canvas = { 'figure': figure, 'canvas': canvas, 'navigation_tool': navigation_tool, 'axes_labels': plots_labels[i], } self.canvases.append(canvas) canvas['canvas'].draw() def create_interface(self): self.create_graphics() labels_box = QHBoxLayout() for label in self.ui_labels: labels_box.addWidget(label) nums_box = QHBoxLayout() for number in self.LCD_numbers: nums_box.addWidget(number) sliders_box = QHBoxLayout() for slider in self.sliders: sliders_box.addWidget(slider) graph_box = QVBoxLayout() graph_box.addWidget(self.canvases[0]['navigation_tool']) graph_box.addWidget(self.canvases[0]['canvas']) left_box = QVBoxLayout() left_box.addLayout(labels_box) left_box.addLayout(sliders_box) left_box.addLayout(nums_box) left_box.addLayout(graph_box) checkbox_and_button_layout = QHBoxLayout() for i in range(self.EFFECTS_NUMBER): checkbox_and_button_layout.addWidget(self.effects_checkboxes[i]) checkbox_and_button_layout.addWidget(self.play_button) checkbox_and_button_layout.addWidget(self.pause_button) checkbox_and_button_layout.addWidget(self.stop_button) graph_box = QVBoxLayout() graph_box.addWidget(self.canvases[1]['navigation_tool']) graph_box.addWidget(self.canvases[1]['canvas']) graph_box.addWidget(self.canvases[2]['navigation_tool']) graph_box.addWidget(self.canvases[2]['canvas']) right_box = QVBoxLayout() right_box.addLayout(checkbox_and_button_layout) right_box.addLayout(graph_box) all_box = QHBoxLayout() all_box.addLayout(left_box) all_box.addLayout(right_box) self.setLayout(all_box) self.setWindowTitle(self.app_name) self.showMaximized() def slider_change_value(self, value): for i, slider in enumerate(self.sliders): if self.sender() == slider: self.sliders_workers[i] = Worker(self.music_edit, i, value) self.threadpool.start(self.sliders_workers[i]) def checkbox_clicked_listener(self, state): if self.sender() == self.effects_checkboxes[0]: if state == Qt.Checked: self.effects_checkboxes[1].setChecked(False) self.effects_checkboxes[2].setChecked(False) self.effects_checkboxes[3].setChecked(False) self.channels = self.channels_hard_clipping.copy() self.spectrum = self.spectrum_hard_clipping.copy() else: self.channels = self.channels_original.copy() self.spectrum = self.spectrum_original.copy() elif self.sender() == self.effects_checkboxes[1]: if state == Qt.Checked: self.effects_checkboxes[0].setChecked(False) self.effects_checkboxes[2].setChecked(False) self.effects_checkboxes[3].setChecked(False) self.channels = self.channels_envelop.copy() self.spectrum = self.spectrum_envelop.copy() else: self.channels = self.channels_original.copy() self.spectrum = self.spectrum_original.copy() elif self.sender() == self.effects_checkboxes[2]: if state == Qt.Checked: self.effects_checkboxes[0].setChecked(False) self.effects_checkboxes[1].setChecked(False) self.effects_checkboxes[3].setChecked(False) self.channels = self.channels_echo.copy() self.spectrum = self.spectrum_echo.copy() else: self.channels = self.channels_original.copy() self.spectrum = self.spectrum_original.copy() elif self.sender() == self.effects_checkboxes[3]: if state == Qt.Checked: self.effects_checkboxes[0].setChecked(False) self.effects_checkboxes[1].setChecked(False) self.effects_checkboxes[2].setChecked(False) self.channels = self.channels_soft_clipping.copy() self.spectrum = self.spectrum_soft_clipping.copy() else: self.channels = self.channels_original.copy() self.spectrum = self.spectrum_original.copy() for slider in self.sliders: slider.setValue(self.slider_default) draw_1 = Worker(self.draw_array, self.spectrum, 0) self.threadpool.start(draw_1) draw_2 = Worker(self.draw_array, self.channels, 1) self.threadpool.start(draw_2) def button_clicked_listener(self): if self.sender() == self.play_button: # Запустить if not self.music_is_playing: self.music_is_playing = True self.music_worker = Worker(self.start_music) self.threadpool.start(self.music_worker) elif self.sender() == self.pause_button: # Пауза if self.music_is_playing: self.music_is_playing = False elif self.sender() == self.stop_button: # Остановить if self.music_is_playing: self.music_is_playing = False self.threadpool.clear() for slider in self.sliders: worker = Worker(self.music_edit, self.sliders.index(slider), self.slider_default) self.sliders_workers.append(worker) self.threadpool.start(worker) self.threadpool.start(Worker(self.wait_until_sliders_launched)) for slider in self.sliders: slider.setValue(self.slider_default) self.buffer_cnt = 0 for i in range(self.EFFECTS_NUMBER): self.effects_checkboxes[i].setChecked(False) def wait_until_sliders_launched(self): while self.threadpool.activeThreadCount() != len(self.sliders): sleep(0.1) self.channels = self.channels_original.copy() self.spectrum = self.spectrum_original.copy() def start_music(self): tmp_channels = [ self.channels[0][self.buffer_cnt * self.buffer_size:(self.buffer_cnt + 1) * self.buffer_size + 1:], self.channels[1][self.buffer_cnt * self.buffer_size:(self.buffer_cnt + 1) * self.buffer_size + 1:] ] tmp_channels = np.array(tmp_channels) tmp_channels = np.ascontiguousarray(tmp_channels.T) tmp_sound = pygame.sndarray.make_sound(tmp_channels) sound = tmp_sound if not self.music_is_playing: return pygame.mixer.Sound.play(sound) start_pos = self.buffer_cnt for self.buffer_cnt in range(start_pos + 1, self.nframes // self.buffer_size): tmp_channels = [ self.channels[0][self.buffer_cnt * self.buffer_size:(self.buffer_cnt + 1) * self.buffer_size + 1:], self.channels[1][self.buffer_cnt * self.buffer_size:(self.buffer_cnt + 1) * self.buffer_size + 1:] ] tmp_channels = np.array(tmp_channels) tmp_channels = np.ascontiguousarray(tmp_channels.T) tmp_sound = pygame.sndarray.make_sound(tmp_channels) while pygame.mixer.get_busy(): sleep(0.01) sound = tmp_sound if not self.music_is_playing: return pygame.mixer.Sound.play(sound) tmp_channels = [ self.channels[0][self.buffer_cnt * self.buffer_size::], self.channels[1][self.buffer_cnt * self.buffer_size::] ] tmp_channels = np.array(tmp_channels) tmp_channels = np.ascontiguousarray(tmp_channels.T) tmp_sound = pygame.sndarray.make_sound(tmp_channels) while pygame.mixer.get_busy(): sleep(0.01) sound = tmp_sound if not self.music_is_playing: return pygame.mixer.Sound.play(sound) self.buffer_cnt = 0 self.music_is_playing = False def music_edit(self, pos, value): old_value = self.sliders_old_values[pos] self.sliders_old_values[pos] = value if old_value == value: return if pos == 0: for i in range(self.nchannels): self.spectrum[i][:self.elem_per_hertz * self.bands[1][pos] + 1] *= 10**((value - old_value) / 20) elif pos == 5: for i in range(self.nchannels): self.spectrum[i][self.elem_per_hertz * self.bands[0][pos]:] *= 10**( (value - old_value) / 20) else: for i in range(self.nchannels): self.spectrum[i][self.elem_per_hertz * self.bands[0][pos]:self.elem_per_hertz * self.bands[1][pos] + 1] *= 10**((value - old_value) / 20) self.channels = (np.fft.irfft(self.spectrum)).astype( IntTypes.types[self.sampwidth]) draw_1 = Worker(self.draw_array, self.spectrum, 0) self.threadpool.start(draw_1) draw_2 = Worker(self.draw_array, self.channels, 1) self.threadpool.start(draw_2) def redraw_subplot(self, canvas: dict, left, right=None): # потоконебезопасная функция, нужен mutex self.redraw_mutex.acquire() canvas['figure'].clear() subplot = canvas['figure'].add_subplot(1, 1, 1) subplot.set_xlabel(canvas['axes_labels'][0]) subplot.set_ylabel(canvas['axes_labels'][1]) canvas['figure'].align_xlabels() canvas['figure'].align_ylabels() if right is not None: subplot.plot(left, right) else: subplot.plot(left) canvas['canvas'].draw() self.redraw_mutex.release() def draw_array(self, arr, spectrum_or_channel): if spectrum_or_channel == 0: self.redraw_subplot( self.canvases[1], np.fft.rfftfreq(self.nframes, 1. / self.framerate)[::self.coefficient], np.abs(arr[0][::self.coefficient]) / self.nframes) else: self.redraw_subplot(self.canvases[0], arr[0][::self.coefficient]) def doing_hard_clipping(self, channels): threshold_max = int(0.6 * np.max(channels[0])) threshold_min = int(0.6 * np.min(channels[0])) self.channels_hard_clipping = np.maximum( np.minimum(channels, threshold_max), threshold_min).astype(IntTypes.types[self.sampwidth]) self.spectrum_hard_clipping = np.fft.rfft(self.channels_hard_clipping) def doing_soft_clipping(self, channels): clip_limit = self.soft_clipping_linear_limit + int( pi / 2 * (self.soft_clipping_hard_limit - self.soft_clipping_linear_limit)) scale = self.soft_clipping_hard_limit - self.soft_clipping_linear_limit tmp_channels = np.array(channels, copy=True) for i in range(len(tmp_channels)): for j in range(len(tmp_channels[i])): n = tmp_channels[i][j] amplitude, sign = abs(n), 1 if n >= 0 else -1 if amplitude <= self.soft_clipping_linear_limit: tmp_channels[i][j] = n continue if amplitude >= clip_limit: tmp_channels[i][j] = self.soft_clipping_hard_limit * sign continue compression = scale * sin( float(amplitude - self.soft_clipping_linear_limit) / scale) tmp_channels[i][j] = (self.soft_clipping_linear_limit + int(compression)) * sign self.channels_soft_clipping = tmp_channels self.spectrum_soft_clipping = np.fft.rfft(self.channels_soft_clipping) def doing_envelop(self, channels): frequency = 1 / 15 envelope_sig = np.array([ abs(sin(2 * pi * frequency * t / self.framerate)) for t in range(self.nframes) ]) tmp_channels = np.array(channels, copy=True) for i in range(self.nchannels): tmp_channels[i] = (tmp_channels[i] * envelope_sig).astype( IntTypes.types[self.sampwidth]) self.channels_envelop = tmp_channels self.spectrum_envelop = np.fft.rfft(self.channels_envelop) def doing_echo(self, channels): tmp_channels = np.array(channels, copy=True) echo_channels = tmp_channels.copy() for i in range(len(tmp_channels)): echo_channels[i] = (echo_channels[i] * self.echo_coefficient).astype( IntTypes.types[self.sampwidth]) echo_channels[i] = np.append(echo_channels[i][self.echo_shift:], np.zeros(self.echo_shift)).astype( IntTypes.types[self.sampwidth]) tmp_channels[i] += echo_channels[i] self.channels_echo = tmp_channels self.spectrum_echo = np.fft.rfft(self.channels_echo)
class EulerSquareUi(object): def setupUi(self, Form): self.threadpool = QThreadPool() self.controller = 1 Form.setObjectName("Form") Form.resize(1144, 554) self.eulerSquareMethodsList = QtWidgets.QListView(Form) self.eulerSquareMethodsList.setGeometry(QtCore.QRect(20, 30, 111, 192)) self.eulerSquareMethodsList.setObjectName("eulerSquareMethodsList") entries = [ 'HillClimbing', 'Evolutionary algorithm', 'Particle Swarm Optimisation', "Ant Colony Optimisation" ] model = QtGui.QStandardItemModel() self.eulerSquareMethodsList.setModel(model) for i in entries: item = QtGui.QStandardItem(i) model.appendRow(item) self.sizeLabel = QtWidgets.QLabel(Form) self.sizeLabel.setGeometry(QtCore.QRect(150, 30, 55, 16)) self.sizeLabel.setObjectName("sizeLabel") self.firstSetLabel = QtWidgets.QLabel(Form) self.firstSetLabel.setGeometry(QtCore.QRect(150, 70, 55, 16)) self.firstSetLabel.setObjectName("firstSetLabel") self.secondSetLabel = QtWidgets.QLabel(Form) self.secondSetLabel.setGeometry(QtCore.QRect(150, 120, 71, 16)) self.secondSetLabel.setObjectName("secondSetLabel") self.titleLabel = QtWidgets.QLabel(Form) self.titleLabel.setGeometry(QtCore.QRect(20, 10, 301, 16)) self.titleLabel.setObjectName("titleLabel") self.sizeEdit = QtWidgets.QLineEdit(Form) self.sizeEdit.setGeometry(QtCore.QRect(280, 30, 113, 22)) self.sizeEdit.setObjectName("sizeEdit") self.firstSetEdit = QtWidgets.QLineEdit(Form) self.firstSetEdit.setGeometry(QtCore.QRect(280, 70, 113, 22)) self.firstSetEdit.setObjectName("firstSetEdit") self.secondSetEdit = QtWidgets.QLineEdit(Form) self.secondSetEdit.setGeometry(QtCore.QRect(280, 120, 113, 22)) self.secondSetEdit.setObjectName("secondSetEdit") self.startButton = QtWidgets.QPushButton(Form) self.startButton.setGeometry(QtCore.QRect(30, 270, 93, 28)) self.startButton.setObjectName("startButton") self.startButton.clicked.connect(self.startButtonClicked) self.crossoverEdit = QtWidgets.QLineEdit(Form) self.crossoverEdit.setGeometry(QtCore.QRect(280, 190, 113, 22)) self.crossoverEdit.setObjectName("crossoverEdit") self.probabilityOfCrossover = QtWidgets.QLabel(Form) self.probabilityOfCrossover.setGeometry(QtCore.QRect( 140, 190, 141, 16)) self.probabilityOfCrossover.setObjectName("probabilityOfCrossover") self.probabilityOfMutationEdit = QtWidgets.QLineEdit(Form) self.probabilityOfMutationEdit.setGeometry( QtCore.QRect(280, 230, 113, 22)) self.probabilityOfMutationEdit.setObjectName( "probabilityOfMutationEdit") self.populationEdit = QtWidgets.QLineEdit(Form) self.populationEdit.setGeometry(QtCore.QRect(280, 290, 113, 22)) self.populationEdit.setObjectName("populationEdit") self.populationSizeButton = QtWidgets.QLabel(Form) self.populationSizeButton.setGeometry(QtCore.QRect(140, 290, 121, 16)) self.populationSizeButton.setObjectName("populationSizeButton") self.ProbabilityMutationButton = QtWidgets.QLabel(Form) self.ProbabilityMutationButton.setGeometry( QtCore.QRect(140, 230, 131, 16)) self.ProbabilityMutationButton.setObjectName( "ProbabilityMutationButton") self.generationEdit = QtWidgets.QLineEdit(Form) self.generationEdit.setGeometry(QtCore.QRect(280, 340, 113, 22)) self.generationEdit.setObjectName("generationEdit") self.generationsLabel = QtWidgets.QLabel(Form) self.generationsLabel.setGeometry(QtCore.QRect(140, 340, 131, 16)) self.generationsLabel.setObjectName("generationsLabel") self.optionalLabel = QtWidgets.QLabel(Form) self.optionalLabel.setGeometry(QtCore.QRect(190, 150, 141, 20)) self.optionalLabel.setObjectName("optionalLabel") self.bestSolutionView = QtWidgets.QListView(Form) self.bestSolutionView.setGeometry(QtCore.QRect(740, 200, 311, 251)) self.bestSolutionView.setObjectName("bestSolutionView") self.stopButton = QtWidgets.QPushButton(Form) self.stopButton.setGeometry(QtCore.QRect(840, 460, 93, 28)) self.stopButton.setObjectName("stopButton") self.stopButton.clicked.connect(self.stopButtonClicked) self.solutionModel = QtGui.QStandardItemModel() self.bestSolutionView.setModel(self.solutionModel) self.bestSolutionLabel = QtWidgets.QLabel(Form) self.bestSolutionLabel.setGeometry(QtCore.QRect(810, 150, 161, 31)) self.bestSolutionLabel.setObjectName("bestSolutionLabel") self.psoParametersLabel = QtWidgets.QLabel(Form) self.psoParametersLabel.setGeometry(QtCore.QRect(470, 160, 131, 16)) self.psoParametersLabel.setObjectName("psoParametersLabel") self.populationPSOLabel = QtWidgets.QLabel(Form) self.populationPSOLabel.setGeometry(QtCore.QRect(410, 190, 71, 16)) self.populationPSOLabel.setObjectName("populationPSOLabel") self.c1Label = QtWidgets.QLabel(Form) self.c1Label.setGeometry(QtCore.QRect(410, 230, 55, 16)) self.c1Label.setObjectName("c1Label") self.c2Label = QtWidgets.QLabel(Form) self.c2Label.setGeometry(QtCore.QRect(410, 270, 55, 16)) self.c2Label.setObjectName("c2Label") self.wLabel = QtWidgets.QLabel(Form) self.wLabel.setGeometry(QtCore.QRect(410, 300, 55, 16)) self.wLabel.setObjectName("wLabel") self.neighborhoodLabel = QtWidgets.QLabel(Form) self.neighborhoodLabel.setGeometry(QtCore.QRect(410, 350, 111, 16)) self.neighborhoodLabel.setObjectName("neighborhoodLabel") self.iterationLabel = QtWidgets.QLabel(Form) self.iterationLabel.setGeometry(QtCore.QRect(410, 390, 121, 16)) self.iterationLabel.setObjectName("iterationLabel") self.populationPSOEdit = QtWidgets.QLineEdit(Form) self.populationPSOEdit.setGeometry(QtCore.QRect(480, 190, 113, 22)) self.populationPSOEdit.setObjectName("populationPSOEdit") self.c1PSOEdit = QtWidgets.QLineEdit(Form) self.c1PSOEdit.setGeometry(QtCore.QRect(480, 230, 113, 22)) self.c1PSOEdit.setObjectName("c1PSOEdit") self.c2PSOEdit = QtWidgets.QLineEdit(Form) self.c2PSOEdit.setGeometry(QtCore.QRect(480, 270, 113, 22)) self.c2PSOEdit.setObjectName("c2PSOEdit") self.wPSOEdit = QtWidgets.QLineEdit(Form) self.wPSOEdit.setGeometry(QtCore.QRect(480, 300, 113, 22)) self.wPSOEdit.setObjectName("wPSOEdit") self.neighborhoodPSOEdit = QtWidgets.QLineEdit(Form) self.neighborhoodPSOEdit.setGeometry(QtCore.QRect(540, 350, 113, 22)) self.neighborhoodPSOEdit.setObjectName("neighborhoodPSOEdit") self.IterationsPSOEdit = QtWidgets.QLineEdit(Form) self.IterationsPSOEdit.setGeometry(QtCore.QRect(540, 390, 113, 22)) self.IterationsPSOEdit.setObjectName("IterationsPSOEdit") self.AcoLabel = QtWidgets.QLabel(Form) self.AcoLabel.setGeometry(QtCore.QRect(500, 10, 131, 16)) self.AcoLabel.setObjectName("AcoLabel") self.NoEpoch = QtWidgets.QLabel(Form) self.NoEpoch.setGeometry(QtCore.QRect(400, 30, 111, 16)) self.NoEpoch.setObjectName("NoEpoch") self.AntLabel = QtWidgets.QLabel(Form) self.AntLabel.setGeometry(QtCore.QRect(400, 70, 101, 16)) self.AntLabel.setObjectName("AntLabel") self.alphaLabel = QtWidgets.QLabel(Form) self.alphaLabel.setGeometry(QtCore.QRect(400, 120, 55, 16)) self.alphaLabel.setObjectName("alphaLabel") self.betaLabel = QtWidgets.QLabel(Form) self.betaLabel.setGeometry(QtCore.QRect(630, 30, 31, 16)) self.betaLabel.setObjectName("betaLabel") self.rhoLabel = QtWidgets.QLabel(Form) self.rhoLabel.setGeometry(QtCore.QRect(630, 70, 31, 16)) self.rhoLabel.setObjectName("rhoLabel") self.q0Label = QtWidgets.QLabel(Form) self.q0Label.setGeometry(QtCore.QRect(630, 120, 21, 16)) self.q0Label.setObjectName("q0Label") self.NoEpochEdit = QtWidgets.QLineEdit(Form) self.NoEpochEdit.setGeometry(QtCore.QRect(510, 30, 113, 22)) self.NoEpochEdit.setObjectName("NoEpochEdit") self.NoAntsEdit = QtWidgets.QLineEdit(Form) self.NoAntsEdit.setGeometry(QtCore.QRect(510, 70, 113, 22)) self.NoAntsEdit.setObjectName("NoAntsEdit") self.alphaEdit = QtWidgets.QLineEdit(Form) self.alphaEdit.setGeometry(QtCore.QRect(510, 120, 113, 22)) self.alphaEdit.setObjectName("alphaEdit") self.betaEdit = QtWidgets.QLineEdit(Form) self.betaEdit.setGeometry(QtCore.QRect(660, 30, 113, 22)) self.betaEdit.setObjectName("betaEdit") self.rhoEdit = QtWidgets.QLineEdit(Form) self.rhoEdit.setGeometry(QtCore.QRect(660, 70, 113, 22)) self.rhoEdit.setObjectName("rhoEdit") self.q0Edit = QtWidgets.QLineEdit(Form) self.q0Edit.setGeometry(QtCore.QRect(660, 120, 113, 22)) self.q0Edit.setObjectName("q0Edit") self.retranslateUi(Form) QtCore.QMetaObject.connectSlotsByName(Form) def retranslateUi(self, Form): _translate = QtCore.QCoreApplication.translate Form.setWindowTitle(_translate("Form", "Form")) self.sizeLabel.setText(_translate("Form", "Size")) self.firstSetLabel.setText(_translate("Form", "First Set")) self.secondSetLabel.setText(_translate("Form", "Second Set")) self.titleLabel.setText( _translate("Form", "Please fill in the parameters and select the method")) self.startButton.setText(_translate("Form", "Start")) self.probabilityOfCrossover.setText( _translate("Form", "Probability of Crossover")) self.populationSizeButton.setText(_translate("Form", "Population")) self.ProbabilityMutationButton.setText( _translate("Form", "Probability of Mutation")) self.generationsLabel.setText(_translate("Form", "Generations")) self.optionalLabel.setText(_translate("Form", "Parameters for EA:")) self.bestSolutionLabel.setText( _translate("Form", "Best solution found yet:")) self.psoParametersLabel.setText( _translate("Form", "Paremeters for PSO:")) self.populationPSOLabel.setText(_translate("Form", "Population:")) self.c1Label.setText(_translate("Form", "c1:")) self.c2Label.setText(_translate("Form", "c2:")) self.wLabel.setText(_translate("Form", "w:")) self.neighborhoodLabel.setText(_translate("Form", "neighborhood Size:")) self.iterationLabel.setText(_translate("Form", "Number of Iterations:")) self.stopButton.setText(_translate("Form", "Stop")) self.AcoLabel.setText(_translate("Form", "parameters for ACO:")) self.NoEpoch.setText(_translate("Form", "Number of Epoch:")) self.AntLabel.setText(_translate("Form", "Number of Ants:")) self.alphaLabel.setText(_translate("Form", "Alpha:")) self.betaLabel.setText(_translate("Form", "Beta:")) self.rhoLabel.setText(_translate("Form", "Rho:")) self.q0Label.setText(_translate("Form", "Q0:")) def makePopulationEA(self, pop, n, firstSet, secondSet): population = [] for i in range(0, pop): matrix = [] for j in range(0, n): matrix.append([]) for k in range(0, n): first = rand.randint(0, n - 1) second = rand.randint(0, n - 1) matrix[j].append([firstSet[first], secondSet[second]]) population.append(copy.deepcopy(matrix)) return population def makePopulationPSO(self, pop, n, firstSet, secondSet): return [particle(n, firstSet, secondSet) for x in range(pop)] def startButtonClicked(self): itms = self.eulerSquareMethodsList.selectedIndexes() itm = itms[0].row() size = int(self.sizeEdit.text()) firstSet = self.firstSetEdit.text().split(" ") secondSet = self.secondSetEdit.text().split(" ") if (itm == 0): init = [] for i in range(0, size): init.append([]) for j in range(0, size): first = rand.randint(0, size - 1) second = rand.randint(0, size - 1) init[i].append([firstSet[first], secondSet[second]]) elif (itm == 1): PCrossover = float(self.crossoverEdit.text()) PMutation = float(self.probabilityOfMutationEdit.text()) population = int(self.populationEdit.text()) generations = int(self.generationEdit.text()) init = self.makePopulationEA(population, size, firstSet, secondSet) elif (itm == 2): population = int(self.populationPSOEdit.text()) c1 = float(self.c1PSOEdit.text()) c2 = float(self.c2PSOEdit.text()) w = float(self.wPSOEdit.text()) neighborhoodSize = int(self.neighborhoodPSOEdit.text()) iterations = int(self.IterationsPSOEdit.text()) init = self.makePopulationPSO(population, size, firstSet, secondSet) elif (itm == 3): noEpoch = int(self.NoEpochEdit.text()) noAnts = int(self.NoAntsEdit.text()) alpha = float(self.alphaEdit.text()) beta = float(self.betaEdit.text()) rho = float(self.rhoEdit.text()) q0 = float(self.q0Edit.text()) init = [] problem = EulerSquare(init, firstSet, secondSet) self.controller = Controller(problem) if (itm == 0): self.worker = Worker(self.controller.HillClimbing, self.populateView, 2) self.threadpool.start(self.worker) elif (itm == 1): self.worker = Worker(self.controller.EA, self.populateView, 2, population, PMutation, PCrossover, generations) self.threadpool.start(self.worker) elif (itm == 2): self.worker = Worker(self.controller.PSO, self.populateView, 2, neighborhoodSize, c1, c2, w, iterations) self.threadpool.start(self.worker) elif (itm == 3): self.worker = Worker(self.controller.ACO, self.populateView, 2, noEpoch, noAnts, alpha, beta, rho, q0) self.threadpool.start(self.worker) def stopButtonClicked(self): self.worker.stop() self.threadpool.clear() def populateView(self, res, matrix, score, iteration): if (res == True): itemSucces = QtGui.QStandardItem("Finished") else: itemSucces = QtGui.QStandardItem("Not Finished Yet") self.solutionModel.clear() self.solutionModel.appendRow(itemSucces) itemIteration = QtGui.QStandardItem("Iteration:" + str(iteration)) self.solutionModel.appendRow(itemIteration) itemScore = QtGui.QStandardItem("score: " + "-" + str(score)) self.solutionModel.appendRow(itemScore) for i in range(0, len(matrix)): line = "" for j in range(0, len(matrix)): line += "(" + str(matrix[i][j][0]) + "," + str( matrix[i][j][1]) + ")" + " " itemLine = QtGui.QStandardItem(line) self.solutionModel.appendRow(itemLine) def show(self): Form = QtWidgets.QWidget() ui = EulerSquareUi() ui.setupUi(Form) Form.show()
class RelialokMainWindow(object): def __init__(self, MainWindow, *args, **kwargs): ''' Main front-end GUI class. Defines backend functions for hardware interface and front-end widgets for control and monitoring of interlock. :param MainWindow: :param args: MainWindow (QtWidgets.QMainWindow()) :param kwargs: None ''' # Class variables and flags self.connection_open = False self.com_ports = [ comport.device for comport in serial.tools.list_ports.comports() ] self.serial = None self.setup_ui(MainWindow) def setup_ui(self, MainWindow): ''' Definition of GUI widgets, positioning, and framing. Also connects functions to widget hooks. ''' # Gui definition MainWindow.setObjectName("MainWindow") MainWindow.resize(933, 725) MainWindow.setMinimumSize(QtCore.QSize(933, 725)) MainWindow.setMaximumSize(QtCore.QSize(934, 726)) MainWindow.setAutoFillBackground(True) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") # Define GUI button positions self.pushButton = QtWidgets.QPushButton(self.centralwidget) self.pushButton.setGeometry(QtCore.QRect(670, 650, 75, 23)) self.pushButton.setObjectName("pushButton") self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget) self.pushButton_2.setGeometry(QtCore.QRect(750, 650, 75, 23)) self.pushButton_2.setAutoFillBackground(True) self.pushButton_2.setObjectName("pushButton_2") self.pushButton_7 = QtWidgets.QPushButton(self.centralwidget) self.pushButton_7.setGeometry(QtCore.QRect(830, 650, 75, 23)) self.pushButton_7.setObjectName("pushButton_7") # Define text box self.textBox = QtWidgets.QTextEdit(self.centralwidget) self.textBox.setGeometry(QtCore.QRect(20, 240, 881, 381)) self.textBox.setObjectName("textBox") # Define cursor in text box self.cursor = QTextCursor(self.textBox.document()) # Define GUI structure & grid layout self.line = QtWidgets.QFrame(self.centralwidget) self.line.setGeometry(QtCore.QRect(20, 160, 321, 16)) self.line.setFrameShape(QtWidgets.QFrame.HLine) self.line.setFrameShadow(QtWidgets.QFrame.Sunken) self.line.setObjectName("line") self.line_2 = QtWidgets.QFrame(self.centralwidget) self.line_2.setGeometry(QtCore.QRect(420, 160, 321, 20)) self.line_2.setFrameShape(QtWidgets.QFrame.HLine) self.line_2.setFrameShadow(QtWidgets.QFrame.Sunken) self.line_2.setObjectName("line_2") self.label_9 = QtWidgets.QLabel(self.centralwidget) self.label_9.setGeometry(QtCore.QRect(360, 160, 47, 16)) self.gridLayoutWidget_2 = QtWidgets.QWidget(self.centralwidget) self.gridLayoutWidget_2.setGeometry(QtCore.QRect(759, 30, 141, 201)) self.gridLayoutWidget_2.setObjectName("gridLayoutWidget_2") self.gridLayout_2 = QtWidgets.QGridLayout(self.gridLayoutWidget_2) self.gridLayout_2.setContentsMargins(0, 0, 0, 0) self.gridLayout_2.setObjectName("gridLayout_2") self.horizontalLayoutWidget = QtWidgets.QWidget(self.centralwidget) self.horizontalLayoutWidget.setGeometry(QtCore.QRect(20, 190, 721, 41)) self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget") self.horizontalLayout = QtWidgets.QHBoxLayout( self.horizontalLayoutWidget) self.horizontalLayout.setContentsMargins(0, 0, 0, 0) self.horizontalLayout.setObjectName("horizontalLayout") self.gridLayoutWidget = QtWidgets.QWidget(self.centralwidget) self.gridLayoutWidget.setGeometry(QtCore.QRect(20, 29, 721, 111)) self.gridLayoutWidget.setObjectName("gridLayoutWidget") self.gridLayout_3 = QtWidgets.QGridLayout(self.gridLayoutWidget) self.gridLayout_3.setContentsMargins(0, 0, 0, 0) self.gridLayout_3.setObjectName("gridLayout_3") self.gridLayout_3.setSpacing(20) self.widget = QtWidgets.QWidget(self.gridLayoutWidget_2) self.widget.setObjectName("widget") self.gridLayout_2.addWidget(self.widget, 0, 0, 1, 1) self.comboBox = QtWidgets.QComboBox(self.centralwidget) self.comboBox.setGeometry(QtCore.QRect(20, 650, 69, 22)) self.comboBox.setObjectName("com_ports") self.comboBox.addItems(self.com_ports) font = QtGui.QFont() font.setPointSize(12) font.setBold(True) font.setWeight(75) # Place & configure buttons self.pushButton_4 = QtWidgets.QPushButton(self.gridLayoutWidget_2) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.pushButton_4.sizePolicy().hasHeightForWidth()) self.pushButton_4.setSizePolicy(sizePolicy) self.pushButton_4.setObjectName("pushButton_4") self.gridLayout_2.addWidget(self.pushButton_4, 1, 0, 1, 1) self.pushButton_5 = QtWidgets.QPushButton(self.gridLayoutWidget_2) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.pushButton_5.sizePolicy().hasHeightForWidth()) self.pushButton_5.setSizePolicy(sizePolicy) self.pushButton_5.setObjectName("pushButton_5") self.gridLayout_2.addWidget(self.pushButton_5, 3, 0, 1, 1) self.pushButton_6 = QtWidgets.QPushButton(self.gridLayoutWidget_2) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.pushButton_6.sizePolicy().hasHeightForWidth()) self.pushButton_6.setSizePolicy(sizePolicy) self.pushButton_6.setObjectName("pushButton_6") self.gridLayout_2.addWidget(self.pushButton_6, 2, 0, 1, 1) # Define readout LEDs and place in GUI structure # Power ON light self.led_25 = LedIndicatorWidget.LedIndicator(color='blue') self.gridLayout_2.addWidget(self.led_25, 0, 0, 1, 1) self.led_25.setGeometry(QtCore.QRect(40, 0, 61, 31)) self.led_25.setObjectName("led_25") self.led_25.setChecked(False) # Fault 1 self.led_f1 = LedIndicatorWidget.LedIndicator(color='red') self.led_f1.setObjectName("led_fault_1") self.horizontalLayout.addWidget(self.led_f1) self.led_f1.setChecked(False) # Fault 2 self.led_f2 = LedIndicatorWidget.LedIndicator(color='red') self.led_f2.setObjectName("led_fault_2") self.horizontalLayout.addWidget(self.led_f2) self.led_f2.setChecked(False) # Fault 3 self.led_f3 = LedIndicatorWidget.LedIndicator(color='red') self.led_f3.setObjectName("led_fault_3") self.horizontalLayout.addWidget(self.led_f3) self.led_f3.setChecked(False) # Fault 4 self.led_f4 = LedIndicatorWidget.LedIndicator(color='red') self.led_f4.setObjectName("led_fault_4") self.horizontalLayout.addWidget(self.led_f4) self.led_f4.setChecked(False) # Fault 5 self.led_f5 = LedIndicatorWidget.LedIndicator(color='red') self.led_f5.setObjectName("led_fault_5") self.horizontalLayout.addWidget(self.led_f5) self.led_f5.setChecked(False) # Fault 6 self.led_f6 = LedIndicatorWidget.LedIndicator(color='red') self.led_f6.setObjectName("led_fault_6") self.horizontalLayout.addWidget(self.led_f6) self.led_f6.setChecked(False) # Fault 7 self.led_f7 = LedIndicatorWidget.LedIndicator(color='red') self.led_f7.setObjectName("led_fault_7") self.horizontalLayout.addWidget(self.led_f7) self.led_f7.setChecked(False) # Fault 8 self.led_f8 = LedIndicatorWidget.LedIndicator(color='red') self.led_f8.setObjectName("led_fault_8") self.horizontalLayout.addWidget(self.led_f8) self.led_f8.setChecked(False) # ON-1 self.led_on_1 = LedIndicatorWidget.LedIndicator(color='green') self.led_on_1.setObjectName("led_on_1") self.gridLayout_3.addWidget(self.led_on_1, 1, 0, 1, 1) self.led_on_1.setChecked(False) # OFF-1 self.led_off_1 = LedIndicatorWidget.LedIndicator(color='red') self.led_off_1.setObjectName("led_off_2") self.gridLayout_3.addWidget(self.led_off_1, 2, 0, 1, 1) self.led_off_1.setChecked(False) # ON-2 self.led_on_2 = LedIndicatorWidget.LedIndicator(color='green') self.led_on_2.setObjectName("led_on_2") self.gridLayout_3.addWidget(self.led_on_2, 1, 1, 1, 1) self.led_on_2.setChecked(False) # OFF-2 self.led_off_2 = LedIndicatorWidget.LedIndicator(color='red') self.led_off_2.setObjectName("led_off_2") self.gridLayout_3.addWidget(self.led_off_2, 2, 1, 1, 1) self.led_off_2.setChecked(False) # ON-3 self.led_on_3 = LedIndicatorWidget.LedIndicator(color='green') self.led_on_3.setObjectName("led_on_3") self.gridLayout_3.addWidget(self.led_on_3, 1, 2, 1, 1) self.led_on_3.setChecked(False) # OFF-3 self.led_off_3 = LedIndicatorWidget.LedIndicator(color='red') self.led_off_3.setObjectName("led_off_3") self.gridLayout_3.addWidget(self.led_off_3, 2, 2, 1, 1) self.led_off_3.setChecked(False) # ON-4 self.led_on_4 = LedIndicatorWidget.LedIndicator(color='green') self.led_on_4.setObjectName("led_on_4") self.gridLayout_3.addWidget(self.led_on_4, 1, 3, 1, 1) self.led_on_4.setChecked(False) # OFF-4 self.led_off_4 = LedIndicatorWidget.LedIndicator(color='red') self.led_off_4.setObjectName("led_off_4") self.gridLayout_3.addWidget(self.led_off_4, 2, 3, 1, 1) self.led_off_4.setChecked(False) # ON-5 self.led_on_5 = LedIndicatorWidget.LedIndicator(color='green') self.led_on_5.setObjectName("led_on_5") self.gridLayout_3.addWidget(self.led_on_5, 1, 4, 1, 1) self.led_on_5.setChecked(False) # OFF-5 self.led_off_5 = LedIndicatorWidget.LedIndicator(color='red') self.led_off_5.setObjectName("led_off_5") self.gridLayout_3.addWidget(self.led_off_5, 2, 4, 1, 1) self.led_off_5.setChecked(False) # ON-6 self.led_on_6 = LedIndicatorWidget.LedIndicator(color='green') self.led_on_6.setObjectName("led_on_6") self.gridLayout_3.addWidget(self.led_on_6, 1, 5, 1, 1) self.led_on_6.setChecked(False) # OFF-6 self.led_off_6 = LedIndicatorWidget.LedIndicator(color='red') self.led_off_6.setObjectName("led_off_6") self.gridLayout_3.addWidget(self.led_off_6, 2, 5, 1, 1) self.led_off_6.setChecked(False) # ON-7 self.led_on_7 = LedIndicatorWidget.LedIndicator(color='green') self.led_on_7.setObjectName("led_on_7") self.gridLayout_3.addWidget(self.led_on_7, 1, 6, 1, 1) self.led_on_7.setChecked(False) # OFF-7 self.led_off_7 = LedIndicatorWidget.LedIndicator(color='red') self.led_off_7.setObjectName("led_off_7") self.gridLayout_3.addWidget(self.led_off_7, 2, 6, 1, 1) self.led_off_7.setChecked(False) # ON-8 self.led_on_8 = LedIndicatorWidget.LedIndicator(color='green') self.led_on_8.setObjectName("led_on_8") self.gridLayout_3.addWidget(self.led_on_8, 1, 7, 1, 1) self.led_on_8.setChecked(False) # OFF-8 self.led_off_8 = LedIndicatorWidget.LedIndicator(color='red') self.led_off_8.setObjectName("led_off_8") self.gridLayout_3.addWidget(self.led_off_8, 2, 7, 1, 1) self.led_off_8.setChecked(False) # Define labels & place self.label_6 = QtWidgets.QLabel(self.gridLayoutWidget) self.label_6.setAlignment(QtCore.Qt.AlignCenter) self.label_6.setObjectName("label_6") self.gridLayout_3.addWidget(self.label_6, 0, 5, 1, 1) self.label = QtWidgets.QLabel(self.gridLayoutWidget) self.label.setAlignment(QtCore.Qt.AlignCenter) self.label.setObjectName("label") self.gridLayout_3.addWidget(self.label, 0, 0, 1, 1) self.label_2 = QtWidgets.QLabel(self.gridLayoutWidget) self.label_2.setAlignment(QtCore.Qt.AlignCenter) self.label_2.setObjectName("label_2") self.gridLayout_3.addWidget(self.label_2, 0, 1, 1, 1) self.label_3 = QtWidgets.QLabel(self.gridLayoutWidget) self.label_3.setAlignment(QtCore.Qt.AlignCenter) self.label_3.setObjectName("label_3") self.gridLayout_3.addWidget(self.label_3, 0, 2, 1, 1) self.label_4 = QtWidgets.QLabel(self.gridLayoutWidget) self.label_4.setAlignment(QtCore.Qt.AlignCenter) self.label_4.setObjectName("label_4") self.gridLayout_3.addWidget(self.label_4, 0, 3, 1, 1) self.label_5 = QtWidgets.QLabel(self.gridLayoutWidget) self.label_5.setAlignment(QtCore.Qt.AlignCenter) self.label_5.setObjectName("label_5") self.gridLayout_3.addWidget(self.label_5, 0, 4, 1, 1) self.label_7 = QtWidgets.QLabel(self.gridLayoutWidget) self.label_7.setAlignment(QtCore.Qt.AlignCenter) self.label_7.setObjectName("label_7") self.gridLayout_3.addWidget(self.label_7, 0, 6, 1, 1) self.label_8 = QtWidgets.QLabel(self.gridLayoutWidget) self.label_8.setAlignment(QtCore.Qt.AlignCenter) self.label_8.setObjectName("label_8") self.gridLayout_3.addWidget(self.label_8, 0, 7, 1, 1) self.label_9.setFont(font) self.label_9.setObjectName("label_9") MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 933, 21)) self.menubar.setObjectName("menubar") self.menuOctolok = QtWidgets.QMenu(self.menubar) self.menuOctolok.setObjectName("menuOctolok") MainWindow.setMenuBar(self.menubar) self.statusbar = QtWidgets.QStatusBar(MainWindow) self.statusbar.setObjectName("statusbar") MainWindow.setStatusBar(self.statusbar) self.menubar.addAction(self.menuOctolok.menuAction()) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) # Define function dispatcher to set state of of LED self.dispatcher = { 'FAULT': [ self.led_f1.setChecked, self.led_f2.setChecked, self.led_f3.setChecked, self.led_f4.setChecked, self.led_f5.setChecked, self.led_f6.setChecked, self.led_f7.setChecked, self.led_f8.setChecked ], 'ON-OFF': [[self.led_on_1.setChecked, self.led_off_1.setChecked], [self.led_on_2.setChecked, self.led_off_2.setChecked], [self.led_on_3.setChecked, self.led_off_3.setChecked], [self.led_on_4.setChecked, self.led_off_4.setChecked], [self.led_on_5.setChecked, self.led_off_5.setChecked], [self.led_on_6.setChecked, self.led_off_6.setChecked], [self.led_on_7.setChecked, self.led_off_7.setChecked], [self.led_on_8.setChecked, self.led_off_8.setChecked]] } # Button hooks self.pushButton.clicked.connect(self.connect) self.pushButton_2.clicked.connect(self.disconnect) self.pushButton_4.clicked.connect(self.get_status) self.pushButton_6.clicked.connect(lambda: self.decode('DISABLE ')) self.pushButton_7.clicked.connect(self.close) def retranslateUi(self, MainWindow): ''' Redefines label and button names for front-end usages. :param MainWindow: QtWidgets.QMainWindow() :return: None ''' _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) self.pushButton.setText(_translate("MainWindow", "Connect")) self.pushButton_2.setText(_translate("MainWindow", "Disconnect")) self.pushButton_4.setText(_translate("MainWindow", "Status")) self.pushButton_5.setText(_translate("MainWindow", "Reset")) self.pushButton_6.setText(_translate("MainWindow", "Disable")) self.pushButton_7.setText(_translate("MainWindow", "Close")) self.label_5.setText(_translate("MainWindow", "5")) self.label_6.setText(_translate("MainWindow", "6")) self.label.setText(_translate("MainWindow", "1")) self.label_3.setText(_translate("MainWindow", "3")) self.label_7.setText(_translate("MainWindow", "7")) self.label_2.setText(_translate("MainWindow", "2")) self.label_8.setText(_translate("MainWindow", "8")) self.label_4.setText(_translate("MainWindow", "4")) self.label_9.setText(_translate("MainWindow", "Fault")) self.menuOctolok.setTitle(_translate("MainWindow", "Octolok")) # Start thread self.threadpool = QThreadPool() print("Multithreading with maximum %d threads" % self.threadpool.maxThreadCount()) def connect(self): ''' Create instance of serial port handler, SerialPort(). Passes combo boxx selection containing current serial port. :return: None ''' self.print_output( "Initializing serial connection on port: {port}".format( port=self.comboBox.currentText())) self.serial = SerialPort(self.comboBox.currentText()) self.connection_open = True self.listen() def close(self): ''' Ends MainWindow session. :return: None ''' self.threadpool.waitForDone(2000) self.serial.disconnect() MainWindow.close() def disconnect(self): ''' Waits for completion of current thread in threadpool and closes serial port connection. If current connection doesn't exist, function passes and does nothing. :return: None ''' if self.connection_open: try: self.print_output( "Disconnecting serial connection on port: {port}".format( port=self.comboBox.currentText())) self.threadpool.waitForDone(2000) self.threadpool.clear() self.serial.disconnect() self.led_25.setChecked(False) except Exception as ex: pass else: self.print_output('Connection not active. Please connect.') def print_output(self, s): ''' Wrapper function to print to front-end text box. :param s: string-type to send to text box. :return: None ''' self.cursor.setPosition(0) self.textBox.setTextCursor(self.cursor) self.textBox.insertPlainText('[{ts}] {msg}\n'.format(ts=time.ctime( time.time())[11:-5], msg=s)) def decode(self, message): ''' Parses and decodes incoming communication from hardware device. :param reply: string-type reply or interrupt message from hardware. :return: None ''' self.print_output('Decoding response ...') try: type, reply = message.split(' ') reply = reply.strip() self.status = reply[::2] self.state = reply[1::2] self.status = [ bool(int(self.status[i])) for i in range(len(self.status)) ] self.state = [ bool(int(self.state[i])) for i in range(len(self.state)) ] if type == 'STATUS': for (on, off), i in zip(self.dispatcher['ON-OFF'], range(len(self.dispatcher['ON-OFF']))): if not self.status[i]: on(False) off(False) else: on(self.state[i]) off(not self.state[i]) elif type == 'DISABLE': for (on, off), i in zip(self.dispatcher['ON-OFF'], range(len(self.dispatcher['ON-OFF']))): on(False) off(False) elif type == 'FAULT': self.fault = [ bool(int(self.reply[i])) for i in range(len(self.reply)) ] for fault, i in zip(self.dispatcher['FAULT'], range(len(self.dispatcher['FAULT']))): fault(self.fault[i]) else: pass except AttributeError as ex: pass def data_received(self, data): print('Data at COM port:') self.print_output(data) def listen(self): ''' Spanwns polling thread to look for interrupt communication form hardware device at COM port. Function has secondary priority to serial port resource. :return: None ''' if self.connection_open: try: self.led_25.setChecked(True) # Pass the function to execute worker = WorkerThreading.Worker(self.serial.listen) worker.signals.result.connect(self.decode) # worker.signals.finished.connect(self.thread_complete) worker.signals.progress.connect(self.data_received) # Execute self.threadpool.start(worker, priority=3) except Exception as ex: self.print_output( 'Error listening on port: {0}. Check log for more details.' .format(ex)) else: self.print_output('Connection not active. Please connect.') return def get_status(self): ''' Spawns thread for sending command to hardware. Sends STATUS? command to hardware ans then waits for reply. Reply is sent to decode fucntion. Has top priority to serial port resource. :param cmd: :return: ''' if self.connection_open: try: # Pass the function to execute worker = WorkerThreading.Worker(self.serial.send, command='STATUS?') worker.signals.result.connect(self.decode) # worker.signals.finished.connect(self.thread_complete) # Execute self.threadpool.start(worker, priority=4) except Exception as ex: self.print_output( 'Error reading on port: {0}. Check log for more details.'. format(ex)) else: self.print_output('Connection not active. Please connect.') return
class UI(QMainWindow): def __init__(self): super(UI, self).__init__() uic.loadUi("recorder.ui", self) # find the widgets in the xml file self.timer_label = self.findChild(QLCDNumber, "lcdNumber") self.record_button = self.findChild(QPushButton, "recordpushButton") self.stop_button = self.findChild(QPushButton, "stoppushButton") self.save_button = self.findChild(QPushButton, "savepushButton") self.fps_spinbox = self.findChild(QDoubleSpinBox, "fpsdoubleSpinBox") self.index_spinbox = self.findChild(QSpinBox, "indexspinBox") self.record_button.clicked.connect(self.clickedrecordBtn) self.stop_button.clicked.connect(self.clickedstopBtn) self.save_button.clicked.connect(self.clickedsaveBtn) self.fps_spinbox.valueChanged.connect(self.valuechangefps) self.index_spinbox.valueChanged.connect(self.valuechangeindex) self.record_button.setEnabled(True) self.stop_button.setEnabled(False) self.save_button.setEnabled(False) # temporary output video name and type self.voutput_name = "video.mp4" # temporary output audio name and type self.aoutput_name = "audio.wav" self.fps = float(self.fps_spinbox.value()) self.device_index = int(self.index_spinbox.value()) self.threadpool = QThreadPool() self.components() self.audio_device_show() self.show() def audio_device_show(self): p = pyaudio.PyAudio() print("Number of device: ", p.get_device_count()) for i in range(p.get_device_count()): device_info = p.get_device_info_by_index(i) print("Index: {} has device name: {}".format( device_info["index"], device_info["name"])) def components(self): self.count = 0 self.flag = False self.timer_label.display(self.count) timer = QTimer(self) timer.timeout.connect(self.showTime) timer.start(100) # every 0.1 s def showTime(self): if self.flag: self.count += 1 # t = self.count / 10 t = time_converter(self.count) self.timer_label.display(t) def clickedrecordBtn(self): self.flag = True self.setWindowOpacity(0.5) # make window transparent during recording self.record_button.setEnabled(False) # turn off record button self.save_button.setEnabled(False) # turn off save button self.count = 0 # make a new record - start video and audio recording self.threadpool.clear() # create screen recorder object self.vrec = ScreenRecorder_QT(output_name=self.voutput_name, fps=self.fps) # create audio recorder object self.arec = AudioRecorder_QT( output_name=self.aoutput_name, input_device_index=self.device_index, fps=self.fps, ) self.threadpool.start(self.vrec) self.threadpool.start(self.arec) self.stop_button.setEnabled(True) # turn on stop button def clickedstopBtn(self): self.flag = False self.setWindowOpacity(1.0) # make window visible again after recording # stop video and audio recording self.arec.quit_flag = True self.vrec.quit_flag = True self.threadpool.clear() self.record_button.setEnabled(True) # turn on record button self.stop_button.setEnabled(False) # turn off stop button self.save_button.setEnabled(True) # turn on save button def clickedsaveBtn(self): self.flag = False self.setWindowOpacity(1.0) # make window visible again after recording self.record_button.setEnabled(False) # turn off record button self.stop_button.setEnabled(False) # turn off stop button self.save_button.setEnabled(False) # turn off save button self.count = 0 self.timer_label.display(self.count) # save to intended directory and input file name dialog = QtWidgets.QFileDialog() pathsave_custom = dialog.getSaveFileName( None, "Select destination folder and file name", "./", "mp4 files (*.mp4)")[0] # re-encode video according to measured video length if Path(self.voutput_name).is_file(): encode_video(self.vrec.fps, self.vrec.recorded_fps, self.voutput_name) # merge video and audio if len(self.arec.audio_frames) != 0 and Path( self.aoutput_name).is_file() and Path( self.voutput_name).is_file(): timing_adjustment = timing_adjust(self.vrec, self.arec) insert_silent(timing_adjustment, self.aoutput_name) print("Merge video and audio......") video_audio_merge(pathsave_custom, self.aoutput_name, self.voutput_name) elif Path(self.voutput_name).is_file(): print("No sound recorded. Transfer video......") video_convert(pathsave_custom, self.voutput_name) else: print("No sound and no video recorded.") self.record_button.setEnabled(True) # turn on record button self.stop_button.setEnabled(False) # turn off stop button self.save_button.setEnabled(False) # turn off save button def valuechangefps(self): self.fps = float(self.fps_spinbox.value()) def valuechangeindex(self): self.device_index = int(self.index_spinbox.value())
class GestureDraw(QMainWindow): populateGallery = pyqtSignal() closedWindow = pyqtSignal(object) key_pressed = pyqtSignal(object) def __init__(self, parent): super(GestureDraw, self).__init__() self.setWindowTitle('Gesture Draw') self.parent = parent self.configure_gui() self.create_widgets() self.create_menu() self.order[0].actions()[-1].trigger() self.show() def configure_gui(self): self.stack = QStackedWidget(self) self.setCentralWidget(self.stack) resolution = Qapp.desktop().screenGeometry() width, height = resolution.width(), resolution.height() self.setGeometry(0, 0, width // 2, height) def create_widgets(self): self.windows = set() self.mysql = CONNECT(self) self.threadpool = QThreadPool() self.gallery = Gallery(self) self.preview = Preview(self) self.timer = Timer(self.preview, self) self.stack.addWidget(self.gallery) self.stack.addWidget(self.preview) self.statusbar = QStatusBar(self) self.setStatusBar(self.statusbar) self.statusbar.setFixedHeight(30) self.mysql.finishedTransaction.connect(self.select_records) self.mysql.finishedSelect.connect(self.gallery.clearSelection) self.mysql.finishedSelect.connect(self.gallery.update) self.mysql.finishedSelect.connect(self.update_statusbar) self.gallery.selection.connect(self.update_statusbar) self.gallery.find_artist.connect(self.find_by_artist) self.gallery.setContentsMargins(5, 0, 5, 0) for action in self.gallery.menu.actions(): if action.text() in ['Delete', 'Properties']: self.gallery.menu.removeAction(action) self.preview.label.setStyleSheet(f'background: black') def create_menu(self): self.menubar = self.menuBar() self.toolbar = self.addToolBar('Ribbon') self.ribbon = Ribbon(self) self.toolbar.addWidget(self.ribbon) self.menubar.triggered.connect(self.menuPressEvent) self.toolbar.actionTriggered.connect(self.menuPressEvent) self.ribbon.selection_mode.connect(self.setSelectionMode) self.ribbon.multi.click() self.ribbon.tags.setFocus() # File file = self.menubar.addMenu('File') file.addAction('Copy Images to') self.gesture_menu = create_submenu_(self, 'Gesture Draw', GESTURE.keys(), check=False)[0] file.addMenu(self.gesture_menu) file.addSeparator() file.addAction('Exit', self.close, shortcut='CTRL+W') # database database = self.menubar.addMenu('Database') database.addAction('Reconnect') database.addAction('Current statement') database.addAction('Update Autocomplete') database.addAction('Remove Redundancies') # View view = self.menubar.addMenu('View') # Help help = self.menubar.addMenu('Help') @pyqtSlot() def select_records(self): worker = Worker(self.mysql.execute, self.ribbon.update_query(1, 1000)) self.threadpool.start(worker) def start_session(self, gallery, time): if gallery and time: self.menubar.hide() self.toolbar.hide() self.statusbar.hide() if ':' in time: min, sec = time.split(':') time = (int(min) * 60) + int(sec) else: time = int(time) self.stack.setCurrentIndex(1) self.timer.start(gallery, time) else: QMessageBox.information(self, '', 'You are either missing images or a time', QMessageBox.Ok) def update_statusbar(self): total = self.gallery.total() select = len(self.gallery.selectedIndexes()) total = (f'{total} image' if (total == 1) else f'{total} images') if select: select = (f'{select} image selected' if (select == 1) else f'{select} images selected') else: select = '' self.statusbar.showMessage(f' {total} {select}') def find_by_artist(self, index): artist = index.data(Qt.UserRole)[1] if artist: self.ribbon.setText(' OR '.join(artist.split())) else: QMessageBox.information(self, 'Find by artist', 'This image has no artist') def setSelectionMode(self, event): if event: self.gallery.setSelectionMode(QAbstractItemView.MultiSelection) else: self.gallery.setSelectionMode(QAbstractItemView.ExtendedSelection) self.gallery.clearSelection() def menuPressEvent(self, event=None): action = event.text() # Files if action == 'Copy Images to': copy_to(self, self.gallery.selectedIndexes()) elif action in GESTURE.keys(): if action == 'Custom Time': time, ok = QInputDialog.getText(self, "Dialog", "Enter time:") if ok: gallery = self.gallery.selectedIndexes() self.start_session(gallery, time) else: gallery = self.gallery.selectedIndexes() self.start_session(gallery, GESTURE[action]) elif action == 'Exit': self.close() # Database elif action == 'Reconnect': self.mysql = CONNECT(self) self.threadpool = QThreadPool() elif action == 'Current Statement': QMessageBox.information(self, 'Current Statement', self.ribbon.query) elif action == 'Update Autocomplete': worker = Worker(update_autocomplete) self.threadpool.start(worker) self.ribbon.tags.setCompleter( Completer(open(AUTOCOMPLETE).read().split())) elif action == 'Remove Redundancies': worker = Worker(remove_redundancies) self.threadpool.start(worker) def keyPressEvent(self, event): key_press = event.key() if key_press == Qt.Key_Space: self.timer.pause() elif key_press in (Qt.Key_Left, Qt.Key_Right): pass elif key_press == Qt.Key_Escape: if self.stack.currentIndex(): self.timer.pause() self.menubar.show() self.toolbar.show() self.statusbar.show() self.statusbar.showMessage('') self.stack.setCurrentIndex(0) self.select_records() else: self.close() else: self.key_pressed.emit(event) def mousePressEvent(self, event): if event.button() == Qt.MouseButton.LeftButton: self.timer.pause() def closeEvent(self, event): self.threadpool.clear() for window in self.windows: window.close() self.mysql.close() self.closedWindow.emit(self)
class main_program(QObject): def __init__(self): super(main_program, self).__init__() self.video_source = None self.ui = Ui_MainWindow() self.threadpool = QThreadPool() self.threadpool.setMaxThreadCount(8) self.database = Database() self.combo_list = [ "Görüntü kaynağını seçiniz...", "Webcam", "IP Kamera", "IP Kamera 2" ] self.is_signedin = False def button_connections(self): # Activate in main. self.ui.start_stop_button.clicked.connect(self.Start) # self.ui.stop_button.clicked.connect(self.Stop) self.ui.to_taskbar_button.clicked.connect(MainWindow.showMinimized) self.ui.quit_button.clicked.connect(sys.exit) self.ui.btn_page_1.clicked.connect( lambda: self.ui.stackedWidget.setCurrentWidget(self.ui.page_1)) self.ui.btn_page_2.clicked.connect( lambda: self.ui.stackedWidget.setCurrentWidget(self.ui.page_2)) self.ui.media_source_combobox.addItems(self.combo_list) self.ui.media_source_combobox.activated.connect(self.ComboSelected) self.ui.sign_out_button.clicked.connect(self.sign_out_clicked) self.ui.sign_in_button.clicked.connect(self.login_func) self.ui.reload_table_button.clicked.connect(self.load_report_table) @pyqtSlot(QImage) def setImage(self, image): self.ui.image_frame.setPixmap(QPixmap.fromImage(image)) if self.detection.stopped: self.ui.image_frame.setPixmap( QtGui.QPixmap(":/placeholders/Resources/placeholder2.png")) @pyqtSlot(str) def setInfo(self, statement): self.ui.out_info_box.setText(statement) @pyqtSlot(str) def setTitleBox(self, statement): self.ui.info_title_box.setText(statement) def Start(self): if self.is_signedin: self.ui.out_info_box.setText("") if self.check_video_source(): self.ui.image_frame.setPixmap( QtGui.QPixmap("Resources/please_wait.png")) self.detection = Detection() self.detection.video_source = self.video_source # Connect signals and slots self.detection.signals.changeButton.connect( self.change_start_context) self.detection.signals.changePixmap.connect(self.setImage) self.detection.signals.changeTextBox.connect(self.setInfo) self.detection.signals.changeTitleBox.connect(self.setTitleBox) self.threadpool.start(self.detection) self.change_start_context("stop_button") else: self.ui.out_info_box.setText("Video kaynağınızı kontrol edin.") else: self.ui.out_info_box.setText("Lütfen önce giriş yapınız.") @pyqtSlot(str) def change_start_context(self, mode): if mode == "start_button": self.ui.start_stop_button.clicked.disconnect() self.ui.start_stop_button.clicked.connect(self.Start) self.ui.start_stop_button.setStyleSheet( "QPushButton {\n" "color: rgb(255, 255, 255);\n" "border: 0px solid;\n" "background-color: #667BC4;\n" "padding:0.5em;\n" "font-weight:bold;\n" "font-size:12px;\n" "}\n" "QPushButton:hover {\n" " background-color: #7289DA;\n" "}") self.ui.start_stop_button.setText("Başlat") elif mode == "stop_button": self.ui.start_stop_button.clicked.disconnect() self.ui.start_stop_button.clicked.connect(self.Stop) self.ui.start_stop_button.setStyleSheet( "QPushButton {\n" "color: rgb(255, 255, 255);\n" "border: 0px solid;\n" "background-color: #ff2115;\n" "padding:0.5em;\n" "font-weight:bold;\n" "font-size:12px;\n" "}\n" "QPushButton:hover {\n" "background-color: #ff392e;\n" "}") self.ui.start_stop_button.setText("Durdur") def check_video_source(self): if self.video_source is None: return False else: _, frame = cv2.VideoCapture(self.video_source).read() if frame is not None: return True else: return False # TODO: When loop ends, button context should change. def Stop(self): try: self.detection.stopped = True self.threadpool.clear() self.threadpool.releaseThread() # print("Active thread count last (stop): {}".format(self.threadpool.activeThreadCount())) # self.change_start_context("start_button") except AttributeError: print("Detection is not initialize yet.") def ComboSelected(self): media_source_str = self.ui.media_source_combobox.currentText() current_index = self.ui.media_source_combobox.currentIndex() if current_index == 0: self.video_source = None if current_index == 1: self.video_source = 0 if current_index == 2: self.video_source = 'videos/toprakli_fit_buyuk.mp4' if current_index == 3: self.video_source = "videos/inek_field.mp4" #################################################### # SIGN IN - SIGN OUT # #################################################### def starting_page(self): """ This function answer this question: 'Did user sign in before or not?' """ is_matching, file_path = self.database.get_data_n_check() if is_matching: self.change_profile_button_context(1) else: try: os.remove(file_path) self.ui.info_box.setText( "Güvenlikle ilgili bir sorun meydana geldi.\nYeniden giriş yapın." ) except FileNotFoundError: print("Usr.md file doesn't exist.") self.change_profile_button_context(0) def change_profile_button_context(self, status): # 0 is for NOT signed in, 1 is for signed in. icon = QtGui.QIcon() if status == 0: self.ui.btn_page_4.disconnect() self.ui.btn_page_4.clicked.connect( lambda: self.ui.stackedWidget.setCurrentWidget(self.ui. sign_in_page)) icon.addPixmap( QtGui.QPixmap( ":/icons/Resources/icons/32px/user_alternative.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.ui.btn_page_4.setIcon(icon) self.is_signedin = False elif status == 1: self.ui.btn_page_4.disconnect() self.ui.btn_page_4.clicked.connect( lambda: self.ui.stackedWidget.setCurrentWidget(self.ui. profile_page)) icon.addPixmap( QtGui.QPixmap(":/icons/Resources/icons/32px/user_active.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.ui.btn_page_4.setIcon(icon) self.is_signedin = True # cu stands for current user. cu_email, cu_name, cu_surname = self.database.get_current_user_info( ) self.ui.current_name_surname.setText("{} {}".format( cu_name, cu_surname)) self.ui.current_email.setText("{}".format(cu_email)) def login_func(self): self.ui.profile_info_box.setAlignment(QtCore.Qt.AlignCenter) if self.ui.email.text() == "" or self.ui.password.text() == "": self.ui.info_box.setStyleSheet("color:#ff5048;font-weight: 700;") self.ui.info_box.setText("Boş alanları doldurunuz.") else: encrypted_pass = self.database.encrpt_password( self.ui.password.text()) email = self.ui.email.text() try: self.database.cursor.execute( "select name, email, password, userID from User WHERE User.email = %s and User.password=%s", (email, encrypted_pass)) x = self.database.cursor.next() CURRENT_USER_NAME = x[0] CURRENT_USER_EMAIL = x[1] CURRENT_USER_ID = x[3] # Save user information to local. self.save_current_user_local(CURRENT_USER_EMAIL, CURRENT_USER_ID) # Change the context and icon of profile button self.change_profile_button_context(1) # Redirecting to page 2. self.ui.stackedWidget.setCurrentWidget(self.ui.profile_page) # Complete message. self.ui.profile_info_box.setText(f"Giriş başarılı.") except StopIteration: self.ui.info_box.setStyleSheet( "color:#ff5048; font-weight: 700;") self.ui.info_box.setText("E-postanız veya parolanız yanlış.") def save_current_user_local(self, email, uid): file_exist_message = "Old user. [File exist]" # Get OS of user. platform_name = platform.system() if platform_name == "Windows": save_dir = os.getenv('APPDATA') save_dir += '\\Provactus\\' file_path = save_dir + '\\usr.md' elif platform_name == "Linux": save_dir = '/var/Provactus' file_path = '/var/Provactus/usr.md' # Trying to create file. try: os.mkdir(save_dir) except FileExistsError: print(file_exist_message) # Local registry for following usages. with open(file_path, 'w+') as file: file.write(f"{uid}\n{email}\n") def sign_out_clicked(self): # Get OS of user. platform_name = platform.system() if platform_name == "Windows": save_dir = os.getenv('APPDATA') save_dir += '\\Provactus\\' file_path = save_dir + '\\Provactus\\usr.md' elif platform_name == "Linux": file_path = "/var/Provactus/usr.md" os.remove(file_path) self.change_profile_button_context(0) # Redirecting to page 2. self.ui.stackedWidget.setCurrentWidget(self.ui.sign_in_page) self.ui.info_box.setText("") #################################################### # Report # #################################################### def load_report_table(self): if self.is_signedin: t = datetime.now() current_time = t.strftime("%d/%m/%y %H:%M:%S.%f")[:-4] self.report_page_controls(True) self.ui.report_info_box.setText( "Son güncellenme tarihi: {}".format(current_time)) # To update the information, we have to re-initialize the db. self.database = Database() (report_id, date, elapsed, total_left, total_right, user_id, enter_position) = self.database.get_reports( self.database.get_id_local()) var_collection = [date, elapsed, total_left, total_right] var_collection_rev = [date, elapsed, total_right, total_right] # reverse vars for var in var_collection: var.reverse() # listing if len(report_id) != 0: self.ui.report_table.setRowCount(len(report_id)) for col_n in range(4): for row_n in range(len(report_id)): if enter_position[row_n] == "right": self.ui.report_table.setItem( row_n, col_n, QtWidgets.QTableWidgetItem( str(var_collection[col_n][row_n]))) elif enter_position[row_n] == "left": self.ui.report_table.setItem( row_n, col_n, QtWidgets.QTableWidgetItem( str(var_collection_rev[col_n][row_n]))) else: self.report_page_controls(False) self.ui.report_info_box.setText("Henüz rapor oluşturmadınız.") else: self.report_page_controls(False) self.ui.report_info_box.setText("Önce giriş yapınız.") def report_page_controls(self, is_okay): self.ui.report_info_box.setAlignment(QtCore.Qt.AlignCenter) if is_okay is True: self.ui.report_info_box.setStyleSheet("color: #FFFFFF;\n" "font-weight: 700;\n" "font-size: 14px;\n" "margin:2em;\n" "") self.ui.report_table.show() self.ui.report_info_box.setText("") else: self.ui.report_info_box.setStyleSheet("color: #ff5048;\n" "font-weight: 700;\n" "font-size: 14px;\n" "margin:2em;\n" "") self.ui.report_table.close() self.ui.report_info_box.show()
class Cola2Status(QObject): reconnect_signal = pyqtSignal() cola2_connected = pyqtSignal(bool) update_data_signal = pyqtSignal() def __init__(self, config, vehicleinfo, label, indicator): super(Cola2Status, self).__init__() self.config = config self.vehicleinfo = vehicleinfo self.timer = QTimer() self.timer.timeout.connect(self.update_data) self.subscribed = False self.total_time_topic = None self.t_time = 0 self.cola2_label = label self.cola2_indicator = indicator self.cola2_label.setStyleSheet('font:italic; color:red') self.cola2_indicator.setPixmap(QPixmap(":/resources/red_led.svg")) self.reconnect_signal.connect(self.start_cola2_thread) self.update_data_signal.connect(self.start_timer) self.iswatchdog = False self.t_time_text = None vd_handler = VehicleDataHandler(self.config) # get vehicle data topics xml_vehicle_data_topics = vd_handler.read_topics() # back compatibility for topic in xml_vehicle_data_topics: if topic.get('id') == "total time": self.t_time_text = topic.text self.iswatchdog = False elif (topic.get('id') == "watchdog"): self.t_time_text = topic.text self.iswatchdog = True self.threadpool = QThreadPool() self.start_cola2_thread() def start_cola2_thread(self): # self.t = threading.Thread(target=self.update_cola2_status) # self.t.daemon = True # self.t.start() worker = Worker( self.update_cola2_status ) # Any other args, kwargs are passed to the run function self.threadpool.start(worker) def update_cola2_status(self): try: self.subscribed = True self.total_time_topic = SubscribeToTopic( self.vehicleinfo.get_vehicle_ip(), 9091, self.vehicleinfo.get_vehicle_namespace() + self.t_time_text) self.cola2_connected.emit(True) self.update_data_signal.emit() except OSError as oe: logger.error("Disconnecting cola2 status {}".format(oe)) self.disconnect_cola2status() except: logger.error("Disconnecting cola2 status") self.disconnect_cola2status() if not self.subscribed: time.sleep(5) # self.update_cola2_status() self.reconnect_signal.emit() def start_timer(self): self.timer.start(1000) def update_data(self): try: if self.subscribed: if self.total_time_topic: data = self.total_time_topic.get_data() if data and data['valid_data'] == 'new_data': if self.iswatchdog: if self.t_time != data['data']: self.t_time = data['data'] self.cola2_label.setStyleSheet( 'font:italic; color:green') self.cola2_indicator.setPixmap( QPixmap(":/resources/green_led.svg")) else: self.cola2_label.setStyleSheet( 'font:italic; color:red') self.cola2_indicator.setPixmap( QPixmap(":/resources/red_led.svg")) elif self.t_time != data['total_time']: self.t_time = data['total_time'] self.cola2_label.setStyleSheet( 'font:italic; color:green') self.cola2_indicator.setPixmap( QPixmap(":/resources/green_led.svg")) else: self.cola2_label.setStyleSheet( 'font:italic; color:red') self.cola2_indicator.setPixmap( QPixmap(":/resources/red_led.svg")) else: if data and data['valid_data'] == 'disconnected': self.disconnect_cola2status() self.reconnect_signal.emit() else: self.cola2_label.setStyleSheet( 'font:italic; color:red') self.cola2_indicator.setPixmap( QPixmap(":/resources/red_led.svg")) else: self.cola2_label.setStyleSheet('font:italic; color:red') self.cola2_indicator.setPixmap( QPixmap(":/resources/red_led.svg")) except: self.disconnect_cola2status() self.reconnect_signal.emit() def is_subscribed(self): return self.subscribed def disconnect_cola2status(self): self.cola2_connected.emit(False) self.subscribed = False self.cola2_label.setStyleSheet('font:italic; color:red') self.cola2_indicator.setPixmap(QPixmap(":/resources/red_led.svg")) if self.total_time_topic: # close subscription self.total_time_topic.close() self.timer.stop() self.total_time_topic = None self.threadpool.clear()
class ConnectionClient(QObject): connection_failure = pyqtSignal() connection_ok = pyqtSignal() reconnect_signal = pyqtSignal() def __init__( self, ip, port, ): super(ConnectionClient, self).__init__() self.ip = ip self.port = port self.sock = None self.threadpool = QThreadPool() self.timer = QTimer() self.timer.timeout.connect(self.watchdog) self.reconnect_signal.connect(self.start_cc_thread) self.connection_ok.connect(self.start_watchdog_timer) # self.rt = RepeatedTimer(5000, self.watchdog) self.connected = False @property def ip(self): return self.__ip @ip.setter def ip(self, ip): self.__ip = ip @property def port(self): return self.__port @port.setter def port(self, port): self.__port = port def start_cc_thread(self): # self.t = threading.Thread(target=self.do_connection) # self.t.daemon = True # self.t.start() worker = Worker( self.do_connection ) # Any other args, kwargs are passed to the run function self.threadpool.start(worker) def do_connection(self): try: # Create a TCP/IP socket self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Set timeout self.sock.settimeout(3.0) server_address = (self.__ip, int(self.__port)) self.sock.connect(server_address) self.connected = True self.connection_ok.emit() logger.info("Connected") except socket.error as e: self.disconnect() self.connected = False self.connection_failure.emit() except Exception as e: self.disconnect() self.connected = False self.connection_failure.emit() if not self.connected: time.sleep(5) self.reconnect_signal.emit() def start_watchdog_timer(self): self.timer.start(5000) def watchdog(self): try: data = self.send("watchdog") if data != "watchdogack": self.disconnect() self.connection_failure.emit() self.reconnect_signal.emit() except socket.timeout: logger.error("timeout error") self.disconnect() self.connection_failure.emit() self.reconnect_signal.emit() except socket.error: logger.error("socket error occured") self.disconnect() self.connection_failure.emit() self.reconnect_signal.emit() except Exception as e: logger.error("%s fail to receive ack from the server" % e) self.disconnect() self.connection_failure.emit() self.reconnect_signal.emit() def send(self, message): self.sock.sendall(message.encode()) data = self.sock.recv(4096).decode() return data def disconnect(self): # if self.rt: # self.rt.stop() self.connected = False self.timer.stop() if self.sock: self.sock.close() self.threadpool.clear()
class WaitingWidget(QWidget): def __init__(self, parent, games=None): super().__init__() self.threadpool = QThreadPool() self.parent = parent self.resize(300, 200) self.games_to_play = games self.games_played = 0 self.label_played = QtWidgets.QLabel(self) self.label_played.setGeometry(QtCore.QRect(100, 80, 111, 16)) self.label_played.setObjectName("label_played") # self.label_gif = QtWidgets.QLabel(self) # self.label_gif.setGeometry(QtCore.QRect(105, 130, 100, 100)) # self.label_gif.setObjectName("label_gif") self.listWidget_played = QtWidgets.QListWidget(self) self.listWidget_played.setGeometry(QtCore.QRect(100, 100, 111, 21)) self.listWidget_played.setObjectName("listWidget_played") self.label_to_play = QtWidgets.QLabel(self) self.label_to_play.setGeometry(QtCore.QRect(100, 30, 111, 16)) self.label_to_play.setObjectName("label_to_play") self.listWidget_to_play = QtWidgets.QListWidget(self) self.listWidget_to_play.setGeometry(QtCore.QRect(100, 50, 111, 21)) self.listWidget_to_play.setObjectName("listWidget_to_play") self.btn_stop = QtWidgets.QPushButton(self) self.btn_stop.setGeometry(QtCore.QRect(105, 130, 93, 28)) self.btn_stop.setObjectName("btn_stop") self.btn_stop.clicked.connect(self.stop) self.btn_stop.hide() # self.gif = QMovie('View/loading.gif') # self.label_gif.setMovie(self.gif) # self.gif.start() self.retranslateUi() QtCore.QMetaObject.connectSlotsByName(self) def retranslateUi(self): _translate = QtCore.QCoreApplication.translate self.setWindowTitle(_translate("Form", "Waiting Window")) self.btn_stop.setText(_translate("Form", "Back")) self.label_played.setText(_translate("Form", "Games played")) self.label_to_play.setText(_translate("Form", "Games to play")) def populate_lists(self, games): self.listWidget_played.clear() self.listWidget_to_play.clear() self.games_played = games if self.games_played == int(self.games_to_play): self.show_back_button() self.listWidget_to_play.addItem(self.games_to_play) self.listWidget_played.addItem(str(self.games_played)) def show_back_button(self): self.btn_stop.show() def start_bot(self): loop = asyncio.get_event_loop() self.worker = Worker(showdown, self.populate_lists, loop) self.threadpool.start(self.worker) def setGames(self, games): self.games_to_play = games def stop(self): self.threadpool.clear() self.parent.back() self.close()
class Main_Window_class(QDialog): def __init__(self): super().__init__() self.initUI() def initUI(self): ### Hyperparameters ### self.nlabels = 6 self.checkboxes_lables = ['Клиппинг', 'Энвелоп'] self.btns_lables = ['Воспроизвести', 'Пауза', 'Остановить'] self.app_name = 'Эквалайзер' self.sld_min = -50 self.sld_max = 50 self.sld_def = 0 self.sld_interval = 10 self.sld_step = 1 ####################### ### Global variables ### self.path_to_pull = None self.nchannels = None # number of channels self.sampwidth = None # number of bytes per sample self.framerate = None # number of frames per second self.nframes = None # total number of frames self.comptype = None # compression type self.compname = None # compression type name self.elem_per_herz = None self.koeff = 1000 # коэффициент прореживания self.types = {} self.buffer_size = None self.buffer_cnt = 0 self.music_is_playing = False self.threadpool = QThreadPool() print(self.threadpool.maxThreadCount()) self.music_worker = None self.sld1_worker = None self.sld2_worker = None self.sld3_worker = None self.sld4_worker = None self.sld5_worker = None self.sld6_worker = None self.checkbox1_worker = None self.checkbox2_worker = None self.min_freq = 0 self.max_freq = None self.channels = [] self.spectrum = None self.spectrum_original = None self.spectrum_kliping = None self.spectrum_envelop = None self.channels_original = [] self.channels_kliping = [] self.channels_envelop = [] self.bands = [[], []] self.labels = [] ######################## ### Links ### # https://habrahabr.ru/post/113239/ # http://old.pynsk.ru/posts/2015/Nov/09/matematika-v-python-preobrazovanie-fure/ # http://www.7not.ru/articles/klip_cool.phtml # https://martinfitzpatrick.name/article/multithreading-pyqt-applications-with-qthreadpool/ # https://www.tutorialspoint.com/pyqt/pyqt_qlineedit_widget.htm # https://stackoverflow.com/questions/21887862/python-chorus-effect-and-meaning-of-audio-data # http://websound.ru/articles/sound-processing/effects.htm # http://www.auditionrich.com/lessons/kak-v-adobe-audition-ispolzovat-effekt-envelope-follower.html # https://works.doklad.ru/view/M_cHUqES_HE/2.html ############# self.path_to_pull = QFileDialog.getOpenFileName( self, 'Выберите .wav файл')[0] self.pull_music() self.create_bands() self.create_lables() self.create_LCD_numbers() self.create_sliders() self.create_checkboxes() self.create_buttons() self.create_graphics() self.create_interface() def pull_music(self): wav = wave.open(self.path_to_pull, mode='r') self.types = {1: np.int8, 2: np.int16, 4: np.int32} (self.nchannels, self.sampwidth, self.framerate, self.nframes, self.comptype, self.compname) = wav.getparams() self.max_freq = self.framerate // 2 self.buffer_size = self.framerate content = wav.readframes(self.nframes) samples = np.fromstring(content, dtype=self.types[self.sampwidth]) for i in range(self.nchannels): self.channels.append(samples[i::self.nchannels]) self.channels = np.array(self.channels) self.channels_original = self.channels.copy() self.checkbox1_worker = Worker(self.doing_kliping, self.channels) self.threadpool.start(self.checkbox1_worker) self.checkbox2_worker = Worker(self.doing_envelop, self.channels) self.threadpool.start(self.checkbox2_worker) self.spectrum = np.fft.rfft(self.channels_original) self.spectrum_original = self.spectrum.copy() pygame.mixer.pre_init(frequency=self.framerate, size=-self.sampwidth * 8, channels=self.nchannels) pygame.init() def create_bands(self): step = (self.max_freq - self.min_freq) // 2**self.nlabels self.bands[0].append(self.min_freq) self.bands[1].append(self.min_freq + step) for i in range(1, self.nlabels - 1): self.bands[0].append(self.bands[1][i - 1]) self.bands[1].append(self.bands[0][i] + 2**i * step) self.bands[0].append(self.bands[1][self.nlabels - 2]) self.bands[1].append(self.max_freq) for i in range(self.nlabels): self.labels.append( str(self.bands[0][i]) + ' - ' + str(self.bands[1][i])) def create_lables(self): self.label_1 = QLabel(self.labels[0], self) self.label_2 = QLabel(self.labels[1], self) self.label_3 = QLabel(self.labels[2], self) self.label_4 = QLabel(self.labels[3], self) self.label_5 = QLabel(self.labels[4], self) self.label_6 = QLabel(self.labels[5], self) def create_LCD_numbers(self): self.num_1 = QLCDNumber(self) self.num_2 = QLCDNumber(self) self.num_3 = QLCDNumber(self) self.num_4 = QLCDNumber(self) self.num_5 = QLCDNumber(self) self.num_6 = QLCDNumber(self) def create_sliders(self): self.sld_1 = QSlider(Qt.Vertical, self) self.sld_2 = QSlider(Qt.Vertical, self) self.sld_3 = QSlider(Qt.Vertical, self) self.sld_4 = QSlider(Qt.Vertical, self) self.sld_5 = QSlider(Qt.Vertical, self) self.sld_6 = QSlider(Qt.Vertical, self) self.sld_1.setMinimum(self.sld_min) self.sld_2.setMinimum(self.sld_min) self.sld_3.setMinimum(self.sld_min) self.sld_4.setMinimum(self.sld_min) self.sld_5.setMinimum(self.sld_min) self.sld_6.setMinimum(self.sld_min) self.sld_1.setMaximum(self.sld_max) self.sld_2.setMaximum(self.sld_max) self.sld_3.setMaximum(self.sld_max) self.sld_4.setMaximum(self.sld_max) self.sld_5.setMaximum(self.sld_max) self.sld_6.setMaximum(self.sld_max) self.sld_1.setValue(self.sld_def) self.sld_2.setValue(self.sld_def) self.sld_3.setValue(self.sld_def) self.sld_4.setValue(self.sld_def) self.sld_5.setValue(self.sld_def) self.sld_6.setValue(self.sld_def) self.sld_1.setFocusPolicy(Qt.StrongFocus) self.sld_2.setFocusPolicy(Qt.StrongFocus) self.sld_3.setFocusPolicy(Qt.StrongFocus) self.sld_4.setFocusPolicy(Qt.StrongFocus) self.sld_5.setFocusPolicy(Qt.StrongFocus) self.sld_6.setFocusPolicy(Qt.StrongFocus) self.sld_1.setTickPosition(QSlider.TicksBothSides) self.sld_2.setTickPosition(QSlider.TicksBothSides) self.sld_3.setTickPosition(QSlider.TicksBothSides) self.sld_4.setTickPosition(QSlider.TicksBothSides) self.sld_5.setTickPosition(QSlider.TicksBothSides) self.sld_6.setTickPosition(QSlider.TicksBothSides) self.sld_1.setTickInterval(self.sld_interval) self.sld_2.setTickInterval(self.sld_interval) self.sld_3.setTickInterval(self.sld_interval) self.sld_4.setTickInterval(self.sld_interval) self.sld_5.setTickInterval(self.sld_interval) self.sld_6.setTickInterval(self.sld_interval) self.sld_1.setSingleStep(self.sld_step) self.sld_2.setSingleStep(self.sld_step) self.sld_3.setSingleStep(self.sld_step) self.sld_4.setSingleStep(self.sld_step) self.sld_5.setSingleStep(self.sld_step) self.sld_6.setSingleStep(self.sld_step) self.sld_1.valueChanged[int].connect(self.sliderChangeValue) self.sld_2.valueChanged[int].connect(self.sliderChangeValue) self.sld_3.valueChanged[int].connect(self.sliderChangeValue) self.sld_4.valueChanged[int].connect(self.sliderChangeValue) self.sld_5.valueChanged[int].connect(self.sliderChangeValue) self.sld_6.valueChanged[int].connect(self.sliderChangeValue) self.sld_1.valueChanged[int].connect(self.num_1.display) self.sld_2.valueChanged[int].connect(self.num_2.display) self.sld_3.valueChanged[int].connect(self.num_3.display) self.sld_4.valueChanged[int].connect(self.num_4.display) self.sld_5.valueChanged[int].connect(self.num_5.display) self.sld_6.valueChanged[int].connect(self.num_6.display) self.old_value_sld1 = self.sld_def self.old_value_sld2 = self.sld_def self.old_value_sld3 = self.sld_def self.old_value_sld4 = self.sld_def self.old_value_sld5 = self.sld_def self.old_value_sld6 = self.sld_def def create_checkboxes(self): self.checkbox_1 = QCheckBox(self.checkboxes_lables[0], self) self.checkbox_2 = QCheckBox(self.checkboxes_lables[1], self) self.checkbox_1.setChecked(False) self.checkbox_2.setChecked(False) self.checkbox_1.stateChanged.connect(self.checkboxClicked) self.checkbox_2.stateChanged.connect(self.checkboxClicked) def create_buttons(self): self.btn_1 = QPushButton(self.btns_lables[0], self) self.btn_2 = QPushButton(self.btns_lables[1], self) self.btn_3 = QPushButton(self.btns_lables[2], self) self.btn_1.clicked.connect(self.buttonClicked) self.btn_2.clicked.connect(self.buttonClicked) self.btn_3.clicked.connect(self.buttonClicked) def create_graphics(self): figure_1 = plt.figure() self.figure_2 = plt.figure() self.figure_4 = plt.figure() self.canvas_1 = FigureCanvas(figure_1) self.canvas_2 = FigureCanvas(self.figure_2) self.canvas_4 = FigureCanvas(self.figure_4) self.toolbar_1 = NavigationToolbar(self.canvas_1, self) self.toolbar_2 = NavigationToolbar(self.canvas_2, self) self.toolbar_4 = NavigationToolbar(self.canvas_4, self) figure_1.clear() self.figure_2.clear() self.figure_4.clear() ax_1 = figure_1.add_subplot(1, 1, 1) self.ax_2 = self.figure_2.add_subplot(1, 1, 1) self.ax_4 = self.figure_4.add_subplot(1, 1, 1) ax_1.set_xlabel('Частота, Гц') self.ax_2.set_xlabel('Частота, Гц') self.ax_4.set_xlabel('Время, с') figure_1.align_xlabels() self.figure_2.align_xlabels() self.figure_4.align_xlabels() ax_1.set_ylabel('Амплитуда') self.ax_2.set_ylabel('Амплитуда') self.ax_4.set_ylabel('Амплитуда') figure_1.align_ylabels() self.figure_2.align_ylabels() self.figure_4.align_ylabels() self.elem_per_herz = self.spectrum.shape[1] // (self.max_freq - self.min_freq) ax_1.plot( np.fft.rfftfreq(self.nframes, 1. / self.framerate)[::self.koeff], np.abs(self.spectrum[0][::self.koeff]) / self.nframes) self.ax_2.plot( np.fft.rfftfreq(self.nframes, 1. / self.framerate)[::self.koeff], np.abs(self.spectrum[0][::self.koeff]) / self.nframes) self.ax_4.plot(self.channels[0][::self.koeff]) self.canvas_1.draw() self.canvas_2.draw() self.canvas_4.draw() def create_interface(self): self.labels_box = QHBoxLayout() self.labels_box.addWidget(self.label_1) self.labels_box.addWidget(self.label_2) self.labels_box.addWidget(self.label_3) self.labels_box.addWidget(self.label_4) self.labels_box.addWidget(self.label_5) self.labels_box.addWidget(self.label_6) self.nums_box = QHBoxLayout() self.nums_box.addWidget(self.num_1) self.nums_box.addWidget(self.num_2) self.nums_box.addWidget(self.num_3) self.nums_box.addWidget(self.num_4) self.nums_box.addWidget(self.num_5) self.nums_box.addWidget(self.num_6) self.slds_box = QHBoxLayout() self.slds_box.addWidget(self.sld_1) self.slds_box.addWidget(self.sld_2) self.slds_box.addWidget(self.sld_3) self.slds_box.addWidget(self.sld_4) self.slds_box.addWidget(self.sld_5) self.slds_box.addWidget(self.sld_6) self.graphs_box_1 = QVBoxLayout() self.graphs_box_1.addWidget(self.toolbar_4) self.graphs_box_1.addWidget(self.canvas_4) self.checks_and_btns_box = QHBoxLayout() self.checks_and_btns_box.addWidget(self.checkbox_1) self.checks_and_btns_box.addWidget(self.checkbox_2) self.checks_and_btns_box.addWidget(self.btn_1) self.checks_and_btns_box.addWidget(self.btn_2) self.checks_and_btns_box.addWidget(self.btn_3) self.graphs_box_2 = QVBoxLayout() self.graphs_box_2.addWidget(self.toolbar_1) self.graphs_box_2.addWidget(self.canvas_1) self.graphs_box_2.addWidget(self.toolbar_2) self.graphs_box_2.addWidget(self.canvas_2) self.left_box = QVBoxLayout() self.left_box.addLayout(self.labels_box) self.left_box.addLayout(self.slds_box) self.left_box.addLayout(self.nums_box) self.left_box.addLayout(self.graphs_box_1) self.right_box = QVBoxLayout() self.right_box.addLayout(self.checks_and_btns_box) self.right_box.addLayout(self.graphs_box_2) self.all_box = QHBoxLayout() self.all_box.addLayout(self.left_box) self.all_box.addLayout(self.right_box) self.setLayout(self.all_box) self.setWindowTitle(self.app_name) self.showMaximized() def sliderChangeValue(self, value): if (self.sender() == self.sld_1): self.sld1_worker = Worker(self.music_edit, 0, value) self.threadpool.start(self.sld1_worker) elif (self.sender() == self.sld_2): self.sld2_worker = Worker(self.music_edit, 1, value) self.threadpool.start(self.sld2_worker) elif (self.sender() == self.sld_3): self.sld3_worker = Worker(self.music_edit, 2, value) self.threadpool.start(self.sld3_worker) elif (self.sender() == self.sld_4): self.sld4_worker = Worker(self.music_edit, 3, value) self.threadpool.start(self.sld4_worker) elif (self.sender() == self.sld_5): self.sld5_worker = Worker(self.music_edit, 4, value) self.threadpool.start(self.sld5_worker) else: self.sld6_worker = Worker(self.music_edit, 5, value) self.threadpool.start(self.sld6_worker) def checkboxClicked(self, state): if (self.sender() == self.checkbox_1): if (state == Qt.Checked): self.checkbox_2.setChecked(False) self.channels = self.channels_kliping.copy() self.spectrum = self.spectrum_kliping.copy() else: self.channels = self.channels_original.copy() self.spectrum = self.spectrum_original.copy() else: if (state == Qt.Checked): self.checkbox_1.setChecked(False) self.channels = self.channels_envelop.copy() self.spectrum = self.spectrum_envelop.copy() else: self.channels = self.channels_original.copy() self.spectrum = self.spectrum_original.copy() self.sld_1.setValue(self.sld_def) self.sld_2.setValue(self.sld_def) self.sld_3.setValue(self.sld_def) self.sld_4.setValue(self.sld_def) self.sld_5.setValue(self.sld_def) self.sld_6.setValue(self.sld_def) draw_1 = Worker(self.draw_array, self.spectrum, 0) self.threadpool.start(draw_1) draw_2 = Worker(self.draw_array, self.channels, 1) self.threadpool.start(draw_2) def buttonClicked(self): if (self.sender() == self.btn_1): if (self.music_is_playing == False): self.music_is_playing = True self.music_worker = Worker(self.start_music) self.threadpool.start(self.music_worker) elif (self.sender() == self.btn_2): if (self.music_is_playing == True): self.music_is_playing = False else: if (self.music_is_playing == True): self.music_is_playing = False self.threadpool.clear() sliders = [ self.sld1_worker, self.sld2_worker, self.sld3_worker, self.sld4_worker, self.sld5_worker, self.sld6_worker ] for slider in sliders: self.sld_stop(slider) self.buffer_cnt = 0 self.sld_1.setValue(self.sld_def) self.sld_2.setValue(self.sld_def) self.sld_3.setValue(self.sld_def) self.sld_4.setValue(self.sld_def) self.sld_5.setValue(self.sld_def) self.sld_6.setValue(self.sld_def) self.checkbox_1.setChecked(False) self.checkbox_2.setChecked(False) tmp_worker = Worker(self.tmp_func) self.threadpool.start(tmp_worker) def sld_stop(self, slider): ids = { self.sld1_worker: 0, self.sld2_worker: 1, self.sld3_worker: 2, self.sld4_worker: 3, self.sld5_worker: 4, self.sld6_worker: 5 } slider = Worker(self.music_edit, ids[slider], self.sld_def) self.threadpool.start(slider) def tmp_func(self): while (self.threadpool.activeThreadCount() != 1): sleep(0.1) self.channels = self.channels_original.copy() self.spectrum = self.spectrum_original.copy() print('music stopped') def start_music(self): tmp_channels = [] tmp_channels.append( self.channels[0][self.buffer_cnt * self.buffer_size:(self.buffer_cnt + 1) * self.buffer_size + 1:]) tmp_channels.append( self.channels[1][self.buffer_cnt * self.buffer_size:(self.buffer_cnt + 1) * self.buffer_size + 1:]) tmp_channels = np.array(tmp_channels) tmp_channels = np.ascontiguousarray(tmp_channels.T) tmp_sound = pygame.sndarray.make_sound(tmp_channels) sound = tmp_sound if (self.music_is_playing == False): return pygame.mixer.Sound.play(sound) start_pos = self.buffer_cnt for self.buffer_cnt in range(start_pos + 1, self.nframes // self.buffer_size): tmp_channels = [] tmp_channels.append( self.channels[0][self.buffer_cnt * self.buffer_size:(self.buffer_cnt + 1) * self.buffer_size + 1:]) tmp_channels.append( self.channels[1][self.buffer_cnt * self.buffer_size:(self.buffer_cnt + 1) * self.buffer_size + 1:]) tmp_channels = np.array(tmp_channels) tmp_channels = np.ascontiguousarray(tmp_channels.T) tmp_sound = pygame.sndarray.make_sound(tmp_channels) while (pygame.mixer.get_busy()): sleep(0.01) sound = tmp_sound if (self.music_is_playing == False): return pygame.mixer.Sound.play(sound) tmp_channels = [] tmp_channels.append(self.channels[0][self.buffer_cnt * self.buffer_size::]) tmp_channels.append(self.channels[1][self.buffer_cnt * self.buffer_size::]) tmp_channels = np.array(tmp_channels) tmp_channels = np.ascontiguousarray(tmp_channels.T) tmp_sound = pygame.sndarray.make_sound(tmp_channels) while (pygame.mixer.get_busy()): sleep(0.01) sound = tmp_sound if (self.music_is_playing == False): return pygame.mixer.Sound.play(sound) self.buffer_cnt = 0 self.music_is_playing = False def music_edit(self, pos, value): old_values = { 0: self.old_value_sld1, 1: self.old_value_sld2, 2: self.old_value_sld3, 3: self.old_value_sld4, 4: self.old_value_sld5, 5: self.old_value_sld6 } old_value = old_values[pos] if pos == 0: self.old_value_sld1 = value elif pos == 1: self.old_value_sld2 = value elif pos == 2: self.old_value_sld3 = value elif pos == 3: self.old_value_sld4 = value elif pos == 4: self.old_value_sld5 = value else: self.old_value_sld6 = value if (old_value == value): return if (pos == 0): for i in range(self.nchannels): self.spectrum[i][:self.elem_per_herz * self.bands[1][pos] + 1] *= 10**((value - old_value) / 20) elif (pos == 5): for i in range(self.nchannels): self.spectrum[i][self.elem_per_herz * self.bands[0][pos]:] *= 10**( (value - old_value) / 20) else: for i in range(self.nchannels): self.spectrum[i][self.elem_per_herz * self.bands[0][pos]:self.elem_per_herz * self.bands[1][pos] + 1] *= 10**((value - old_value) / 20) self.channels = (np.fft.irfft(self.spectrum)).astype( self.types[self.sampwidth]) draw_1 = Worker(self.draw_array, self.spectrum, 0) self.threadpool.start(draw_1) draw_2 = Worker(self.draw_array, self.channels, 1) self.threadpool.start(draw_2) def draw_array(self, arr, spectrum_or_channel): if (spectrum_or_channel == 0): self.figure_2.clear() self.ax_2 = self.figure_2.add_subplot(1, 1, 1) self.ax_2.set_xlabel('Частота, Гц') self.figure_2.align_xlabels() self.ax_2.set_ylabel('Амплитуда') self.figure_2.align_ylabels() self.ax_2.plot( np.fft.rfftfreq(self.nframes, 1. / self.framerate)[::self.koeff], np.abs(arr[0][::self.koeff]) / self.nframes) self.canvas_2.draw() else: self.figure_4.clear() self.ax_4 = self.figure_4.add_subplot(1, 1, 1) self.ax_4.set_xlabel('Время, с') self.figure_4.align_xlabels() self.ax_4.set_ylabel('Амплитуда') self.figure_4.align_ylabels() self.ax_4.plot(arr[0][::self.koeff]) self.canvas_4.draw() def doing_kliping(self, channels): print('kliping start') start_time = time() threshold_max = int(0.6 * np.max(channels[0])) threshold_min = int(0.6 * np.min(channels[0])) self.channels_kliping = np.maximum(np.minimum(channels, threshold_max), threshold_min).astype( self.types[self.sampwidth]) self.spectrum_kliping = np.fft.rfft(self.channels_kliping) print('kliping end: ' + str(time() - start_time)) def doing_envelop(self, channels): print('envelop start') start_time = time() frequency = 1 / 15 envelope_sig = np.array([ abs(sin(2 * pi * frequency * t / self.framerate)) for t in range(self.nframes) ]) tmp_channels = channels.copy() for i in range(self.nchannels): tmp_channels[i] = (tmp_channels[i] * envelope_sig).astype( self.types[self.sampwidth]) self.channels_envelop = tmp_channels.copy() self.spectrum_envelop = np.fft.rfft(self.channels_envelop) print('envelop end: ' + str(time() - start_time))
class Ui(QtWidgets.QMainWindow): def __init__(self): super(Ui, self).__init__() # https://github.com/mherrmann/fbs/issues/32 uic.loadUi(appctxt.get_resource('main.ui'), self) # `findChild(,'open')`非必需,比如uic会自动在此自动生成`self.open` self.open_button = self.findChild(QtWidgets.QPushButton, 'open') self.convert_button = self.findChild(QtWidgets.QPushButton, 'convertButton') self.output_button = self.findChild(QtWidgets.QPushButton, 'output') self.output_dir_edit = self.findChild(QtWidgets.QLineEdit, 'output_dir') self.progress_bar = self.findChild(QtWidgets.QProgressBar, 'progressBar') self.list_widget = self.findChild(QtWidgets.QListWidget, 'listWidget') self.open_button.clicked.connect(self.open_button_pressed) self.convert_button.clicked.connect(self.convert_button_pressed) self.output_button.clicked.connect(self.output_button_pressed) self.directory = None self.entries = None self.output_dir = None self.mutex = QMutex() self.thread_pool = QThreadPool() self.thread_pool.setMaxThreadCount(os.cpu_count() - 1) # for not use all system cpu self.show() def convert(self, entry): in_filename = os.path.join(self.directory, entry) out_filename = os.path.join(self.output_dir, os.path.splitext(entry)[0] + '.mp3') # `run_async(quite=True)` will pipe subprocess stdout and stderr from ffmpeg-python code. # This will block subprocess If parent process not read the PIPE, # cause the PIPE bufsize is io.DEFAULT_BUFFER_SIZE by default. # so use `run_async()` now. # TODO Read stdout and stderr from PIPE for logs. process = (ffmpeg .input(in_filename) .output(out_filename, format='mp3') .overwrite_output() .run_async() ) while process.poll() is None: if _QUIT: process.terminate() process.wait() else: time.sleep(1) def thread_complete(self): self.mutex.lock() self.progress_bar.setValue(self.progress_bar.value() + 1) self.mutex.unlock() if self.progress_bar.value() == self.progress_bar.maximum(): self.convert_button.setDisabled(False) self.statusBar.showMessage('文件全部转换完成.') def convert_button_pressed(self): self.statusBar.showMessage('') if self.output_dir and self.directory and self.entries: self.progress_bar.setMaximum(len(self.entries)) self.progress_bar.setValue(0) self.convert_button.setEnabled(False) self.statusBar.showMessage('文件转换中...') for entry in self.entries: worker = Worker(self.convert, entry) worker.signals.finished.connect(self.thread_complete) self.thread_pool.start(worker) def open_button_pressed(self): self.directory = str(QFileDialog.getExistingDirectory(self, "选择音频目录")) if self.directory: self.entries = sorted( [i for i in os.listdir(self.directory) if os.path.splitext(i)[-1][1:] in ['wma', 'mp3']]) self.list_widget.clear() self.list_widget.addItems(self.entries) def output_button_pressed(self): self.output_dir = str(QFileDialog.getExistingDirectory(self, "选择输出目录")) if self.output_dir: self.output_dir_edit.setText(self.output_dir) def exit(self): self.thread_pool.clear() global _QUIT _QUIT = True time.sleep(1.5) self.thread_pool.waitForDone()