コード例 #1
0
class Window(QMainWindow):
    def __init__(self):
        super(Window, self).__init__(flags=Qt.Window)
        self.index_page = 0
        self.valid_players = player_store.players
        self.setWindowTitle("Business FUT")
        self.setWindowIcon(QIcon("img/fut_icon.ico"))
        self.tab_widgets = QTabWidget()
        self.tab_widgets.setStyleSheet(QTabWidget_stylesheet)
        self.tab_widgets.blockSignals(True)
        self.tab_widgets.currentChanged.connect(self.on_tab_changed)
        self.buy_tab = BuyTab()
        self.favorite_tab = FavoriteTab()
        self.sell_tab = SellTab()
        self.tab_widgets.addTab(self.buy_tab, "Achats")
        self.tab_widgets.addTab(self.favorite_tab, "Favoris")
        self.tab_widgets.addTab(self.sell_tab, "Ventes")
        self.setCentralWidget(self.tab_widgets)
        self.tab_widgets.blockSignals(False)

    def on_tab_changed(self):
        self.tab_widgets.currentWidget().update_table()

    def keyPressEvent(self, e):
        if type(e) == QKeyEvent and e.key() == Qt.Key_F1:
            c.ech += 1
            if c.ech > 3:
                c.ech = 1
            from model.database import Database
            db = Database()
            db.update_constant(c.ech)
            self.close()
