예제 #1
0
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()
예제 #2
0
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()
예제 #3
0
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)
예제 #4
0
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()
예제 #5
0
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]
예제 #6
0
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()
예제 #7
0
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()
예제 #8
0
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(' ', '&nbsp;')
        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)
예제 #9
0
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)
예제 #10
0
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()
예제 #11
0
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
예제 #12
0
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())
예제 #13
0
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)
예제 #14
0
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()
예제 #15
0
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()
예제 #17
0
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()
예제 #18
0
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))
예제 #19
0
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()