コード例 #2
0
ファイル: dicast.py プロジェクト: CGAT-Group/DICAST
class Ui_main_window(object):
    trigger = pyqtSignal()

    def __init__(self, window):
        super().__init__()

        self.config_setter = None
        self.main_window = window
        self.main_grid = QtWidgets.QWidget(self.main_window)

        self.process = QtCore.QProcess()
        self._pid = -1
        self.process_finished = False
        self.std_err_file = ""
        self.std_out_file = ""
        self.new_process_starting_date = ""
        self.old_process_starting_date = ""

        self.timer = QTimer()

        self.resources_path = os.path.join(
            os.path.abspath(os.path.dirname(__file__)), "resources")
        self.log_path = os.path.join(
            os.path.abspath(os.path.dirname(__file__)), "log")

        self.statusbar = QtWidgets.QStatusBar(self.main_window)
        self.menubar = QtWidgets.QMenuBar(self.main_window)
        self.header_label = QtWidgets.QLabel(self.main_grid)

        self.line = QtWidgets.QFrame(self.main_grid)
        self.base_grid = QtWidgets.QGridLayout(self.main_grid)

        # File selection grid
        self.file_selector_grid = QtWidgets.QGridLayout()
        self.snake_label = QtWidgets.QLabel(self.main_grid)
        self.wd_label = QtWidgets.QLabel(self.main_grid)

        self.custom_snakefile_full_path = ""
        self.wd_folder_full_path = ""

        self.snake_button = QtWidgets.QPushButton(self.main_grid)
        self.snake_button.clicked.connect(
            lambda: self.set_snake_file(self.select_snakefile_label))

        self.wd_button = QtWidgets.QPushButton(self.main_grid)
        self.wd_button.clicked.connect(
            lambda: self.set_wd(self.select_wdfolder_label))

        self.select_snakefile_label = QtWidgets.QLabel(self.main_grid)
        self.select_wdfolder_label = QtWidgets.QLabel(self.main_grid)

        # Attribute grid
        self.attribute_settings_grid = QtWidgets.QGridLayout()
        self.set_configs_label = QtWidgets.QLabel(self.main_grid)
        self.set_configs_button = QtWidgets.QPushButton(self.main_grid)
        self.set_configs_button.clicked.connect(self.open_config_setter)
        self.config_setter_window = QtWidgets.QMainWindow()

        self.overwrite_label = QtWidgets.QLabel(self.main_grid)
        self.overwrite_cb = QtWidgets.QCheckBox(self.main_grid)
        self.overwrite_cb.stateChanged.connect(self.check_runnable)

        self.cores_label = QtWidgets.QLabel(self.main_grid)
        self.cores_line = QtWidgets.QLineEdit(self.main_grid)
        self.cores_line.setFixedWidth(120)
        self.cores_line.setText("2")
        self.cores_line.setValidator(QIntValidator())

        self.asim_label = QtWidgets.QLabel(self.main_grid)
        self.asim_cb = QtWidgets.QCheckBox(self.main_grid)

        self.mt_label = QtWidgets.QLabel(self.main_grid)
        self.mt_list = QtWidgets.QListWidget(self.main_grid)
        self.mt_list.setFixedHeight(130)
        self.mt_list.setSelectionMode(QAbstractItemView.MultiSelection)

        self.ast_label = QtWidgets.QLabel(self.main_grid)
        self.ast_list = QtWidgets.QListWidget(self.main_grid)
        self.ast_list.setFixedHeight(130)
        self.ast_list.setSelectionMode(QAbstractItemView.MultiSelection)

        for tool in MAPPING_TOOLS:
            self.mt_list.addItem(tool)

        for tool in AS_TOOLS:
            self.ast_list.addItem(tool)

        self.current_run_label = QtWidgets.QLabel(self.main_grid)
        self.refresh_status_button = QtWidgets.QPushButton(self.main_grid)
        self.refresh_status_button.clicked.connect(self.check_running)

        self.cleanup_button = QtWidgets.QPushButton(self.main_grid)
        self.cleanup_button.clicked.connect(self.cleanup)

        self.snake_out_text_edit = QPlainTextEdit()
        self.error_text_edit = QPlainTextEdit()
        self.snake_out_text_edit.setReadOnly(True)
        self.error_text_edit.setReadOnly(True)

        self.tabs = QTabWidget()
        self.tabs.setMinimumHeight(200)
        self.tabs.blockSignals(True)
        self.tabs.currentChanged.connect(self.refresh_log_display)
        self.snakemake_out_tab = QWidget()
        self.error_out_tab = QWidget()
        self.tabs.addTab(self.snakemake_out_tab, "DICAST Output")
        self.tabs.addTab(self.error_out_tab, "Snakemake Output")

        # Bottom button grid
        self.horizontal_layout = QtWidgets.QHBoxLayout()

        self.okcancel_buttonbox = QtWidgets.QDialogButtonBox(self.main_grid)
        self.okcancel_buttonbox.accepted.connect(self.on_button_ok_clicked)

    def setupUi(self, window):
        window.setObjectName("main_window")
        size_policy_f_f = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed,
                                                QtWidgets.QSizePolicy.Fixed)
        size_policy_f_f.setHorizontalStretch(0)
        size_policy_f_f.setVerticalStretch(0)
        size_policy_e_f = QtWidgets.QSizePolicy(
            QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
        size_policy_e_p = QtWidgets.QSizePolicy(
            QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
        size_policy_e_p.setHorizontalStretch(0)
        size_policy_e_p.setVerticalStretch(0)

        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum,
                                           QtWidgets.QSizePolicy.Minimum)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(window.sizePolicy().hasHeightForWidth())
        window.setSizePolicy(sizePolicy)
        icon = QtGui.QIcon()
        pix_map_path = os.path.join(self.resources_path, "Dicast.svg")
        icon.addPixmap(QtGui.QPixmap(pix_map_path), QtGui.QIcon.Normal,
                       QtGui.QIcon.Off)
        window.setWindowIcon(icon)
        self.main_grid.setEnabled(True)
        self.main_grid.setObjectName("main_grid")
        self.base_grid.setObjectName("gridLayout_2")
        horizontal_spacer = QtWidgets.QSpacerItem(
            20, 40, QtWidgets.QSizePolicy.Minimum,
            QtWidgets.QSizePolicy.Expanding)
        self.base_grid.addItem(horizontal_spacer, 6, 0, 1, 1)
        self.file_selector_grid.setSizeConstraint(
            QtWidgets.QLayout.SetDefaultConstraint)
        self.file_selector_grid.setObjectName("file_selector_grid")
        vertical_spacer = QtWidgets.QSpacerItem(
            0, 0, QtWidgets.QSizePolicy.Expanding,
            QtWidgets.QSizePolicy.Minimum)

        size_policy_e_p.setHeightForWidth(
            self.wd_label.sizePolicy().hasHeightForWidth())
        self.wd_label.setSizePolicy(size_policy_e_p)
        self.wd_label.setObjectName("wd_label")
        self.file_selector_grid.addWidget(self.wd_label, 0, 0, 1, 2,
                                          QtCore.Qt.AlignLeft)
        size_policy_f_f.setHeightForWidth(
            self.wd_button.sizePolicy().hasHeightForWidth())
        self.wd_button.setSizePolicy(size_policy_f_f)
        self.wd_button.setObjectName("wd_button")
        self.file_selector_grid.addWidget(
            self.wd_button, 1, 0, 1, 1,
            QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
        self.file_selector_grid.addWidget(
            self.select_wdfolder_label, 1, 1, 1, 1,
            QtCore.Qt.AlignLeft | QtCore.Qt.AlignHCenter)
        self.file_selector_grid.addItem(vertical_spacer, 1, 3, 1, 1)

        size_policy_e_p.setHeightForWidth(
            self.snake_label.sizePolicy().hasHeightForWidth())
        self.snake_label.setSizePolicy(size_policy_e_p)
        self.snake_label.setObjectName("snake_label")
        self.file_selector_grid.addWidget(self.snake_label, 0, 2, 1, 2,
                                          QtCore.Qt.AlignLeft)
        size_policy_f_f.setHeightForWidth(
            self.snake_button.sizePolicy().hasHeightForWidth())
        self.snake_button.setSizePolicy(size_policy_f_f)
        self.snake_button.setObjectName("snake_button")
        self.snake_button.setToolTip(
            "If you have a customized Snakefile, you can select it here."
            "\nOr leave it blank to use the one provided by DICAST."
            "\nIf you do use your own, the configuration file created with this"
            "\ntool will be saved to the same directory as your Snakefile.")
        self.file_selector_grid.addWidget(
            self.snake_button, 1, 2, 1, 1,
            QtCore.Qt.AlignLeft | QtCore.Qt.AlignHCenter)
        self.file_selector_grid.addWidget(
            self.select_snakefile_label, 1, 3, 1, 1,
            QtCore.Qt.AlignLeft | QtCore.Qt.AlignHCenter)
        self.file_selector_grid.addItem(vertical_spacer, 1, 1, 1, 1)

        size_policy_e_p.setHeightForWidth(
            self.set_configs_label.sizePolicy().hasHeightForWidth())
        self.set_configs_label.setSizePolicy(size_policy_e_p)
        self.set_configs_label.setObjectName("config_label")
        self.file_selector_grid.addWidget(self.set_configs_label, 0, 4, 1, 2,
                                          QtCore.Qt.AlignLeft)

        size_policy_f_f.setHeightForWidth(
            self.set_configs_button.sizePolicy().hasHeightForWidth())
        self.set_configs_button.setSizePolicy(size_policy_f_f)
        self.set_configs_button.setObjectName("config_button")
        self.file_selector_grid.addWidget(
            self.set_configs_button, 1, 4, 1, 1,
            QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
        self.file_selector_grid.addItem(vertical_spacer, 1, 5, 1, 1)

        self.base_grid.addLayout(self.file_selector_grid, 2, 0, 1, 1)

        # Attributes
        # self.set_configs_label.setObjectName("set_configs_label")
        # self.attribute_settings_grid.addWidget(self.set_configs_label, 0, 0, 1, 1)

        # size_policy_f_f.setHeightForWidth(self.set_configs_button.sizePolicy().hasHeightForWidth())
        # self.set_configs_button.setSizePolicy(size_policy_f_f)
        # self.set_configs_button.setObjectName("set_configs_button")
        # self.attribute_settings_grid.addWidget(self.set_configs_button, 0, 1, 1, 1)

        self.overwrite_label.setObjectName("overwrite_label")
        self.attribute_settings_grid.addWidget(self.overwrite_label, 0, 0, 1,
                                               1)

        self.overwrite_cb.setObjectName("overwrite_cb")
        self.attribute_settings_grid.addWidget(self.overwrite_cb, 0, 1, 1, 1,
                                               QtCore.Qt.AlignLeft)

        self.cores_label.setObjectName("cores_label")
        self.attribute_settings_grid.addWidget(self.cores_label, 1, 0, 1, 1)
        size_policy_e_f.setHeightForWidth(
            self.cores_line.sizePolicy().hasHeightForWidth())
        self.cores_line.setSizePolicy(size_policy_e_f)
        self.cores_line.setObjectName("cores_line")
        self.attribute_settings_grid.addWidget(self.cores_line, 1, 1, 1, 2)

        self.asim_label.setObjectName("asim_label")
        self.attribute_settings_grid.addWidget(self.asim_label, 2, 0, 1, 1)

        self.asim_cb.setObjectName("asim_cb")
        self.attribute_settings_grid.addWidget(self.asim_cb, 2, 1, 1, 1,
                                               QtCore.Qt.AlignLeft)

        self.attribute_settings_grid.setObjectName("attribute_settings_grid")
        self.mt_label.setObjectName("mt_label")
        self.attribute_settings_grid.addWidget(self.mt_label, 3, 0, 1, 1)

        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum,
                                           QtWidgets.QSizePolicy.Minimum)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)

        self.mt_list.setMinimumHeight(60)
        self.mt_list.setSizePolicy(sizePolicy)
        self.mt_list.setObjectName("mt_list")
        self.attribute_settings_grid.addWidget(self.mt_list, 4, 0, 1, 1,
                                               QtCore.Qt.AlignLeft)

        self.ast_label.setObjectName("ast_label")
        self.attribute_settings_grid.addWidget(self.ast_label, 3, 1, 1, 1)

        self.ast_list.setMinimumHeight(60)
        self.ast_list.setSizePolicy(sizePolicy)
        self.ast_list.setObjectName("ast_list")
        self.attribute_settings_grid.addWidget(self.ast_list, 4, 1, 1, 1,
                                               QtCore.Qt.AlignLeft)

        self.current_run_label.setObjectName("current_run_label")
        self.current_run_label.setWordWrap(True)

        self.base_grid.addWidget(self.current_run_label, 5, 0, 1, 1)
        self.base_grid.addWidget(self.tabs, 6, 0, 1, 1)

        self.snake_out_text_edit.setObjectName("snake_out_text_edit")
        self.snakemake_out_tab.layout = QVBoxLayout()
        self.snakemake_out_tab.layout.addWidget(self.snake_out_text_edit, 0)
        self.snakemake_out_tab.setLayout(self.snakemake_out_tab.layout)

        self.error_text_edit.setObjectName("error_text_edit")
        self.error_out_tab.layout = QVBoxLayout()
        self.error_out_tab.layout.addWidget(self.error_text_edit, 0)
        self.error_out_tab.setLayout(self.error_out_tab.layout)

        self.horizontal_layout.setObjectName("horizontal_layout")

        size_policy_f_f.setHeightForWidth(
            self.refresh_status_button.sizePolicy().hasHeightForWidth())
        self.refresh_status_button.setSizePolicy(size_policy_f_f)
        self.refresh_status_button.setObjectName("refresh_status_button")
        self.horizontal_layout.addWidget(self.refresh_status_button)

        size_policy_f_f.setHeightForWidth(
            self.cleanup_button.sizePolicy().hasHeightForWidth())
        self.cleanup_button.setSizePolicy(size_policy_f_f)
        self.cleanup_button.setObjectName("refresh_status_button")
        self.cleanup_button.setToolTip(
            "Should a run fail or be aborted, it may be necessary to remove\n"
            "unfinished log files and the lock on the working directory.")
        self.horizontal_layout.addWidget(self.cleanup_button)
        self.horizontal_layout.addItem(vertical_spacer)
        self.base_grid.addLayout(self.horizontal_layout, 7, 0, 1, 1)

        self.okcancel_buttonbox.setStandardButtons(
            QtWidgets.QDialogButtonBox.Close | QtWidgets.QDialogButtonBox.Abort
            | QtWidgets.QDialogButtonBox.Ok)
        self.submit_button = self.okcancel_buttonbox.button(
            QtWidgets.QDialogButtonBox.Ok)
        self.abort_button = self.okcancel_buttonbox.button(
            QtWidgets.QDialogButtonBox.Abort)
        palette = self.abort_button.palette()
        palette.setColor(self.abort_button.backgroundRole(),
                         QColor(252, 53, 53))
        self.abort_button.setAutoFillBackground(True)
        self.abort_button.setPalette(palette)
        self.cancel_button = self.okcancel_buttonbox.button(
            QtWidgets.QDialogButtonBox.Close)
        self.abort_button.clicked.connect(self.on_button_abort_clicked)
        self.cancel_button.clicked.connect(self.main_window.close)
        self.okcancel_buttonbox.setObjectName("okcancel_buttonbox")
        self.base_grid.addWidget(self.okcancel_buttonbox, 8, 0, 1, 1)

        self.base_grid.addLayout(self.attribute_settings_grid, 3, 0, 1, 1)
        self.header_label.setObjectName("header_label")
        pix_map_path = os.path.join(self.resources_path, "Dicast-text.png")
        pixmap = QPixmap(pix_map_path)
        pixmap = pixmap.scaled(250, 250, QtCore.Qt.KeepAspectRatio)
        self.header_label.setPixmap(pixmap)
        self.base_grid.addWidget(self.header_label, 0, 0, 1, 1)
        self.line.setFrameShape(QtWidgets.QFrame.HLine)
        self.line.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line.setObjectName("line")
        self.base_grid.addWidget(self.line, 1, 0, 1, 1)
        window.setCentralWidget(self.main_grid)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 692, 20))
        self.menubar.setObjectName("menubar")
        window.setMenuBar(self.menubar)
        self.statusbar.setObjectName("statusbar")
        window.setStatusBar(self.statusbar)

        self.retranslateUi(window)
        QtCore.QMetaObject.connectSlotsByName(window)
        self.tabs.blockSignals(False)
        self.check_running()
        self.timer.timeout.connect(self.check_running)
        self.timer.setInterval(1000)

    def retranslateUi(self, window):
        _translate = QtCore.QCoreApplication.translate
        window.setWindowTitle(_translate("main_window", "DICAST"))
        self.wd_button.setText(_translate("main_window", "Browse"))
        self.snake_button.setText(_translate("main_window", "Browse"))
        self.snake_label.setText(
            _translate("main_window", "Select custom Snakefile"))
        self.select_snakefile_label.setText(
            _translate("main_window", "Select a file..."))
        self.select_wdfolder_label.setText(
            _translate("main_window", "Select a folder..."))
        self.wd_label.setText(
            _translate("main_window", "Select working directory"))
        self.mt_label.setText(
            _translate("main_window", "Which mapping tools: "))
        self.set_configs_label.setText(
            _translate("main_window", "Customize configuration file"))
        self.set_configs_button.setText(_translate("main_window", "Customize"))
        self.overwrite_label.setText(
            _translate("main_window", "Possible overwrite acknowledgment"))
        self.overwrite_cb.setText(_translate("main_window", "Acknowledged"))
        self.cores_label.setText(
            _translate("main_window",
                       "Number of cores available to Snakemake"))
        self.ast_label.setText(_translate("main_window", "Which AS tools: "))
        self.asim_label.setText(
            _translate("main_window", "Do you want to run ASimulatoR?"))
        self.asim_cb.setText(_translate("main_window", "Yes"))
        self.refresh_status_button.setText(
            _translate("main_window", "Refresh status"))
        self.cleanup_button.setText(_translate("main_window", "Cleanup"))

    def set_wd(self, label):
        path = on_button_get_folder_path_clicked(label, "/")
        if path != "":
            self.wd_folder_full_path = path
        wd_button_palette = self.wd_button.style().standardPalette()
        if self.wd_folder_full_path != "":
            self.config_setter = ConfigSetter(self.config_setter_window,
                                              self.wd_folder_full_path)
            if not self.config_setter.parse_successful:
                self.wd_folder_full_path = ""
                self.select_wdfolder_label.setText("Select a folder...")
                self.config_setter = None
                wd_button_palette.setColor(self.wd_button.backgroundRole(),
                                           QColor(252, 53, 53))
            else:
                self.config_setter.setup_ui(self.config_setter_window)
            self.wd_button.setPalette(wd_button_palette)

    def set_snake_file(self, label):
        if self.wd_folder_full_path != "":
            self.custom_snakefile_full_path = on_button_get_file_path_clicked(
                label, self.wd_folder_full_path)
        else:
            show_popup(
                "Error - Missing working directory",
                "Please set the working directory before selecting the snakefile."
            )

    def on_button_ok_clicked(self):
        if self.check_runnable(True):
            self.submit()
            self.overwrite_cb.setChecked(False)
            self.check_running()

    def submit(self):
        self.start_process()
        self.process.started.connect(
            lambda: self.submit_button.setDisabled(True))
        self.process.finished.connect(
            lambda: self.submit_button.setEnabled(True))
        self.process.started.connect(
            lambda: self.cleanup_button.setDisabled(True))
        self.process.finished.connect(
            lambda: self.cleanup_button.setEnabled(True))

    def check_runnable(self, submit_state=False):
        overwrite_cb_palette = self.overwrite_cb.palette()
        if submit_state:
            if not self.overwrite_cb.isChecked():
                overwrite_cb_palette.setColor(
                    self.overwrite_cb.backgroundRole(), QColor(252, 128, 121))
                self.overwrite_cb.setAutoFillBackground(True)
            else:
                overwrite_cb_palette = self.overwrite_cb.style(
                ).standardPalette()

            wd_button_palette = self.wd_button.palette()
            if self.wd_folder_full_path == "":
                wd_button_palette.setColor(self.wd_button.backgroundRole(),
                                           QColor(252, 53, 53))
            else:
                wd_button_palette = self.wd_button.style().standardPalette()
            self.wd_button.setPalette(wd_button_palette)

        self.overwrite_cb.setPalette(overwrite_cb_palette)
        return self.overwrite_cb.isChecked()

    def check_running(self):
        def check_process():
            log_file = os.path.join(self.log_path, "_pid.txt")
            try:
                with open(log_file, "r") as f:
                    process_identification = f.read()
                    _pid = int(process_identification.split("-")[0])
                    self.old_process_starting_date = process_identification.split(
                        "-")[1]
                    try:
                        if _pid != "" and _pid != -1:
                            self._pid = _pid
                            process = psutil.Process(_pid)

                            # Check if the process with the PID parsed from the _pid.txt file is actually the DICAST process by comparing it's creation time
                            # with the datetime parsed from the _pid.txt file. If the difference is smaller than 5 seconds, we assume its the same process
                            # 5 seconds because there can be a time delay between setting the datetime for the log files and the creation of the process
                            old_datetime = datetime.strptime(
                                self.old_process_starting_date,
                                '%Y_%m_%d_%H_%M_%S')
                            time_difference = abs(
                                (old_datetime - datetime.fromtimestamp(
                                    process.create_time())).total_seconds())
                            if time_difference < 5:
                                p_status = psutil.Process(_pid).status()
                                self.submit_button.setEnabled(False)
                            else:
                                raise psutil.NoSuchProcess
                        else:
                            return "Current status: Empty _pid.txt"
                    except psutil.NoSuchProcess:
                        self.submit_button.setEnabled(True)
                        if self.timer.isActive():
                            self.timer.stop()
                        return "Current status: No instance running, previous instance finished. " \
                               "Tabs below will show log files from the previous run."
                    else:
                        if not self.timer.isActive():
                            self.timer.start()
                        return f"Current status: Instance {_pid} has status: {p_status}"
            except FileNotFoundError:
                return f"Current status: Missing pid file. No instance running or wrong folder: {log_file}"

        self.current_run_label.setText(check_process())
        self.run_all_refresh_log_display()

    def run_all_refresh_log_display(self):
        self.refresh_log_display(0)
        self.refresh_log_display(1)

    def build_snakemake_config(self):
        config_dict = {
            "Possible_overwrite_acknowledge":
            self.overwrite_cb.isChecked(),
            "ASimulatoR":
            self.asim_cb.isChecked(),
            "Mapping_tools":
            " ".join([item.text() for item in self.mt_list.selectedItems()]),
            "Alternative_splicing_detection_tools":
            " ".join([item.text() for item in self.ast_list.selectedItems()])
        }

        if self.custom_snakefile_full_path != "":
            config_json_path = os.path.dirname(self.custom_snakefile_full_path)
            config_json_path = os.path.join(config_json_path,
                                            'snakemake_config.json')
        else:
            config_json_path = os.path.join(self.wd_folder_full_path,
                                            'scripts', 'snakemake',
                                            'snakemake_config.json')
            if Path(config_json_path).is_file():
                date = datetime.today().strftime('%Y_%m_%d_%H_%M_%S')
                backup_config_file = os.path.join(
                    os.path.dirname(config_json_path),
                    f"backup_{date}_{os.path.basename(config_json_path)}")
                os.rename(config_json_path, backup_config_file)
                backup_path = os.path.join(os.path.dirname(config_json_path),
                                           'backup')
                if not os.path.exists(backup_path):
                    os.makedirs(backup_path)
                move(backup_config_file, backup_path)

        with open(config_json_path, 'w') as f:
            json.dump(config_dict, f)

    def create_command_line_args(self):
        if self.custom_snakefile_full_path != "":
            snakefile_path = self.custom_snakefile_full_path
            snakefile_config_path = os.path.join(
                os.path.dirname(self.custom_snakefile_full_path),
                'snakemake_config.json')
        else:
            snakefile_path = os.path.join(self.wd_folder_full_path, 'scripts',
                                          'snakemake', 'Snakefile')
            snakefile_config_path = os.path.join(self.wd_folder_full_path,
                                                 'scripts', 'snakemake',
                                                 'snakemake_config.json')

        if not Path(snakefile_path).is_file():
            show_popup(
                "Error - File not found",
                f"Couldn't find Snakefile {snakefile_path}."
                f"\nPlease make sure you have selected the correct working directory and the file is in the correct folder."
            )
            return False

        if not Path(snakefile_config_path).is_file():
            show_popup(
                "Error - File not found",
                f"Couldn't find Snakefile config {snakefile_config_path}."
                f"\nSomething must have gone wrong in the creation of the config file. Please make sure the working directory is correct."
                f"\nIf you used a custom Snakefile, make sure you have write access to the folder."
            )
            return False

        args = [
            "-j", f"{self.cores_line.text()}", "-s", f"{snakefile_path}", "-d",
            f"{self.wd_folder_full_path}", "--configfile",
            f"{snakefile_config_path}"
        ]
        return args

    def start_process(self):
        self.build_snakemake_config()
        run_str = "snakemake"
        args = self.create_command_line_args()
        if not args:
            return
        self.process.setProgram(run_str)
        self.process.setArguments(args)
        if not os.path.isdir(self.log_path):
            os.makedirs(self.log_path)
        self.new_process_starting_date = datetime.today().strftime(
            '%Y_%m_%d_%H_%M_%S')
        self.std_err_file = os.path.join(
            self.log_path,
            f"snakemake_log_{self.new_process_starting_date}.txt")
        self.std_out_file = os.path.join(
            self.log_path, f"dicast_log_{self.new_process_starting_date}.txt")
        self.process.setStandardOutputFile(self.std_out_file)
        self.process.setStandardErrorFile(self.std_err_file)
        ok, pid = self.process.startDetached()
        if ok:
            self._pid = pid
            with open(os.path.join(self.log_path, "_pid.txt"), "w") as f:
                process_identification = f"{str(self._pid)}-{self.new_process_starting_date}"
                f.write(process_identification)
        else:
            show_popup(
                "Error - Failed to start.",
                "An error occurred and DICAST was unable to run the Snakemake pipeline.\n"
                "Make sure you have activated the correct conda environment and you can run snakemake.\n"
                "See the documentation for more information.")

    def on_button_abort_clicked(self):
        if not self.process_finished:
            self.stop_process()
            self.check_running()

    def process_finished(self):
        self.submit_button.setEnabled(True)
        self.process_finished = True

    def stop_process(self):
        if self._pid > 0:
            try:
                p = psutil.Process(self._pid)
            except psutil.NoSuchProcess:
                pass
            else:
                for child in p.children(recursive=True):
                    child.kill()
                p.kill()
                self._pid = -1

    def cleanup(self):
        if self.wd_folder_full_path == "":
            return
        locks_folder = os.path.join(self.wd_folder_full_path, ".snakemake",
                                    "locks")
        snake_output_folder = os.path.join(self.wd_folder_full_path, "output",
                                           "snakemake")
        if os.path.exists(locks_folder):
            rmtree(locks_folder)
        if os.path.exists(snake_output_folder):
            rmtree(snake_output_folder)

    def refresh_log_display(self, i):
        if i == 0:
            try:
                with open(self.std_out_file, 'r') as dicast_log_file:
                    data = dicast_log_file.read()
                    self.snake_out_text_edit.setPlainText(data)
                    # Scroll to the bottom
                    self.snake_out_text_edit.verticalScrollBar().setValue(
                        self.snake_out_text_edit.verticalScrollBar().maximum())
            except FileNotFoundError:
                try:
                    log_file = os.path.join(
                        self.log_path, "dicast_log_" +
                        self.old_process_starting_date + ".txt")
                    with open(log_file, 'r') as out_dicast_log_file:
                        data = out_dicast_log_file.read()
                        self.snake_out_text_edit.setPlainText(data)
                        self.snake_out_text_edit.verticalScrollBar().setValue(
                            self.snake_out_text_edit.verticalScrollBar(
                            ).maximum())
                except FileNotFoundError:
                    self.snake_out_text_edit.setPlainText(
                        "Couldn't find DICAST log file from previous run.")
        elif i == 1:
            try:
                with open(self.std_err_file, 'r') as out_snakemake_log_file:
                    data = out_snakemake_log_file.read()
                    self.error_text_edit.setPlainText(data)
                    self.error_text_edit.verticalScrollBar().setValue(
                        self.error_text_edit.verticalScrollBar().maximum())

            except FileNotFoundError:
                try:
                    snakemake_log_file = os.path.join(
                        self.log_path, "snakemake_log_" +
                        self.old_process_starting_date + ".txt")
                    with open(snakemake_log_file,
                              'r') as out_snakemake_log_file:
                        data = out_snakemake_log_file.read()
                        self.error_text_edit.setPlainText(data)
                        self.error_text_edit.verticalScrollBar().setValue(
                            self.error_text_edit.verticalScrollBar().maximum())
                except FileNotFoundError:
                    self.error_text_edit.setPlainText(
                        "Couldn't find Snakemake log file from previous run.")

    def open_config_setter(self):
        if self.config_setter is not None and self.config_setter.parse_successful:
            self.config_setter_window.show()
        else:
            show_popup(
                "Error - No config file found",
                "No config file found. Make sure the correct working directory is set."
            )
コード例 #3
0
ファイル: MultiView.py プロジェクト: AMaywurm/RepTate
class MultiView(QWidget):
    LEFT=0.15
    RIGHT=0.98
    BOTTOM=0.15
    TOP=0.98
    WSPACE=0.25
    HSPACE=0.35
    DPI = 300

    def __init__(self, pot=PlotOrganizationType.Vertical, nplots=1, ncols=1, parent=None):
        #QDialog.__init__(self)
        #super().__init__(self)
        #QWidget.__init__()
        super().__init__()
        self.parent_application = parent
        self.pot = pot
        self.nplots = nplots
        self.ncols = ncols
        self.setupUi()
        mpl.rcParams['savefig.dpi'] = self.DPI

    def setupUi(self):
        # Remove seaborn dependency
        dark_gray = ".15"
        light_gray = ".8"
        style_dict = {
            "figure.facecolor": "white",
            "text.color": dark_gray,
            "axes.labelcolor": dark_gray,
            "axes.facecolor": "white",
            "axes.edgecolor": dark_gray,
            "axes.linewidth": 1.25,
            "grid.color": light_gray,
            "legend.frameon": False,
            "legend.numpoints": 1,
            "legend.scatterpoints": 1,
            "xtick.direction": "out",
            "ytick.direction": "out",
            "xtick.color": dark_gray,
            "ytick.color": dark_gray,
            "xtick.major.size": 6,
            "ytick.major.size": 6,
            "xtick.minor.size": 3,
            "ytick.minor.size": 3,
            "axes.grid": False,
            "axes.axisbelow": True,
            "image.cmap": "rocket",
            "font.family": ["sans-serif"],
            "font.sans-serif": ["Arial", "DejaVu Sans", "Liberation Sans",
                                "Bitstream Vera Sans", "sans-serif"],
            "grid.linestyle": "-",
            "lines.solid_capstyle": "round",
            }
        mpl.rcParams.update(style_dict)

        self.setObjectName("self")
        self.horizontalLayout = QHBoxLayout(self)
        self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout.setSpacing(0)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.plotselecttabWidget = QTabWidget(self)
        self.plotselecttabWidget.setMaximumSize(QSize(22, 1000))
        self.plotselecttabWidget.setTabPosition(QTabWidget.West)
        self.plotselecttabWidget.setTabShape(QTabWidget.Triangular)
        self.plotselecttabWidget.setUsesScrollButtons(False)
        self.plotselecttabWidget.setDocumentMode(False)
        self.plotselecttabWidget.setTabsClosable(False)
        self.plotselecttabWidget.setObjectName("plotselecttabWidget")
        self.plotselecttabWidget.setStyleSheet("QTabBar::tab { color:black; height: 40px; }")

        # Create a tab for all plots
        if (self.nplots>1):
            self.tab = QWidget()
            self.tab.setMaximumSize(QSize(0, 0))
            self.plotselecttabWidget.addTab(self.tab, "All")
        else:
            self.plotselecttabWidget.setVisible(False)
        # Create a tab for each plot
        for i in range(self.nplots):
            self.tab = QWidget()
            self.tab.setMaximumSize(QSize(0, 0))
            self.plotselecttabWidget.addTab(self.tab, "%d"%(i+1))
        self.horizontalLayout.addWidget(self.plotselecttabWidget)
        self.plotselecttabWidget.setCurrentIndex(0)

        self.plotcontainer = QVBoxLayout()
        self.plotcontainer.setObjectName("plotcontainer")
        self.horizontalLayout.addLayout(self.plotcontainer)

        # Create the multiplot figure
        gs = self.organizeplots(self.pot, self.nplots, self.ncols)
        self.axarr = []
        self.figure = plt.figure()
        for i in range(self.nplots):
            self.axarr.append(self.figure.add_subplot(gs[i]))

        self.set_bbox()

        self.canvas = FigureCanvasQTAgg(self.figure)
        self.canvas.setFocusPolicy( Qt.ClickFocus )
        self.canvas.setFocus()
        self.plotcontainer.addWidget(self.canvas)
        self.init_plot(0)

        connection_id = self.plotselecttabWidget.currentChanged.connect(self.handle_plottabChanged)
        axes = plt.gcf().axes
        for ax_i in axes:
            for side in ["top", "right"]:
                ax_i.spines[side].set_visible(False)

            ax_i.xaxis.tick_bottom()
            ax_i.yaxis.tick_left()
        self.hidden_tab = []

    def set_bbox(self):
        self.bbox = []
        x0min = y0min = 1e9
        x1max = y1max = -1e9
        for i in range(self.nplots):
            bboxnow = self.axarr[i].get_position()
            self.bbox.append(bboxnow)
            x0min = min(x0min, bboxnow.x0)
            y0min = min(y0min, bboxnow.y0)
            x1max = max(x1max, bboxnow.x1)
            y1max = max(y1max, bboxnow.y1)
        self.bboxmax = [x0min, y0min, x1max-x0min, y1max-y0min]

    def reorg_fig(self, nplots):
        """Reorganise the views to show nplots"""
        if CmdBase.mode == CmdMode.GUI:
            self.parent_application.sp_nviews.blockSignals(True)
            self.parent_application.sp_nviews.setValue(nplots)
            self.parent_application.sp_nviews.blockSignals(False)

        self.plotselecttabWidget.blockSignals(True)
        nplot_old = self.nplots
        self.nplots = nplots
        gs = self.organizeplots(self.pot, self.nplots, self.ncols)

        # hide tabs if only one figure
        self.plotselecttabWidget.setVisible(nplots > 1)

        for i in range(nplots):
            self.axarr[i].set_position(gs[i].get_position(self.figure))
            self.axarr[i].set_subplotspec(gs[i])
        for tab in self.hidden_tab:
            tab_id = tab[0]
            widget = tab[1]
            tab_text = tab[2]
            self.plotselecttabWidget.insertTab(tab_id, widget, tab_text)
        self.hidden_tab = []

        for i in range(nplots, len(self.axarr)):
            self.axarr[i].set_visible(False)
            tab_id = i + 1
            widget = self.plotselecttabWidget.widget(nplots + 1)
            tab_text = self.plotselecttabWidget.tabText(nplots + 1)
            self.hidden_tab.append([tab_id, widget, tab_text])
            self.plotselecttabWidget.removeTab(nplots + 1)

        self.set_bbox()
        for i in range(self.nplots):
            self.axarr[i].set_position(self.bbox[i])
        # add new axes to plt
        for i in range(nplot_old, self.nplots):
            try:
                plt.subplot(self.axarr[i])
            except:
                pass
        # remove axes from plt
        for i in range(self.nplots, nplot_old):
            try:
                plt.delaxes(self.axarr[i])
            except:
                pass
        for ds in self.parent_application.datasets.values():
            ds.nplots = nplots
        self.parent_application.update_all_ds_plots()
        self.handle_plottabChanged(0) # switch to all plot tab
        self.plotselecttabWidget.blockSignals(False)

    def init_plot(self, index):
        if index == 0: #multiplots
            for i in range(self.nplots):
                self.axarr[i].set_position(self.bbox[i])
        else: #single plot max-size
            tab_to_maxi = index - 1
            for i in range(self.nplots):
                if i == tab_to_maxi: #hide other plots
                    self.axarr[i].set_visible(True)
                    self.axarr[i].set_position(self.bboxmax)
                else:
                    self.axarr[i].set_visible(False)

        self.parent_application.current_viewtab = index
        self.canvas.draw()

    def handle_plottabChanged(self, index):
        self.parent_application.current_viewtab = index
        if index == 0: #multiplots
            view_name = self.parent_application.multiviews[0].name
            if CmdBase.mode == CmdMode.GUI:
                ind = self.parent_application.viewComboBox.findText(view_name, Qt.MatchExactly)
                self.parent_application.viewComboBox.blockSignals(True)
                self.parent_application.viewComboBox.setCurrentIndex(ind) #set the view combobox according to current view
                self.parent_application.viewComboBox.blockSignals(False)
            for i in range(self.nplots):
                self.axarr[i].set_position(self.bbox[i])
                self.axarr[i].set_visible(True)
                try:
                    plt.subplot(self.axarr[i])
                except:
                    pass

        else: #single plot max-size
            tab_to_maxi = index - 1 # in 0 1 2
            view_name = self.parent_application.multiviews[tab_to_maxi].name
            if CmdBase.mode == CmdMode.GUI:
                ind = self.parent_application.viewComboBox.findText(view_name)
                self.parent_application.viewComboBox.blockSignals(True)
                self.parent_application.viewComboBox.setCurrentIndex(ind) #set the view combobox according to current view
                self.parent_application.viewComboBox.blockSignals(False)
            for i in range(self.nplots):
                if i == tab_to_maxi: #hide other plots
                    self.axarr[i].set_visible(True)
                    self.axarr[i].set_position(self.bboxmax)
                    try:
                        plt.subplot(self.axarr[i])
                    except:
                        pass
                else:
                    self.axarr[i].set_visible(False)
                    try:
                        plt.delaxes(self.axarr[i])
                    except:
                        pass
        self.parent_application.update_datacursor_artists()
        self.canvas.draw()
        self.parent_application.set_view_tools(view_name)

    def organizeHorizontal(self, nplots):
        gs = gridspec.GridSpec(1, self.nplots,left=self.LEFT,right=self.RIGHT,
                                  bottom=self.BOTTOM,top=self.TOP,
                                  wspace=self.WSPACE,hspace=self.HSPACE)
        return gs

    def organizeVertical(self, nplots):
        gs = gridspec.GridSpec(self.nplots, 1,left=self.LEFT,right=self.RIGHT,
                                  bottom=self.BOTTOM,top=self.TOP,
                                  wspace=self.WSPACE,hspace=self.HSPACE)
        return gs

    def organizeOptimalRow(self, nplots, ncols):
        row = math.ceil(nplots / ncols)
        gstmp = gridspec.GridSpec(row, ncols,left=self.LEFT,right=self.RIGHT,
                                  bottom=self.BOTTOM,top=self.TOP,
                                  wspace=self.WSPACE,hspace=self.HSPACE)
        gs=[]
        # First row might be different
        gs.append(gstmp[0,0:row*ncols-nplots+1])
        for j in range(row*ncols-nplots+1,ncols):
            gs.append(gstmp[0,j])
        for i in range(1,row):
            for j in range(ncols):
                gs.append(gstmp[i,j])
        return gs

    def organizeOptimalColumn(self, nplots, ncols):
        row = math.ceil(nplots/ncols)
        gstmp = gridspec.GridSpec(row, ncols,left=self.LEFT,right=self.RIGHT,
                                  bottom=self.BOTTOM,top=self.TOP,
                                  wspace=self.WSPACE,hspace=self.HSPACE)
        gs = []
        # First column might be different
        gs.append(gstmp[0:row*ncols-nplots+1,0])
        for j in range(row*ncols-nplots+1,row):
            gs.append(gstmp[j,0])
        for i in range(1,ncols):
            for j in range(row):
                gs.append(gstmp[j, i])

        return gs

    def organizeplots(self, organizationtype, nplots=1, ncols=1, gs=None):
        if organizationtype == PlotOrganizationType.Vertical:
            return self.organizeVertical(nplots)
        elif organizationtype == PlotOrganizationType.Horizontal:
            return self.organizeHorizontal(nplots)
        elif organizationtype == PlotOrganizationType.OptimalRow:
            return self.organizeOptimalRow(nplots, ncols)
        elif organizationtype == PlotOrganizationType.OptimalColumn:
            return self.organizeOptimalColumn(nplots, ncols)
        elif organizationtype == PlotOrganizationType.Specified:
            pass
        elif organizationtype == PlotOrganizationType.DefaultOrganization:
            pass
コード例 #4
0
class CamTabsWidget(QWidget):
    frames_ready = pyqtSignal(QImage, QImage, QImage)

    def __init__(self, parent, path):
        super(QWidget, self).__init__(parent)
        self.__path = path
        self.__counter = 0
        self.layout = QVBoxLayout(self)
        # initialize tab screen
        self.__tabs = QTabWidget()
        self.__tabs.blockSignals(True)  # just for not showing the initial message
        self.__tabs.currentChanged.connect(self.on_change)

        self.__tab3D = QWidget()
        self.__tab2D = QWidget()
        # add tabs
        self.__tabs.addTab(self.__tab3D, "3D")
        self.__tabs.addTab(self.__tab2D, "2D")
        # create the content and layout of the tab with 3D cameras
        self.__set_tab3d_layout()
        # create the content and layout of the tab with 2D cameras
        self.__set_tab2d_layout()
        # set all objects that support the pipeline to create 3D images
        self.__set_3d_supporting_objects()
        # capture the cameras' frames to create a movie
        self.layout.addWidget(self.__tabs)
        self.__run_movie()
        self.__tabs.blockSignals(False)

    def __set_3d_supporting_objects(self):
        self.pd_collection = []
        self.mapper_collection = []
        self.actor_collection = []
        self.np_array = []
        self.cells_npy = []
        self.timer_count = 0
        self._n_coordinates = 0
        self.align = rs.align(rs.stream.color)
        self.__iren = self.__vtkWidget.GetRenderWindow().GetInteractor()
        self.__iren.GetInteractorStyle().SetCurrentStyleToTrackballActor()
        self.__iren.GetInteractorStyle().SetCurrentStyleToTrackballCamera()
        self._timer = QTimer(self)
        self._timer.timeout.connect(self.timer_event)
        self.view_coordinates = [[0., .5, .5, 1.], [.5, .5, 1., 1.], [0., 0., .5, .5], [.5, 0., 1., .5]]

    def __set_tab3d_layout(self):
        frame = QFrame()
        # add a vtk-based window for interaction
        self.__vtkWidget = QVTKRenderWindowInteractor(frame)
        # add a label and a text box for input of the object id
        self.__lbl_3d_idx = QLabel('ID:', self)
        self.__txt_box_3d_idx = QLineEdit(self)
        # add a button to save 3D images
        self.__btn_save_3d_img = QPushButton('Save Image', self)
        self.__btn_save_3d_img.setToolTip('Save 3D image to the file.')
        self.__btn_save_3d_img.clicked.connect(self.save_3d_image)
        # set the layout of the tab which holds the 3D cameras
        self.__tab3D.setLayout(self.__create_3d_cams_grid_layout())

    def __set_tab2d_layout(self):
        self.__lbl_2d_cam_1 = QLabel()
        self.__lbl_2d_cam_2 = QLabel()
        self.__lbl_2d_cam_3 = QLabel()
        self.__lbl_2d_cam_4 = QLabel()
        # add a label and a text box for input of the object id
        self.__lbl_2d_idx = QLabel('ID:', self)
        self.__txt_box_2d_idx = QLineEdit(self)
        # add a button to save 3D images
        self.__btn_save_2d_img = QPushButton('Save Image', self)
        self.__btn_save_2d_img.setToolTip('Save 2D image to the file.')
        self.__btn_save_2d_img.clicked.connect(self.save_2d_image)
        # set the layout of the tab which holds the 2D cameras
        self.__tab2D.setLayout(self.__create_2d_cams_grid_layout())

    def get_txt_box_2d_idx(self):
        return self.__txt_box_2d_idx

    def get_txt_box_3d_idx(self):
        return self.__txt_box_3d_idx

    def __run_movie(self):
        cam_counter = 0

        for pipe in pipelines:
            frame_set = pipe.wait_for_frames()

            # Wait for a coherent color frame
            # frames = None  # real_sense_cam.get_pipeline().wait_for_frames()
            # Align the depth frame to color frame
            aligned_frames = self.align.process(frame_set)

            depth_frame = aligned_frames.get_depth_frame()
            color_frame = aligned_frames.get_color_frame()
            color_image = np.asanyarray(color_frame.get_data())
            color_image = color_image.reshape((color_image.shape[0] * color_image.shape[1], 3))

            # self._colors.SetNumberOfTuples(color_image.shape[0])
            colors = vtk.vtkUnsignedCharArray()
            colors.SetNumberOfComponents(3)
            # colors.SetName("Colors")

            current_pd = vtk.vtkPolyData()
            self.pd_collection.append(current_pd)
            colors.SetArray(vtk_np.numpy_to_vtk(color_image), color_image.shape[0] * color_image.shape[1], 1)
            current_pd.GetPointData().SetScalars(colors)

            pc = rs.pointcloud()
            point_cloud = pc.calculate(depth_frame)
            pc.map_to(color_frame)
            v, t = point_cloud.get_vertices(), point_cloud.get_texture_coordinates()
            vertices = np.asanyarray(v).view(np.float32).reshape(-1, 3)  # xyz

            self._n_coordinates = vertices.shape[0]

            points = vtk.vtkPoints()
            cells = vtk.vtkCellArray()

            points.SetData(vtk_np.numpy_to_vtk(vertices))
            cells_npy = np.vstack([np.ones(self._n_coordinates, dtype=np.int64),
                                   np.arange(self._n_coordinates, dtype=np.int64)]).T.flatten()
            cells.SetCells(self._n_coordinates, vtk_np.numpy_to_vtkIdTypeArray(cells_npy))
            self.pd_collection[cam_counter].SetPoints(points)
            self.pd_collection[cam_counter].SetVerts(cells)

            mapper = vtk.vtkPolyDataMapper()
            self.mapper_collection.append(mapper)
            self.mapper_collection[cam_counter].SetInputData(self.pd_collection[cam_counter])

            transform = vtk.vtkTransform()
            transform.SetMatrix(flip_transform)

            actor = vtk.vtkActor()
            self.actor_collection.append(actor)
            self.actor_collection[cam_counter].SetMapper(self.mapper_collection[cam_counter])
            self.actor_collection[cam_counter].GetProperty().SetRepresentationToPoints()
            self.actor_collection[cam_counter].SetUserTransform(transform)

            current_ren = vtk.vtkRenderer()
            current_ren.GetActiveCamera()

            # set viewports if the number of cams ara greater than one
            if len(pipelines) > 1:
                current_ren.SetViewport(self.view_coordinates[cam_counter])
            current_ren.AddActor(self.actor_collection[cam_counter])
            self.__vtkWidget.GetRenderWindow().AddRenderer(current_ren)
            cam_counter += 1

        self.__iren.AddObserver('TimerEvent', self.update_poly_data)

        dt = 30  # ms
        self.__iren.CreateRepeatingTimer(dt)

    def update_poly_data(self, obj=None, event=None):
        cam_counter = 0
        rgb_cam_images = []

        for pipe in pipelines:
            frame_set = pipe.wait_for_frames()
            # Wait for a coherent color frame
            # frames = real_sense_cam.get_pipeline().wait_for_frames()
            # Align the depth frame to color frame
            aligned_frames = self.align.process(frame_set)

            depth_frame = aligned_frames.get_depth_frame()
            color_frame = aligned_frames.get_color_frame()

            pc = rs.pointcloud()

            point_cloud = pc.calculate(depth_frame)
            pc.map_to(color_frame)
            v, t = point_cloud.get_vertices(), point_cloud.get_texture_coordinates()
            vertices = np.asanyarray(v).view(np.float32).reshape(-1, 3)  # xyz

            color_image = np.asanyarray(color_frame.get_data())
            rgb_cam_images.append(np_color_img_to_q_image(color_image))
            color_image = color_image.reshape((color_image.shape[0] * color_image.shape[1], 3))

            colors = vtk.vtkUnsignedCharArray()
            colors.SetNumberOfComponents(3)

            colors.SetArray(vtk_np.numpy_to_vtk(color_image), color_image.shape[0] * color_image.shape[1], 1)
            self.pd_collection[cam_counter].GetPointData().SetScalars(colors)

            points = vtk.vtkPoints()
            cells = vtk.vtkCellArray()

            points.SetData(vtk_np.numpy_to_vtk(vertices))
            cells_npy = np.vstack([np.ones(self._n_coordinates, dtype=np.int64),
                                   np.arange(self._n_coordinates, dtype=np.int64)]).T.flatten()
            cells.SetCells(self._n_coordinates, vtk_np.numpy_to_vtkIdTypeArray(cells_npy))

            self.pd_collection[cam_counter].SetPoints(points)
            self.pd_collection[cam_counter].SetVerts(cells)
            self.pd_collection[cam_counter].Modified()
            cam_counter += 1

        self.frames_ready.emit(rgb_cam_images[0],
                               rgb_cam_images[1],
                               rgb_cam_images[2])

        self.__iren.GetRenderWindow().Render()
        # print(self.timer_count)
        self.timer_count += 1

    def __create_2d_cams_grid_layout(self):
        layout = QGridLayout()
        layout_idx = QHBoxLayout()
        layout_idx.addWidget(self.__lbl_2d_idx)
        layout_idx.addWidget(self.__txt_box_2d_idx)
        # add all widgets to the layout
        # add four labels of images, one for each camera
        layout.addWidget(self.__lbl_2d_cam_1, 0, 0, 1, 1)
        layout.addWidget(self.__lbl_2d_cam_2, 0, 1, 1, 1)
        layout.addWidget(self.__lbl_2d_cam_3, 1, 0, 1, 1)
        layout.addWidget(self.__lbl_2d_cam_4, 1, 1, 1, 1)
        # add a label and a text box to input the object id
        # layout.addWidget(self.__lbl_2d_idx, 2, 0, 1, 1)
        # layout.addWidget(self.__txt_box_2d_idx, 2, 1, 1, 1)
        layout.addLayout(layout_idx, 2, 0, 1, 2)
        # add a save button
        layout.addWidget(self.__btn_save_2d_img, 3, 0, 1, 2)
        # could we create a shared button to save all images at once?

        return layout

    def __create_3d_cams_grid_layout(self):
        layout = QGridLayout()

        layout.addWidget(self.__vtkWidget, 0, 0, 1, 2)
        # add a label and a text box to input the object id
        layout.addWidget(self.__lbl_3d_idx, 1, 0, 1, 1)
        layout.addWidget(self.__txt_box_3d_idx, 1, 1, 1, 1)
        # add a save button
        layout.addWidget(self.__btn_save_3d_img, 2, 0, 1, 2)

        return layout

    def timer_event(self):
        self.__iren.TimerEvent()

    def create_timer(self, obj, evt):
        self._timer.start(0)

    def destroy_timer(self, obj, evt):
        self._timer.stop()
        return 1

    def get_iren(self):
        return self.__iren

    @QtCore.pyqtSlot(QImage, QImage, QImage)
    def receive_frame(self, rgb_1, rgb_2, rgb_3):
        ratio = 1.
        p_cam1 = QPixmap.fromImage(rgb_1)
        p_cam2 = QPixmap.fromImage(rgb_2)
        p_cam3 = QPixmap.fromImage(rgb_3)
        # p_cam4 = QPixmap.fromImage(rgb_4)
        w_cam1, h_cam1 = p_cam1.width() * ratio, p_cam1.height() * ratio
        w_cam2, h_cam2 = p_cam1.width() * ratio, p_cam1.height() * ratio
        w_cam3, h_cam3 = p_cam1.width() * ratio, p_cam1.height() * ratio
        # w_cam4 = self.__lbl_2d_cam_1.width()
        # h_cam4 = self.__lbl_2d_cam_1.height()
        self.__lbl_2d_cam_1.setPixmap(p_cam1.scaled(h_cam1, w_cam1, PyQt5.QtCore.Qt.KeepAspectRatio))
        self.__lbl_2d_cam_2.setPixmap(p_cam2.scaled(h_cam1, w_cam1, PyQt5.QtCore.Qt.KeepAspectRatio))
        self.__lbl_2d_cam_3.setPixmap(p_cam3.scaled(h_cam1, w_cam1, PyQt5.QtCore.Qt.KeepAspectRatio))
        # self.__lbl_2d_cam_4.setPixmap(QPixmap.fromImage(rgb_4))

    def on_change(self, i):
        if i == 0:  # 3d tab
            self.__txt_box_3d_idx.setText(self.__txt_box_2d_idx.text())
        else:
            self.__txt_box_2d_idx.setText(self.__txt_box_3d_idx.text())
        #  QMessageBox.information(self,
        #                          "Tab Index Changed!",
        #                          "Current Tab Index: %d" % i)  # changed!

    def save_2d_image(self):
        cam_1_pixmap = self.__lbl_2d_cam_1.pixmap()
        cam_2_pixmap = self.__lbl_2d_cam_2.pixmap()
        cam_3_pixmap = self.__lbl_2d_cam_3.pixmap()
        # cam_4_pixmap = self.__lbl_2d_cam_4.pixmap()

        # set the correct path to save the images files
        cam_1_pixmap.save("")
        cam_2_pixmap.save("")
        cam_3_pixmap.save("")
        # cam_4_pixmap.save("")

    def save_3d_image(self):
        for i in range(nr_devices):
            writer = vtkXMLPolyDataWriter()
            path_cam = self.__path + serial_numbers[i] + "/3D/"
            path_exists = os.path.isdir(path_cam)
            today_str = datetime.now().strftime("%H:%M:%S.%f")

            if not path_exists:
                os.makedirs(path_cam)

            f_name = path_cam + self.__txt_box_3d_idx.text() + "_img_" + str(self.__counter) + "_" + today_str + ".vtp"

            writer.SetFileName(f_name)
            writer.SetInputData(self.pd_collection[i])
            writer.Write()

        self.__counter += 1
コード例 #5
0
ファイル: main.py プロジェクト: SebastianForsmark/DLSCA
class WidgetGallery(QDialog):
    def __init__(self, parent=None):
        super(WidgetGallery, self).__init__(parent)

        self.originalPalette = QApplication.palette()
        self.selectedString = "selected files:"  #String used to generate list of args for scripts
        self.resize(600, 500)  #Application default resolution

        # Initialize tab screen
        self.tabs = QTabWidget()
        self.tabs.blockSignals(True)
        self.createT1()
        self.createT2()
        self.createT3()
        self.tabs.addTab(self.T1, "HTTP GET")
        self.tabs.addTab(self.T2, "Tests")
        self.tabs.addTab(self.T3, "Utils")

        # Currently contains nothing, but it is the tof of the layout above tabs
        topLayout = QHBoxLayout()
        topLayout.addStretch(1)

        # Layout of the main program. Basically just the tabs.
        mainLayout = QVBoxLayout()
        mainLayout.addLayout(topLayout)
        mainLayout.addWidget(self.tabs)
        mainLayout.addStretch(1)

        # Window layout and header
        self.setLayout(mainLayout)
        self.tabs.blockSignals(
            False)  #This is used to prevent an error during startup
        self.setWindowTitle("Deep Learning SCA Tool")

        # Input argument handling
        if len(sys.argv) > 2:
            if sys.argv[1] == "-t":
                self.tabs.setCurrentIndex(1)
                temp = self.selectedString
                for i in sys.argv[2:]:
                    temp = temp + "\n" + i
                self.updateSelected(temp)
            elif sys.argv[1] == "-u":
                self.tabs.setCurrentIndex(2)
                temp = self.selectedString
                for i in sys.argv[2:]:
                    temp = temp + "\n" + i
                self.updateSelected(temp)

        if len(sys.argv) > 1:
            if sys.argv[1] not in ['-u', '-t']:
                self.tabs.setCurrentIndex(1)
                temp = self.selectedString
                for i in sys.argv[1:]:
                    temp = temp + "\n" + i
                self.updateSelected(temp)

#Naming convention atm: T = tab, #X = index starting from 1, L = left side
#So if something is createT1L it means create the left side of tab1...

    def createT1L(self):
        self.tab1 = QWidget()
        tab1Layout = QVBoxLayout(self)
        self.createBL()
        self.createBR()
        tab1Layout.addWidget(self.BL)
        tab1Layout.addWidget(self.BR)
        self.tab1.setLayout(tab1Layout)

#Not sure if there's a better way to do this since I want elements to be aligned.
#The block separation in this code represents GUI modules.
#Naming convention: t = tab, #X = index starting from 1, l = left side
#Naming convention: b = button, s = script, h = help
#Each widget has its own layout variable where if possible it has the same prefix

    def createT2L(self):
        self.tab2 = QWidget()
        t2lLayout = QVBoxLayout(self)

        t2b1Widget = QWidget()
        t2b1Layout = QHBoxLayout()
        tab2Button1 = QPushButton("Files")
        tab2Button1h = QPushButton("?")
        t2b1Layout.addWidget(tab2Button1, 40)
        t2b1Layout.addWidget(tab2Button1h, 1)
        t2b1Widget.setLayout(t2b1Layout)
        t2lLayout.addWidget(t2b1Widget)

        self.tab2TextWidget = QWidget()
        tab2TextLayout = QHBoxLayout()
        self.tab2.textEdit = QTextEdit()
        self.tab2.textEdit.setPlainText(self.selectedString)
        tab2Texth = QPushButton("?")
        tab2TextLayout.addWidget(self.tab2.textEdit, 40)
        tab2TextLayout.addWidget(tab2Texth, 1)
        self.tab2TextWidget.setLayout(tab2TextLayout)
        t2lLayout.addWidget(self.tab2TextWidget)

        t2dropdownWidget = QWidget()
        t2dropdownLayout = QHBoxLayout()
        t2dropdown = QComboBox()
        t2dropdown.addItem("Average Rank Test")
        t2dropdown.addItem("option 2 tbd")
        t2dropdown.addItem("option 3 tbd")
        t2dropdownh = QPushButton("?")
        t2dropdownLayout.addWidget(t2dropdown, 40)
        t2dropdownLayout.addWidget(t2dropdownh, 1)
        t2dropdownWidget.setLayout(t2dropdownLayout)
        t2lLayout.addWidget(t2dropdownWidget)

        #SELECTION GROUP 1
        t2Group1 = QWidget()
        t2Group1Layout = QVBoxLayout()

        t2interval = QWidget()
        t2intervalLayout = QHBoxLayout()
        traceInterval = QLineEdit('57:153')
        traceIntervalh = QPushButton("?")
        t2intervalLayout.addWidget(traceInterval, 40)
        t2intervalLayout.addWidget(traceIntervalh, 1)
        t2interval.setLayout(t2intervalLayout)
        t2Group1Layout.addWidget(t2interval)

        t2keybyte = QWidget()
        t2keybyteLayout = QHBoxLayout()
        keybytePos = QComboBox()
        #        keybytePos.addItem("Select Keybyte Position")
        keybytePos.addItem("0")
        keybytePos.addItem("1")
        keybytePos.addItem("2")
        keybytePos.addItem("3")
        keybytePos.addItem("4")
        keybytePos.addItem("5")
        keybytePos.addItem("6")
        keybytePos.addItem("7")
        keybytePos.addItem("8")
        keybytePos.addItem("9")
        keybytePos.addItem("A")
        keybytePos.addItem("B")
        keybytePos.addItem("C")
        keybytePos.addItem("D")
        keybytePos.addItem("E")
        keybytePos.addItem("F")
        keybytePosh = QPushButton("?")
        t2keybyteLayout.addWidget(keybytePos, 40)
        t2keybyteLayout.addWidget(keybytePosh, 1)
        t2keybyte.setLayout(t2keybyteLayout)
        t2Group1Layout.addWidget(t2keybyte)

        t2iter = QWidget()
        t2iterLayout = QHBoxLayout()
        numtraces = QLineEdit('50')
        numiter = QLineEdit('100')
        numiterh = QPushButton("?")
        t2iterLayout.addWidget(numtraces, 40)
        t2iterLayout.addWidget(numiter, 40)
        t2iterLayout.addWidget(numiterh, 1)
        t2iter.setLayout(t2iterLayout)
        t2Group1Layout.addWidget(t2iter)

        t2art = QWidget()
        t2artLayout = QHBoxLayout()
        art = QPushButton("run average rank test")
        arth = QPushButton("?")
        t2artLayout.addWidget(art, 40)
        t2artLayout.addWidget(arth, 1)
        t2art.setLayout(t2artLayout)
        t2Group1Layout.addWidget(t2art)

        t2Group1.setLayout(t2Group1Layout)
        t2lLayout.addWidget(t2Group1)
        self.tab2.setLayout(t2lLayout)

        #SELECTION GROUP 2
        t2Group2 = QWidget()
        t2ConfirmLayout = QHBoxLayout()
        tab2Confirm = QPushButton("Confirm")
        tab2Confirmh = QPushButton("?")
        t2ConfirmLayout.addWidget(tab2Confirm, 40)
        t2ConfirmLayout.addWidget(tab2Confirmh, 1)
        t2Group2.setLayout(t2ConfirmLayout)
        t2Group2.hide()
        t2lLayout.addWidget(t2Group2)

        #SELECTION GROUP 3
        t2Group3 = QWidget()
        t2HideLayout = QHBoxLayout()
        tab2Hide = QPushButton("Hide")
        tab2Hideh = QPushButton("?")
        t2HideLayout.addWidget(tab2Hide, 40)
        t2HideLayout.addWidget(tab2Hideh, 1)
        t2Group3.setLayout(t2HideLayout)
        t2Group3.hide()
        t2lLayout.addWidget(t2Group3)

        #A lot of local functions will be used as well as some "global" (bound to super) functions.
        #The following is a list of functions that will be used on buttons presses or text changes
        #Naming convention: info = update right hand side info column.
        def filebrowserinfo():
            info = "Browse for files to add to the list in the text editor. Trained models are of type .h5 while history files and raw results data are .npy."
            self.updateInfo(info, self.tabs.currentIndex())

        def selectedinfo():
            info = "This is an editable list of files currently selected. You can edit it by just deleting text. Never remove the first line and never enter non-file non-empty strings on a line."
            self.updateInfo(info, self.tabs.currentIndex())

        def dropdowninfo():
            info = "Use the dropdown menu to select which script to run on the selected files. It is up to you as the user to not make a mistake..."
            self.updateInfo(info, self.tabs.currentIndex())

        def artinfo():
            info = "Average rank test for selected models. More info to come."
            self.updateInfo(info, self.tabs.currentIndex())

        def confirminfo():
            info = "Placeholder."
            self.updateInfo(info, self.tabs.currentIndex())

        def intervalinfo():
            info = "Set the interval for the first keybyte position to correspond to your model's input size. Subsequent keybytes will be calculated from this."
            self.updateInfo(info, self.tabs.currentIndex())

        def keybyteinfo():
            info = "select which keybyte position to attack using selected models. Best success is typically attacking the same position as trained on."
            self.updateInfo(info, self.tabs.currentIndex())

        def iterinfo():
            info = "set the number of traces to plot and the number of test iterations to run for your average results. I recommend leaving them on default while trying to improve models."
            self.updateInfo(info, self.tabs.currentIndex())

        def textchanget2():
            temp = self.tab2.textEdit.toPlainText()
            self.updateSelected(temp,
                                ignore=1,
                                current=self.tabs.currentIndex())

        def clickedt2b1():
            self.openFileNamesDialog()

        def clickedConfirm():
            print(self.selectedString)

        def avgrank():
            traces = numtraces.text()
            iterations = numiter.text()
            interval = traceInterval.text()
            tracestart = re.search('(\d+):(\d+)', interval).group(1)
            traceend = re.search('(\d+):(\d+)', interval).group(2)
            keybytepos = keybytePos.currentIndex()
            alert = QMessageBox()
            alert.setText("choose trace file")
            alert.exec_()
            tracefile = self.openTracesDialog()
            if not tracefile: returng
            alert.setText("choose plaintext file")
            alert.exec_()
            ptfile = self.openTracesDialog()
            if not ptfile: return
            alert.setText(
                "currently the key is hardcoded to be [ 26, 206, 149, 113, 251,  46,  52, 156,   5, 162, 215,  87,  29, 47, 187, 236]. This may be changed to loading a key file instead in the future"
            )
            alert.exec_()
            models = self.splitter(self.selectedString)
            subprocess.call([
                'python', 'scripts/average_rank_test.py',
                str(traces),
                str(iterations),
                str(tracestart),
                str(traceend),
                str(keybytepos), tracefile, ptfile
            ] + models[1:])

        def selection(i):
            if i == 0:
                t2Group1.show()
                t2Group2.hide()
                t2Group3.hide()

            if i == 1:
                t2Group1.hide()
                t2Group2.show()
                t2Group3.hide()

            if i == 2:
                t2Group1.hide()
                t2Group2.hide()
                t2Group3.show()

#Actually bind the scripts to the buttons and textedits. This needs to be defined after the
#functions they will be used which is why they are hidden down here

        tab2Button1.clicked.connect(clickedt2b1)
        tab2Button1h.clicked.connect(filebrowserinfo)
        tab2Texth.clicked.connect(selectedinfo)
        t2dropdownh.clicked.connect(dropdowninfo)
        tab2Confirm.clicked.connect(clickedConfirm)
        tab2Confirmh.clicked.connect(confirminfo)
        traceIntervalh.clicked.connect(intervalinfo)
        keybytePosh.clicked.connect(keybyteinfo)
        numiterh.clicked.connect(iterinfo)
        art.clicked.connect(avgrank)
        arth.clicked.connect(artinfo)
        self.tab2.textEdit.textChanged.connect(textchanget2)
        t2dropdown.currentIndexChanged.connect(selection)

    def createT3L(self):
        self.tab3 = QWidget()
        t3lLayout = QVBoxLayout(self)

        t3b1Widget = QWidget()
        t3b1Layout = QHBoxLayout()
        tab3Button1 = QPushButton("Files")
        tab3Button1h = QPushButton("?")
        t3b1Layout.addWidget(tab3Button1, 40)
        t3b1Layout.addWidget(tab3Button1h, 1)
        t3b1Widget.setLayout(t3b1Layout)
        t3lLayout.addWidget(t3b1Widget)

        self.tab3TextWidget = QWidget()
        tab3TextLayout = QHBoxLayout()
        self.tab3.textEdit = QTextEdit()
        self.tab3.textEdit.setPlainText(self.selectedString)
        tab3Texth = QPushButton("?")
        tab3TextLayout.addWidget(self.tab3.textEdit, 40)
        tab3TextLayout.addWidget(tab3Texth, 1)
        self.tab3TextWidget.setLayout(tab3TextLayout)
        t3lLayout.addWidget(self.tab3TextWidget)

        t3dropdownWidget = QWidget()
        t3dropdownLayout = QHBoxLayout()
        t3dropdown = QComboBox()
        t3dropdown.addItem("Unzip .tar.zip traces")
        t3dropdown.addItem("Model Input Shape")
        t3dropdown.addItem("Model Summary")
        t3dropdown.addItem("Plot History Files")
        t3dropdown.addItem("Plot a trace")
        t3dropdownh = QPushButton("?")
        t3dropdownLayout.addWidget(t3dropdown, 40)
        t3dropdownLayout.addWidget(t3dropdownh, 1)
        t3dropdownWidget.setLayout(t3dropdownLayout)
        t3lLayout.addWidget(t3dropdownWidget)

        #SELECTION GROUP 1
        t3Group1 = QWidget()
        unzipperLayout = QHBoxLayout()
        unzipper = QPushButton("Unzip")
        unzipperh = QPushButton("?")
        unzipperLayout.addWidget(unzipper, 40)
        unzipperLayout.addWidget(unzipperh, 1)
        t3Group1.setLayout(unzipperLayout)
        t3lLayout.addWidget(t3Group1)

        #SELECTION GROUP 2
        t3Group2 = QWidget()
        inputShapeLayout = QHBoxLayout()
        inShape = QPushButton("Print Model Input Shapes")
        inShapeh = QPushButton("?")
        inputShapeLayout.addWidget(inShape, 40)
        inputShapeLayout.addWidget(inShapeh, 1)
        t3Group2.setLayout(inputShapeLayout)
        t3Group2.hide()
        t3lLayout.addWidget(t3Group2)

        #SELECTION GROUP 3
        t3Group3 = QWidget()
        summaryLayout = QHBoxLayout()
        modelSummary = QPushButton("Print Model Summary")
        modelSummaryh = QPushButton("?")
        summaryLayout.addWidget(modelSummary, 40)
        summaryLayout.addWidget(modelSummaryh, 1)
        t3Group3.setLayout(summaryLayout)
        t3Group3.hide()
        t3lLayout.addWidget(t3Group3)

        #SELECTION GROUP 4
        t3Group4 = QWidget()
        historyLayout = QHBoxLayout()
        plotHistory = QPushButton("Plot History Files")
        plotHistoryh = QPushButton("?")
        historyLayout.addWidget(plotHistory, 40)
        historyLayout.addWidget(plotHistoryh, 1)
        t3Group4.setLayout(historyLayout)
        t3Group4.hide()
        t3lLayout.addWidget(t3Group4)

        #SELECTION GROUP 5
        t3Group5 = QWidget()
        traceLayout = QHBoxLayout()
        plotTrace = QPushButton("Plot Trace")
        plotTraceh = QPushButton("?")
        traceLayout.addWidget(plotTrace, 40)
        traceLayout.addWidget(plotTraceh, 1)
        t3Group5.setLayout(traceLayout)
        t3Group5.hide()
        t3lLayout.addWidget(t3Group5)

        self.tab3.setLayout(t3lLayout)

        def textchanget3():
            temp = self.tab3.textEdit.toPlainText()
            self.updateSelected(temp,
                                ignore=2,
                                current=self.tabs.currentIndex())

        def clickedt3b1():
            self.openFileNamesDialog()

        def filebrowserinfo():
            info = "Browse for files to add to the list in the text editor. Trained models are of type .h5 while history files and raw results data are .npy."
            self.updateInfo(info, self.tabs.currentIndex())

        def selectedinfo():
            info = "This is an editable list of files currently selected. You can edit it by just deleting text. Never remove the first line and never enter non-file non-empty strings on a line."
            self.updateInfo(info, self.tabs.currentIndex())

        def dropdowninfo():
            info = "Use the dropdown menu to select which script to run on the selected files. It is up to you as the user to not make a mistake..."
            self.updateInfo(info, self.tabs.currentIndex())

        def unzipperinfo():
            info = "SEBASTIAN WRITE YOUR INFOR HERE!!!"
            self.updateInfo(info, self.tabs.currentIndex())

        def inshapeinfo():
            info = "A script for printing the input shape of all models selected."
            self.updateInfo(info, self.tabs.currentIndex())

        def summaryinfo():
            info = "A script for printing the model summary of all models selected."
            self.updateInfo(info, self.tabs.currentIndex())

        def historyinfo():
            info = "A script for plotting all selected history files from trained models. These should be .npz files."
            self.updateInfo(info, self.tabs.currentIndex())

        def traceinfo():
            info = "A script for plotting a randomly selected trace from each selected trace file. Make sure to only select trace files for this."
            self.updateInfo(info, self.tabs.currentIndex())

        def clickedConfirm():
            print(self.selectedString)

        def summary():
            args = self.splitter(self.selectedString)
            subprocess.call(['python', 'scripts/model_summary.py'] + args[1:])

        def inputshape():
            args = self.splitter(self.selectedString)
            subprocess.call(['python', 'scripts/input_shape.py'] + args[1:])

        def historyplotter():
            args = self.splitter(self.selectedString)
            subprocess.call(['python', 'scripts/plot_history.py'] + args[1:])

        def traceplot():
            args = self.splitter(self.selectedString)
            subprocess.call(['python', 'scripts/trace_plotter.py'] + args[1:])

        def selection(i):
            if i == 0:
                t3Group1.show()
                t3Group2.hide()
                t3Group3.hide()
                t3Group4.hide()
                t3Group5.hide()

            if i == 1:
                t3Group1.hide()
                t3Group2.show()
                t3Group3.hide()
                t3Group4.hide()
                t3Group5.hide()

            if i == 2:
                t3Group1.hide()
                t3Group2.hide()
                t3Group3.show()
                t3Group4.hide()
                t3Group5.hide()

            if i == 3:
                t3Group1.hide()
                t3Group2.hide()
                t3Group3.hide()
                t3Group4.show()
                t3Group5.hide()

            if i == 4:
                t3Group1.hide()
                t3Group2.hide()
                t3Group3.hide()
                t3Group4.hide()
                t3Group5.show()

        tab3Button1.clicked.connect(clickedt3b1)
        tab3Button1h.clicked.connect(filebrowserinfo)
        plotHistory.clicked.connect(historyplotter)
        t3dropdownh.clicked.connect(dropdowninfo)
        unzipper.clicked.connect(clickedConfirm)
        unzipperh.clicked.connect(unzipperinfo)
        inShape.clicked.connect(inputshape)
        inShapeh.clicked.connect(inshapeinfo)
        modelSummary.clicked.connect(summary)
        modelSummaryh.clicked.connect(summaryinfo)
        plotHistoryh.clicked.connect(historyinfo)
        plotTrace.clicked.connect(traceplot)
        plotTraceh.clicked.connect(traceinfo)
        tab3Texth.clicked.connect(selectedinfo)
        self.tab3.textEdit.textChanged.connect(textchanget3)
        t3dropdown.currentIndexChanged.connect(selection)

#The following three definitions are for right hand side of tabs, used for displaying info.

    def createT1R(self):
        self.T1R = QWidget()
        t1rLayout = QVBoxLayout(self)
        self.tab1info = QLabel()
        self.tab1info.setWordWrap(True)
        self.tab1info.setText("press the ? buttons to get more info")
        t1rLayout.addWidget(self.tab1info)
        self.T1R.setLayout(t1rLayout)

    def createT2R(self):
        self.T2R = QWidget()
        t2rLayout = QVBoxLayout(self)
        self.tab2info = QLabel()
        self.tab2info.setWordWrap(True)
        self.tab2info.setText("press the ? buttons to get more info")
        t2rLayout.addWidget(self.tab2info)
        self.T2R.setLayout(t2rLayout)

    def createT3R(self):
        self.T3R = QWidget()
        t3rLayout = QVBoxLayout(self)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum,
                                           QtWidgets.QSizePolicy.Minimum)
        sizePolicy.setHorizontalStretch(0)
        self.T3R.setSizePolicy(sizePolicy)
        self.tab3info = QLabel()
        self.tab3info.setWordWrap(True)
        self.tab3info.setText("press the ? buttons to get more info")
        t3rLayout.addWidget(self.tab3info)
        self.T3R.setLayout(t3rLayout)

#The actual tabs. Naming convention will have to be changed to be consistent later.
#These are basically just containers holding the two halves of each tab.

    def createT1(self):
        self.T1 = QGroupBox()
        t1Layout = QHBoxLayout()
        self.createT1L()
        self.createT1R()
        t1Layout.addWidget(self.tab1)
        t1Layout.addWidget(self.T1R)
        self.T1.setLayout(t1Layout)

    def createT2(self):
        self.T2 = QGroupBox()
        t2Layout = QHBoxLayout()
        self.createT2L()
        self.createT2R()
        self.T2R.setMaximumWidth(100)
        t2Layout.addWidget(self.tab2)
        t2Layout.addWidget(self.T2R)
        self.T2.setLayout(t2Layout)

    def createT3(self):
        self.T3 = QGroupBox()
        t3Layout = QHBoxLayout()
        self.createT3L()
        self.createT3R()
        self.T3R.setMaximumWidth(100)
        t3Layout.addWidget(self.tab3)
        t3Layout.addWidget(self.T3R)
        self.T3.setLayout(t3Layout)

#This will be changed later. The first draft of this program used quadrants for its design.
#This was the old Bottom Right quadrant. Will be changed to use same design as t2 and t3.

    def createBL(self):
        self.BL = QGroupBox("Results")
        self.BL.textEdit = QTextEdit()
        self.BL.textEdit.setPlainText("waiting for results...")
        mylayout = QGridLayout()
        mylayout.addWidget(self.BL.textEdit, 0, 0, 1, 2)
        mylayout.setRowStretch(5, 1)
        self.BL.setLayout(mylayout)

    def createBR(self):
        self.BR = QGroupBox("IP address/URL")
        self.BR.lineEdit = QLineEdit('0.0.0.0')
        confirmIPButton = QPushButton("Confirm")

        def on_button_clicked():
            globalIP = self.BR.lineEdit.text()
            r = requests.get(globalIP)
            self.BL.textEdit.setPlainText('HEADER:\n\n' + str(r.headers) +
                                          '\n\nCONTENT:\n\n' + str(r.content))
            alert = QMessageBox()
            alert.setText(str(r.status_code))
            alert.exec_()

        confirmIPButton.clicked.connect(on_button_clicked)

        layout = QGridLayout()
        layout.addWidget(self.BR.lineEdit, 0, 0, 1, 2)
        layout.addWidget(confirmIPButton, 1, 0, 1, 2)
        layout.setRowStretch(5, 1)
        self.BR.setLayout(layout)

#File browser used to load files if you didn't use the terminal for that.

    def openFileNamesDialog(self):
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        files, _ = QFileDialog.getOpenFileNames(
            self,
            "QFileDialog.getOpenFileNames()",
            "",
            "All Files (*);;Model Files (*.h5);;Numpy Arrays (*.npy);;Numpy Zipfiles (*.npz)",
            options=options)
        if files:
            temp = self.selectedString
            for i in files:
                temp = temp + "\n" + i
            self.updateSelected(temp)

    def openTracesDialog(self):
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        fileName, _ = QFileDialog.getOpenFileName(
            self,
            "QFileDialog.getOpenFileName()",
            "",
            "Numpy Arrays (*.npy)",
            options=options)
        if fileName:
            return fileName
        else:
            return False

#Updates and synchronizes the loaded file lists on t2 and t3.
#The conditionals prevent infinite recursion.

    def updateSelected(self, newSelected, ignore=0, current=0):
        self.selectedString = newSelected
        if ignore is not 1:
            if current is not 1:
                self.tab2.textEdit.setPlainText(self.selectedString)
        if ignore is not 2:
            if current is not 2:
                self.tab3.textEdit.setPlainText(self.selectedString)

#Update the right hand side info bar with whatever query the user clicked.

    def updateInfo(self, info, tabnumber):
        if tabnumber == 0:
            self.tab1info.setText(info)

        if tabnumber == 1:
            self.tab2info.setText(info)

        if tabnumber == 2:
            self.tab3info.setText(info)

#I don't think this is used anymore? Probably old debugging thing.
#Will be removed if it turns out it is useless.

    def tabSwitch(self):
        print(str(self.tabs.currentIndex()))
        if self.tabs.currentIndex() is not 0:
            if self.tabs.currentIndex() == 1:
                temp = self.tab2.textEdit.toPlainText()
                self.updateSelected(temp)
            if self.tabs.currentIndex() == 2:
                temp = self.tab3.textEdit.toPlainText()
                self.updateSelected(temp)
        self.updateSelected(self.selectedString)


#Script for splitting the string stored in the text edit into a list strings
#to send as args for the linked scripts

    def splitter(self, s):
        return [line.strip() for line in s.splitlines() if line.strip()]
コード例 #6
0
ファイル: tabdocker.py プロジェクト: MPI-Dortmund/transphire
class TabDocker(QWidget):
    """
    Tab widget for the settingswidgets.

    Inherits:
    QWidget
    """
    sig_start_plot = pyqtSignal()
    latest_active = [None]

    def __init__(self, parent=None, **kwargs):
        """
        Initialise layout for TabDocker

        Arguments:
        parent - Parent widget (default None)

        Return:
        None
        """
        super(TabDocker, self).__init__(parent)
        self.parent = parent
        try:
            self.layout = kwargs['layout']
        except KeyError:
            self.layout = None
        try:
            self.name = kwargs['name']
        except KeyError:
            self.name = None
        self.widgets = []

        layout_tmp = QVBoxLayout(self)
        self.parent_widget = QWidget(self)
        layout_tmp.addWidget(self.parent_widget)
        layout_tmp.setContentsMargins(0, 0, 0, 0)

        layout = QVBoxLayout(self.parent_widget)
        layout.setContentsMargins(0, 0, 0, 0)
        self.tab_widget = QTabWidget(self)
        if self.layout in ('TAB1', 'Settings'):
            tab_bar = MyTabBar(self.tab_widget)
            tab_bar.setObjectName('vertical')
            self.tab_widget.setObjectName('vertical')
            self.tab_widget.setTabBar(tab_bar)
            self.tab_widget.setTabPosition(QTabWidget.West)
        layout.addWidget(self.tab_widget)

        self.tab_widget.currentChanged.connect(self.assign_latest)

    @pyqtSlot(int)
    def assign_latest(self, idx):
        current_name = self.tab_widget.tabText(idx)
        try:
            parent_content = self.parent.content[self.layout].name
        except AttributeError:  # Exception for the Default settings dialog
            parent_content = False
        except TypeError:  # Exception for the Default settings dialog
            parent_content = False
        except KeyError:  # Exception for the main window dialog
            parent_content = False

        check_list = (parent_content, self.name, current_name)

        latest_active = self
        for list_idx, entry in enumerate(check_list):
            if entry == 'Visualisation':
                cur_tab_widget = self.tab_widget.widget(idx)
                try:
                    for i in range(list_idx):
                        idx = cur_tab_widget.currentIndex()
                        cur_tab_widget = cur_tab_widget.widget(idx)
                    latest_active = cur_tab_widget if cur_tab_widget is not None else self
                except:
                    latest_active = self
                break
        if self.latest_active[0] != latest_active:
            self.latest_active[0] = latest_active
            latest_active.sig_start_plot.emit()

    def setCurrentIndex(self, idx):
        """
        Set the current Index of the tab_widget.

        Arguments:
        idx - Index to set

        Returns: Current index of self.tab_widget
        """
        return self.tab_widget.setCurrentIndex(idx)

    def setCurrentWidget(self, widget):
        """
        Set the current widget of the tab_widget.

        Arguments:
        idx - Widget to set

        Returns: Current index of self.tab_widget
        """
        return self.tab_widget.setCurrentWidget(widget)

    def currentIndex(self):
        """
        Get the current Index of the tab_widget.

        Returns: Current index of self.tab_widget
        """
        return self.tab_widget.currentIndex()

    def add_tab(self, widget, name, add_widgets=True):
        """
        Add a new tab to the TabDocker

        Arguments:
        widget - Widget to add
        name - Name of the widget

        Return:
        None
        """
        if isinstance(widget, TabDocker):
            widget.parent_widget.setObjectName('tab')
        else:
            pass
        current_state = self.tab_widget.blockSignals(True)
        index = self.tab_widget.addTab(widget, name)
        if add_widgets:
            self.widgets.append(widget)
        self.tab_widget.blockSignals(current_state)
        self.tab_widget.setTabToolTip(index, name)

    def count(self):
        """
        Return the number of tabs.

        Arguments:
        None

        Returns:
        Number of tabs
        """
        return self.tab_widget.count()

    def widget(self, idx):
        """
        Return the widget that belongs to the idx of tabs.

        Arguments:
        idx - Tab index

        Returns:
        Widget
        """
        return self.tab_widget.widget(idx)

    def setMovable(self, status):
        """
        Set the movable status for the tab widgets

        Arguments:
        status - Boolean variable for the status

        Returns:
        None
        """
        return self.tab_widget.setMovable(status)

    def tabText(self, idx):
        """
        Return the text of the tab at idx

        Arguments:
        idx - Index of the tab

        Returns:
        Text of the tab at position isx
        """
        return self.tab_widget.tabText(idx)

    def setTabText(self, idx, text):
        """
        Set the text for the tab at idx

        Arguments:
        idx - Index of the tab
        text - Text of the tab

        Returns:
        None
        """
        return self.tab_widget.setTabText(idx, text)

    def removeTab(self, idx):
        """
        Remove the widget located at tab idx

        Arguments:
        idx - Idx of the widget

        Returns:
        None
        """
        current_state = self.tab_widget.blockSignals(True)
        idx = self.tab_widget.removeTab(idx)
        self.tab_widget.blockSignals(current_state)
        return idx

    def indexOf(self, widget):
        """
        Get the index of the widget.

        Arguments:
        widget - Adress of the widget

        Returns:
        Index of the widget
        """
        return self.tab_widget.indexOf(widget)

    def setTabPosition(self, position):
        """
        Set the tab position of the Tab bar

        Arguments:
        position - Tab position as string ['North', 'East', 'West', 'South']

        Returns:
        None
        """
        tab_position_dict = {
            'North': QTabWidget.North,
            'South': QTabWidget.South,
            'West': QTabWidget.West,
            'East': QTabWidget.East,
        }
        self.tab_widget.setTabPosition(tab_position_dict[position])

    def setTabEnabled(self, index, state):
        """
        Set the tab position index to the enable state.

        Arguments:
        index - Tab position index
        state - State (True or False)

        Returns:
        None
        """
        self.tab_widget.setTabEnabled(index, state)

    def order_tabs(self):
        current_state = self.tab_widget.blockSignals(True)
        widget_tuple = tuple([(self.widget(idx).name, self.widget(idx),
                               self.tab_widget.isTabEnabled(idx))
                              for idx in range(self.count())])
        for idx in reversed(range(self.count())):
            self.removeTab(idx)

        for idx, (name, widget, state) in enumerate(sorted(widget_tuple)):
            self.add_tab(widget, name, add_widgets=False)
            self.setTabEnabled(idx, state)
            if state:
                self.setCurrentIndex(idx)
        self.tab_widget.blockSignals(current_state)

    def enable_tab(self, visible):
        """
        Enable or disable the tab.


        Arguments:
        visible - Enable if True, Disable if False
        name - Name of the tab to disable.

        Returns:
        None
        """
        index = self.parent.content[self.layout].indexOf(self)
        if not visible:
            self.parent.content[self.layout].removeTab(index)
        else:
            self.parent.content[self.layout].add_tab(self, self.name)
            self.parent.content[self.layout].order_tabs()
コード例 #7
0
class TfrmBase(QMainWindow, TScreenStates):

    recordCount = 0

    def __init__(self, parent=None):
        super(TfrmBase, self).__init__()

        self.FOnStateChange = self.onStateChange
        self.activeState = self.ssInactive
        self._defaultSettings()
        self._createWidgets()
        self._setEvents()

    def _defaultSettings(self):
        self.setObjectName("frmBase")
        self.resize(640, 480)
        self.setMinimumSize(QSize(640, 480))

    def _createWidgets(self):
        self._createLayout()
        self._createMenus()
        self._createToolBar()
        self._createStatusBar()
        self._createPages()
        self._setLayouts()

    def _createLayout(self):
        self.clientArea = QWidget()
        self.clientArea.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding))
        self.clientArea.setMinimumSize(QSize(640, 400))
        self.clientArea.setBaseSize(QSize(640, 400))
        self.clientArea.setLayoutDirection(Qt.LeftToRight)
        self.clientArea.setObjectName("clientArea")
        self.gridLayout = QGridLayout(self.clientArea)
        self.gridLayout.setContentsMargins(0, 0, 0, 0)
        self.gridLayout.setSpacing(0)
        self.gridLayout.setObjectName("gridLayout")

    def _createMenus(self):
        # Create a Menu Bar
        self.mnMenu = self.menuBar()
        self.mnMenu.setObjectName("mnMenu")
        # Create all Top Menus
        self.mnApp = QMenu('&Aplicação')
        self.mnApp.setObjectName('mnApp')
        self.mnOpe = QMenu('&Operação')
        self.mnOpe.setObjectName("mnOperations")
        self.mnNav = QMenu('&Navegação')
        self.mnNav.setObjectName("mnNav")
        # Set Menus to MenuBar
        self.mnMenu.addMenu(self.mnNav)
        self.mnMenu.addMenu(self.mnOpe)
        self.mnMenu.addMenu(self.mnApp)
        # Crealte all Actions to Application Menu
        self._createAppActions()
        self._createOpeActions()
        self._setMenuActions()
        self.mnMenu.addAction(self.mnApp.menuAction())
        self.mnMenu.addAction(self.mnOpe.menuAction())
        self.mnMenu.addAction(self.mnNav.menuAction())
        self._settingActionsEvents()

    def _createAppActions(self):
        # Exit Program Action
        self.acExit = QAction(
            self.getIcon("./resources/exit.ico", QSize(32, 32)), '&Sair')
        self.acExit.setObjectName("acExit")
        self.acExit.setShortcut('Ctrl+Q')
        self.acExit.setStatusTip('Finalizar o Programa')
        self.acExit.triggered.connect(self.closeApp)

    def _createOpeActions(self):
        # Search Action
        self.acSearch = QAction(
            self.getIcon("./resources/Search.ico", QSize(32, 32)),
            '&Pesquisar')
        self.acSearch.setObjectName("acSearch")
        self.acSearch.setShortcut('F5,Ctrl+P')
        self.acSearch.setStatusTip(
            'Preenche o Filtro para Selecionar Registros')
        # List Action
        self.acList = QAction(
            self.getIcon("./resources/list.ico", QSize(32, 32)), '&Listar')
        self.acList.setShortcut('Ctrl+L')
        self.acList.setStatusTip('Listar todos os Registros')
        self.acList.setObjectName("acList")
        # Insert Action
        self.acInsert = QAction(
            self.getIcon("./resources/db_add.ico", QSize(32, 32)), '&Inserir')
        self.acInsert.setShortcut('F2,Ins')
        self.acInsert.setStatusTip('Incluir Novo Registros')
        self.acInsert.setObjectName("acInsert")
        # Update Action
        self.acUpdate = QAction(
            self.getIcon("./resources/db_update.ico", QSize(32, 32)),
            '&Editar')
        self.acUpdate.setShortcut('Ctrl+U')
        self.acUpdate.setStatusTip('Editar o Registro Atual')
        self.acUpdate.setObjectName("acUpdate")
        # Delete Action
        self.acDelete = QAction(
            self.getIcon("./resources/db_remove.ico", QSize(32, 32)),
            '&Excluir')
        self.acDelete.setShortcut('Ctrl+Del')
        self.acDelete.setStatusTip('Exclui o Registro Atual')
        self.acDelete.setObjectName("acDelete")
        # Save Action
        self.acSave = QAction(
            self.getIcon("./resources/db_commit.ico", QSize(32, 32)),
            '&Salvar')
        self.acSave.setShortcut('F10,Ctrl+S')
        self.acSave.setStatusTip('Salva as Alterações do Registro')
        self.acSave.setObjectName("acSave")
        # Cancel Action
        self.acCancel = QAction(
            self.getIcon("./resources/cancel.ico", QSize(32, 32)), '&Cancelar')
        self.acCancel.setShortcut('Esc')
        self.acCancel.setStatusTip('Cancela as Alterações do Registro')
        self.acCancel.setObjectName("acCancel")
        # First Action
        self.acFirst = QAction(
            self.getIcon("./resources/start.ico", QSize(32, 32)), '&Início')
        self.acFirst.setShortcut('Ctrl+Left')
        self.acFirst.setStatusTip('Vai para o Primeiro Registro')
        self.acFirst.setObjectName("acFirst")
        # Prior Action
        self.acPrior = QAction(
            self.getIcon("./resources/left.ico", QSize(32, 32)), '&Anterior')
        self.acPrior.setShortcut('Left')
        self.acPrior.setStatusTip('Vai para o Registro Anterior')
        self.acPrior.setObjectName("acPrior")
        # Next Action
        self.acNext = QAction(
            self.getIcon("./resources/right.ico", QSize(32, 32)), '&Próximo')
        self.acNext.setShortcut('Right')
        self.acNext.setStatusTip('Vai para o Próximo Registro')
        self.acNext.setObjectName("acNext")
        # Last Action
        self.acLast = QAction(
            self.getIcon("./resources/end.ico", QSize(32, 32)), '&Último')
        self.acLast.setShortcut('Ctrl+Right')
        self.acLast.setStatusTip('Vai para o Último Registro')
        self.acLast.setObjectName("acLast")
        # Form Title Action
        self.dcTitle = QAction()
        font = QFont()
        font.setPointSize(14)
        font.setBold(True)
        font.setWeight(75)
        self.dcTitle.setFont(font)
        self.dcTitle.setObjectName("dcTitle")

    def getIcon(self, res: str, size: QSize) -> QIcon:
        icon = QIcon()
        icon.addPixmap(
            QPixmap(res).scaled(size.width(), size.height(),
                                Qt.KeepAspectRatio), QIcon.Active, QIcon.On)
        return icon

    def _setMenuActions(self):
        # Set Menu Application Actions
        self.mnApp.addAction(self.acExit)
        # Set Menu Operations Actions
        self.mnOpe.addAction(self.acSearch)
        self.mnOpe.addAction(self.acList)
        self.mnOpe.addSeparator()
        self.mnOpe.addAction(self.acInsert)
        self.mnOpe.addAction(self.acUpdate)
        self.mnOpe.addAction(self.acDelete)
        self.mnOpe.addSeparator()
        self.mnOpe.addAction(self.acSave)
        self.mnOpe.addAction(self.acCancel)
        # Set Menu Navigation Actions
        self.mnNav.addAction(self.acFirst)
        self.mnNav.addAction(self.acPrior)
        self.mnNav.addAction(self.acNext)
        self.mnNav.addAction(self.acLast)

    def _settingActionsEvents(self):
        # Set Menu Operations Trigger onClick
        self.acSearch.triggered.connect(
            lambda: self.setFormStatus(self.ssSearch))
        self.acList.triggered.connect(
            lambda: self.setFormStatus(self.ssSearchAll))
        self.acInsert.triggered.connect(
            lambda: self.setFormStatus(self.ssInsert))
        self.acUpdate.triggered.connect(
            lambda: self.setFormStatus(self.ssUpdate))
        self.acDelete.triggered.connect(
            lambda: self.setFormStatus(self.ssDelete))
        self.acSave.triggered.connect(lambda: self.setFormStatus(self.ssPost))
        self.acCancel.triggered.connect(
            lambda: self.setFormStatus(self.ssCancel))
        # Set Menu Navigation Trigger onClick
        self.acFirst.triggered.connect(
            lambda: self.setFormStatus(self.ssFirst))
        self.acPrior.triggered.connect(
            lambda: self.setFormStatus(self.ssPrior))
        self.acNext.triggered.connect(lambda: self.setFormStatus(self.ssNext))
        self.acLast.triggered.connect(lambda: self.setFormStatus(self.ssLast))

    def _createToolBar(self):
        # Create a tbActions ToolBar
        self.tbActions = QToolBar()
        self.tbActions.setMinimumSize(QSize(300, 34))
        self.tbActions.setMaximumSize(QSize(16777215, 34))
        self.tbActions.setBaseSize(QSize(300, 34))
        self.tbActions.setAcceptDrops(False)
        self.tbActions.setToolTipDuration(3)
        self.tbActions.setAllowedAreas(Qt.TopToolBarArea)
        self.tbActions.setObjectName("tbActions")
        self.addToolBar(Qt.TopToolBarArea, self.tbActions)
        # Create a tbTitle ToolBar
        self.tbTitle = QToolBar()
        self.tbTitle.setMinimumSize(QSize(340, 34))
        self.tbTitle.setMaximumSize(QSize(16777215, 34))
        self.tbTitle.setBaseSize(QSize(341, 34))
        self.tbTitle.setAllowedAreas(Qt.TopToolBarArea)
        self.tbTitle.setToolButtonStyle(Qt.ToolButtonTextOnly)
        self.tbTitle.setFloatable(False)
        self.tbTitle.setObjectName("tbTitle")
        # self.tbTitle.setLabelAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
        self.addToolBar(Qt.TopToolBarArea, self.tbTitle)
        # Call Add Actions to ToolBar
        self._setToolBarActions()

    def _setToolBarActions(self):
        # Set ToolBar Actions
        self.tbActions.addAction(self.acSearch)
        self.tbActions.addAction(self.acInsert)
        self.tbActions.addAction(self.acUpdate)
        self.tbActions.addAction(self.acDelete)
        self.tbActions.addSeparator()
        self.tbActions.addAction(self.acSave)
        self.tbActions.addAction(self.acExit)
        self.tbTitle.addAction(self.dcTitle)

    def _createStatusBar(self):
        self.sbStatus = QStatusBar()
        self.sbStatus.setMaximumHeight(24)
        self.sbStatus.setObjectName("sbStatus")
        self.sbStatus.setStyleSheet("""
            .QLabel {
                background-color: #FFFFFF;
                color: #000000;
            }
        """)
        self.lbStatus = QLabel(self.sbStatus)
        self.lbStatus.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
        self.lbStatus.setText('Inactive')
        self.lbStatus.setMinimumSize(QSize(130, 15))
        self.lbStatus.setFrameShape(QFrame.Panel)
        self.lbStatus.setFrameShadow(QFrame.Sunken)
        self.sbStatus.addPermanentWidget(self.lbStatus)
        self.setStatusBar(self.sbStatus)

    def _createPages(self):
        self.tabMain = QTabWidget(self.clientArea)
        self.tabMain.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding))
        self.tabMain.setTabPosition(QTabWidget.South)
        self.tabMain.setObjectName("tabMain")
        self.pgList = QWidget(self.tabMain)
        self.pgList.setObjectName("pgList")
        self.pgDetail = QWidget(self.tabMain)
        self.pgDetail.setObjectName("pgDetail")
        self.tabMain.addTab(self.pgList, "")
        self.tabMain.addTab(self.pgDetail, "")
        self._createPageListContent()

    def _createPageListContent(self):
        self.treeWidget = QTreeWidget(self.pgList)
        self.treeWidget.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding))
        self.treeWidget.setFrameShape(QFrame.NoFrame)
        self.treeWidget.setFrameShadow(QFrame.Plain)
        self.treeWidget.setColumnCount(3)
        self.treeWidget.setObjectName("treeWidget")
        self.treeWidget.headerItem().setText(0, "Campo")
        self.treeWidget.headerItem().setText(1, "Campo")
        self.treeWidget.headerItem().setText(2, "Campo")
        self.treeWidget.setGeometry(QRect(0, 0, 640, 370))
        self.treeWidget.setMinimumSize(QSize(640, 370))
        self.tabMain.setCurrentIndex(0)

    def _setLayouts(self):
        self.gridLayout.addWidget(self.tabMain, 0,
                                  Qt.AlignBottom | Qt.AlignRight, 1, 1)
        self.setCentralWidget(self.clientArea)

    def translateForm(self):
        self._translate = QCoreApplication.translate
        self.setWindowTitle(
            self._translate("TfrmBase", "Tela de Básica de Cadastros"))
        self.mnApp.setTitle(self._translate("TfrmBase", "Aplicação"))
        self.mnOpe.setTitle(self._translate("TfrmBase", "Operações"))
        self.mnNav.setTitle(self._translate("TfrmBase", "Navegação"))
        self.sbStatus.setToolTip(self._translate("TfrmBase",
                                                 "Barra de Status"))
        self.tbActions.setWindowTitle(
            self._translate("TfrmBase", "Ferramentas"))
        self.tbActions.setToolTip(
            self._translate("TfrmBase", "Barra de Ferramentas"))
        self.tbTitle.setWindowTitle(self._translate("TfrmBase", "Descrição"))
        self.acExit.setText(self._translate("TfrmBase", "&Sair"))
        self.acExit.setToolTip(self._translate("TfrmBase", "Sair do Programa"))
        self.acSearch.setText(self._translate("TfrmBase", "&Pesquisar"))
        self.acSearch.setStatusTip(
            self._translate("TfrmBase", "Procurar Por um Registro"))
        self.acList.setText(self._translate("TfrmBase", "&Listar Todos"))
        self.acList.setStatusTip(
            self._translate("TfrmBase", "Lista todos os Registros"))
        self.acInsert.setText(self._translate("TfrmBase", "&Inserir"))
        self.acInsert.setStatusTip(
            self._translate("TfrmBase", "Adicionar Registro"))
        self.acUpdate.setText(self._translate("TfrmBase", "&Editar"))
        self.acUpdate.setStatusTip(
            self._translate("TfrmBase", "Editar Registro"))
        self.acDelete.setText(self._translate("TfrmBase", "E&xcluir"))
        self.acDelete.setStatusTip(
            self._translate("TfrmBase", "Excluir Registro"))
        self.acSave.setText(self._translate("TfrmBase", "&Salvar"))
        self.acSave.setToolTip(self._translate("TfrmBase", "Salvar Registro"))
        self.acCancel.setText(self._translate("TfrmBase", "&Cancelar"))
        self.acCancel.setToolTip(
            self._translate("TfrmBase", "Cencelar Alterações"))
        self.dcTitle.setText(
            self._translate("TfrmBase", "Título da Tela de Cadastros"))
        self.dcTitle.setToolTip(
            self._translate("TfrmBase", "Título da Tela de Cadastros"))
        self.tabMain.setTabText(
            self.tabMain.indexOf(self.pgList),
            self._translate("TfrmBase", "Lista dos Registros"))
        self.tabMain.setTabToolTip(
            self.tabMain.indexOf(self.pgList),
            self._translate("TfrmBase", "Listagem das Ferramentas"))
        self.tabMain.setTabText(
            self.tabMain.indexOf(self.pgDetail),
            self._translate("TfrmBase", "Detalhes do Registro Selecionando"))

    @property
    def activeState(self):
        return self._activeValue

    @property
    def activeStateColor(self):
        return self.activeValue['FG']

    @property
    def activeStateBackgroud(self):
        return self.activeValue['BG']

    @activeState.setter  # Seta a Propriedade _activeState
    def activeState(self, value: int):
        self.workValue = value
        self._activeState = value

    def setScreenState(self, stt: int):
        self.acExit.setEnabled(self.inBrowse(stt))
        # Set Menu Operations Actions
        self.acSearch.setEnabled((self.inBrowse(stt)
                                  or (self.recordCount == 0)))
        self.acList.setEnabled((self.inBrowse(stt) or (self.recordCount == 0)))
        self.acInsert.setEnabled(self.inBrowse(stt))
        self.acUpdate.setEnabled((self.inBrowse(stt)
                                  and (self.recordCount > 0)))
        self.acDelete.setEnabled((self.inBrowse(stt)
                                  and (self.recordCount > 0)))
        self.acSave.setEnabled(self.inUpdate(stt))
        self.acCancel.setEnabled(self.inUpdate(stt))
        # Set Menu Navigation Actions
        self.acFirst.setEnabled((self.inBrowse(stt)
                                 and (self.recordCount > 0)))
        self.acPrior.setEnabled((self.inBrowse(stt)
                                 and (self.recordCount > 0)))
        self.acNext.setEnabled((self.inBrowse(stt) and (self.recordCount > 0)))
        self.acLast.setEnabled((self.inBrowse(stt) and (self.recordCount > 0)))
        # Set tab Main if state in Browse enabled
        self.tabMain.setEnabled(self.inBrowse(stt))

    def _layoutWidgets(self):
        return (self.frmLayout.itemAt(i)
                for i in range(self.frmLayout.count()))

    def _getAllFields(self):
        arrFields = []
        for w in self._layoutWidgets():
            if (not (isinstance(w, QLabel))):
                arrFields.append(w)
        return arrFields

    def setEnableFields(self, enable: bool = True):
        # Enable All Fields
        for controls in self._layoutWidgets():
            QWidget(controls).setEnabled(enable)

    def clearFields(self):
        # cliar content of all fileds
        for controls in self._getAllFields():
            QWidget(controls).setText('')

    def setColorFields(self):
        # cliar content of all fileds
        style = ".QWidget { backgroud-color: " + self.activeStateBackgroud + "; }"
        for controls in self._getAllFields():
            QWidget(controls).setStyle(style)

    def showDataDetails(self):
        # move data of selected record to fileds
        if (self.tabMain.currentIndex() == 0):
            self.tabMain.setCurrentIndex(1)

    def filterRecord(self):
        raise NotImplementedError(500)

    def getFirstRecord(self):
        raise NotImplementedError(500)

    def getPriorRecord(self):
        raise NotImplementedError(500)

    def getNextRecord(self):
        raise NotImplementedError(500)

    def getLastRecord(self):
        raise NotImplementedError(500)

    def insertRecord(self):
        raise NotImplementedError(500)

    def deleteRecord(self):
        raise NotImplementedError(500)

    def updateRecord(self):
        raise NotImplementedError(500)

    def postRecord(self):
        raise NotImplementedError(500)

    def execOpertations(self, state: int):
        if ((state == self.ssFilter) or (state == self.ssSearchAll)):
            self.filterRecord()
        elif (state == self.ssFirst):
            self.getFirstRecord()
        elif (state == self.ssPrior):
            self.getPriorRecord()
        elif (state == self.ssNext):
            self.getNextRecord()
        elif (state == self.ssLast):
            self.getLastRecord()
        elif (state == self.ssInsert):
            self.insertRecord()
        elif (state == self.ssDelete):
            self.deleteRecord()
        elif (state == self.ssUpdate):
            self.updateRecord()
        elif (state == self.ssPost):
            self.postRecord()
        else:
            raise NotImplementedError(401, 'Operação não suportada')

    @pyqtSlot(int)
    def setFormStatus(self, state: int):
        if ((state == self.ssSearch) and (self.activeState != state)):
            self.clearFields()
            self.setColorFields()
            self.showDataDetails()

        if (self.activeState != state):
            self.activeState = state
            if (state == self.ssCancel):
                self.activeState = self.ssBrowse

    @pyqtSlot(int, int, dict, str)
    def onStateChange(self,
                      NewState: int,
                      OldState: int,
                      Result: dict = {},
                      Err: str = ''):
        try:
            # show screen state on status bar
            state = self.getStateProperties(NewState)
            style = '.QLabel { background-color: ' + state[
                'BG'] + '; color: ' + state['FG'] + '; }'
            self.sbStatus.setStyleSheet(style)
            self.lbStatus.setText(state['Descr'])

            # call operation into child screen
            self.execOpertations(NewState)
            # change buttons states
            self.setScreenState(NewState)
            # set result status code and result satatus Message
            self.setResultStatusCode = 200
            self.setResultStatusMessage = ''
        except Exception as e:
            self.ResultStatusCode = 200
            self.ResultStatusMessage = str(e)
            QMessageBox.critical(self, self.windowTitle(),
                                 self.ResultStatusMessage)
        return self.result

    @pyqtSlot()
    def tabMainChanged(self):
        self.sbStatus.showMessage('TabMain change tabIndex to (' +
                                  str(self.tabMain.currentIndex()) + ')!')
        if (self.tabMain.currentIndex() == 1):
            self.showDataDetails()

    @pyqtSlot()
    def InsertData(self):
        # self.sbStatus.showMessage('Prepare to insert data....')
        pass

    def _setEvents(self):
        self.tabMain.blockSignals(
            True)  # just for not showing the initial message
        self.tabMain.currentChanged.connect(self.tabMainChanged)  # changed!
        self.tabMain.blockSignals(False)  # wait signals now

    @pyqtSlot()
    def closeApp(self):
        self.close()