class DelegateKeepsReferenceToEditor(QAbstractItemDelegate):
    def __init__(self, parent=None):
        QAbstractItemDelegate.__init__(self, parent)
        self.comboBox = QComboBox()
        self.comboBox.addItem(id_text)

    def createEditor(self, parent, option, index):
        self.comboBox.setParent(parent)
        return self.comboBox
    def createEditor(self, parent, option, index):
        editor = QComboBox(parent)
        editor.addItems(self._choices)

        # Use the model data to pre-select a choice in the combo box.
        currentValue = index.model().data(index)
        if currentValue in self._choices:
            currentIndex = self._choices.index(currentValue)
            editor.setCurrentIndex(currentIndex)

        editor.currentIndexChanged.connect(self.currentIndexChanged)
        return editor
예제 #3
0
파일: ui.py 프로젝트: vojtamolda/games
    def initUI(self):
        self.setWindowTitle(self.tr("Game of Life"))
        self.setLayout(QVBoxLayout())
        self.layout().setSpacing(0)
        self.layout().setContentsMargins(0, 0, 0, 0)

        self.comboBox = QComboBox()
        self.comboBox.addItems([*QGameOfLife.Games.keys()])
        self.comboBox.currentTextChanged.connect(self.select)
        self.layout().addWidget(self.comboBox)

        self.scene = QGraphicsScene()
        self.view = QGraphicsView(self.scene)
        self.view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.view.setSizePolicy(QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred))
        self.view.setFrameShape(QFrame.NoFrame)
        self.layout().addWidget(self.view)

        self.item = None
        self.timer = QTimer()
        self.timer.setInterval(10)
        self.timer.timeout.connect(self.tick)
        initialGame = random.choice([*QGameOfLife.Games.keys()])
        self.select(initialGame)
        self.view.fitInView(self.item, Qt.KeepAspectRatioByExpanding)
        self.comboBox.setCurrentText(initialGame)
예제 #4
0
    def createOptionsGroupBox(self):
        self.optionsGroupBox = QGroupBox("Options")

        buttonsOrientationLabel = QLabel("Orientation of buttons:")

        buttonsOrientationComboBox = QComboBox()
        buttonsOrientationComboBox.addItem("Horizontal", Qt.Horizontal)
        buttonsOrientationComboBox.addItem("Vertical", Qt.Vertical)
        buttonsOrientationComboBox.currentIndexChanged[int].connect(self.buttonsOrientationChanged)

        self.buttonsOrientationComboBox = buttonsOrientationComboBox

        optionsLayout = QGridLayout()
        optionsLayout.addWidget(buttonsOrientationLabel, 0, 0)
        optionsLayout.addWidget(self.buttonsOrientationComboBox, 0, 1)
        optionsLayout.setColumnStretch(2, 1)
        self.optionsGroupBox.setLayout(optionsLayout)
예제 #5
0
파일: ui.py 프로젝트: vojtamolda/games
    def initUI(self):
        self.setWindowTitle(self.tr("Tic-Tac-Toe"))
        layout = QVBoxLayout()
        self.setLayout(layout)
        gridLayout = QGridLayout()
        gridLayout.setSpacing(3)
        aiComboBox = QComboBox(self)
        aiComboBox.addItems([self.tr(ai) for ai in self.AIs])
        aiComboBox.currentTextChanged.connect(self.selectAI)
        layout.addWidget(aiComboBox)
        layout.addLayout(gridLayout)

        for tile in self.ticTacToe:
            button = QTicTacToe.QTileButton(self, tile)
            gridLayout.addWidget(button, tile.row, tile.column)
            button.clicked.connect(button.clickEvent)
            tile.delegate = button
예제 #6
0
파일: ui.py 프로젝트: vojtamolda/games
    def initUI(self):
        self.setWindowTitle(self.tr("Fourplay"))
        layout = QVBoxLayout()
        self.setLayout(layout)
        discGridLayout = QGridLayout()
        discGridLayout.setSpacing(4)
        aiComboBox = QComboBox(self)
        aiComboBox.addItems([self.tr(ai) for ai in self.AIs])
        aiComboBox.currentTextChanged.connect(lambda: self.selectAI())
        layout.addWidget(aiComboBox)
        layout.addLayout(discGridLayout)

        for disc in self.fourPlay:
            qDisc = QFourPlay.QDiscButton(self)
            discGridLayout.addWidget(qDisc, disc.row, disc.column)
            qDisc.clicked.connect(lambda qDisc=qDisc, disc=disc: qDisc.clickEvent(disc))
            qDisc.marked(disc)
            disc.delegate = qDisc
예제 #7
0
    def initializeWindow(self):
        layout = QVBoxLayout()

        self.m_deviceBox = QComboBox()
        self.m_deviceBox.activated[int].connect(self.deviceChanged)
        for deviceInfo in QAudioDeviceInfo.availableDevices(QAudio.AudioOutput):
            self.m_deviceBox.addItem(deviceInfo.deviceName(), deviceInfo)

        layout.addWidget(self.m_deviceBox)

        self.m_modeButton = QPushButton()
        self.m_modeButton.clicked.connect(self.toggleMode)
        self.m_modeButton.setText(self.PUSH_MODE_LABEL)

        layout.addWidget(self.m_modeButton)

        self.m_suspendResumeButton = QPushButton(
                clicked=self.toggleSuspendResume)
        self.m_suspendResumeButton.setText(self.SUSPEND_LABEL)

        layout.addWidget(self.m_suspendResumeButton)

        volumeBox = QHBoxLayout()
        volumeLabel = QLabel("Volume:")
        self.m_volumeSlider = QSlider(Qt.Horizontal, minimum=0, maximum=100,
                singleStep=10)
        self.m_volumeSlider.valueChanged.connect(self.volumeChanged)

        volumeBox.addWidget(volumeLabel)
        volumeBox.addWidget(self.m_volumeSlider)

        layout.addLayout(volumeBox)

        window = QWidget()
        window.setLayout(layout)

        self.setCentralWidget(window)
 def createEditor(self, parent, option, index):
     comboBox = QComboBox(parent)
     comboBox.addItem(id_text)
     return comboBox
예제 #9
0
파일: ui.py 프로젝트: vojtamolda/games
class QGameOfLife(QWidget):

    Games = {
        "Game of Life": (GameOfLife, {'fill_rate': 0.50}),
        "Bacteria": (GrayScottDiffusion, {'coeffs': (0.16, 0.08, 0.035, 0.065)}),
        "Coral": (GrayScottDiffusion, {'coeffs': (0.16, 0.08, 0.062, 0.062)}),
        "Fingerprint": (GrayScottDiffusion, {'coeffs': (0.19, 0.05, 0.060, 0.062)}),
        "Spirals": (GrayScottDiffusion, {'coeffs': (0.10, 0.10, 0.018, 0.050)}),
        "Unstable": (GrayScottDiffusion, {'coeffs': (0.16, 0.08, 0.020, 0.055)}),
        "Worms": (GrayScottDiffusion, {'coeffs': (0.16, 0.08, 0.050, 0.065)}),
        "Zebrafish": (GrayScottDiffusion, {'coeffs': (0.16, 0.08, 0.035, 0.060)}),
    }

    def __init__(self, size=(400, 400)):
        super(QGameOfLife, self).__init__()
        self.size = size
        self.game = None
        self.initUI()
        self.show()

    def initUI(self):
        self.setWindowTitle(self.tr("Game of Life"))
        self.setLayout(QVBoxLayout())
        self.layout().setSpacing(0)
        self.layout().setContentsMargins(0, 0, 0, 0)

        self.comboBox = QComboBox()
        self.comboBox.addItems([*QGameOfLife.Games.keys()])
        self.comboBox.currentTextChanged.connect(self.select)
        self.layout().addWidget(self.comboBox)

        self.scene = QGraphicsScene()
        self.view = QGraphicsView(self.scene)
        self.view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.view.setSizePolicy(QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred))
        self.view.setFrameShape(QFrame.NoFrame)
        self.layout().addWidget(self.view)

        self.item = None
        self.timer = QTimer()
        self.timer.setInterval(10)
        self.timer.timeout.connect(self.tick)
        initialGame = random.choice([*QGameOfLife.Games.keys()])
        self.select(initialGame)
        self.view.fitInView(self.item, Qt.KeepAspectRatioByExpanding)
        self.comboBox.setCurrentText(initialGame)

    def select(self, name: str):
        self.timer.stop()
        Game, args = QGameOfLife.Games[name]
        self.game = Game(self.size, **args)
        self.tick()
        self.timer.start()

    def tick(self):
        self.game.tick()
        bitmap = self.game.visualize()
        image = QImage(bitmap.data, bitmap.shape[1], bitmap.shape[0], QImage.Format_Grayscale8)
        self.scene.removeItem(self.item)
        pixmap = QPixmap.fromImage(image)
        self.item = self.scene.addPixmap(pixmap)

    def resizeEvent(self, event: QResizeEvent):
        self.view.fitInView(self.item, Qt.KeepAspectRatioByExpanding)

    def sizeHint(self) -> QSize:
        return QSize(self.size[0], self.size[1])
예제 #10
0
class LevelSelector(QDialog):
    def __init__(self, parent):
        super(LevelSelector, self).__init__(parent)

        self.setWindowTitle("Level Selector")
        self.setModal(True)

        self.level_name = ""

        self.object_set = 0
        self.object_data_offset = 0x0
        self.enemy_data_offset = 0x0

        self.world_label = QLabel(parent=self, text="World")
        self.world_list = QListWidget(parent=self)
        self.world_list.addItems(WORLD_ITEMS)

        self.world_list.itemDoubleClicked.connect(self.on_ok)
        self.world_list.itemSelectionChanged.connect(self.on_world_click)

        self.level_label = QLabel(parent=self, text="Level")
        self.level_list = QListWidget(parent=self)

        self.level_list.itemDoubleClicked.connect(self.on_ok)
        self.level_list.itemSelectionChanged.connect(self.on_level_click)

        self.enemy_data_label = QLabel(parent=self, text="Enemy Data")
        self.enemy_data_spinner = Spinner(parent=self)

        self.object_data_label = QLabel(parent=self, text="Object Data")
        self.object_data_spinner = Spinner(self)

        self.object_set_label = QLabel(parent=self, text="Object Set")
        self.object_set_dropdown = QComboBox(self)
        self.object_set_dropdown.addItems(OBJECT_SET_ITEMS)

        self.button_ok = QPushButton("Ok", self)
        self.button_ok.clicked.connect(self.on_ok)
        self.button_cancel = QPushButton("Cancel", self)
        self.button_cancel.clicked.connect(self.close)

        stock_level_widget = QWidget()
        stock_level_layout = QGridLayout(stock_level_widget)

        stock_level_layout.addWidget(self.world_label, 0, 0)
        stock_level_layout.addWidget(self.level_label, 0, 1)

        stock_level_layout.addWidget(self.world_list, 1, 0)
        stock_level_layout.addWidget(self.level_list, 1, 1)

        self.source_selector = QTabWidget()
        self.source_selector.addTab(stock_level_widget, "Stock Levels")

        for world_number in range(WORLD_COUNT):
            world_number += 1

            world_map_select = WorldMapLevelSelect(world_number)
            world_map_select.level_selected.connect(
                self._on_level_selected_via_world_map)

            self.source_selector.addTab(world_map_select,
                                        f"World {world_number}")

        data_layout = QGridLayout()

        data_layout.addWidget(self.enemy_data_label, 0, 0)
        data_layout.addWidget(self.object_data_label, 0, 1)
        data_layout.addWidget(self.enemy_data_spinner, 1, 0)
        data_layout.addWidget(self.object_data_spinner, 1, 1)

        data_layout.addWidget(self.object_set_label, 2, 0)
        data_layout.addWidget(self.object_set_dropdown, 2, 1)

        data_layout.addWidget(self.button_ok, 3, 0)
        data_layout.addWidget(self.button_cancel, 3, 1)

        main_layout = QVBoxLayout()
        main_layout.addWidget(self.source_selector)
        main_layout.addLayout(data_layout)

        self.setLayout(main_layout)

        self.world_list.setCurrentRow(1)  # select Level 1-1
        self.on_world_click()

    def keyPressEvent(self, key_event: QKeyEvent):
        if key_event.key() == Qt.Key_Escape:
            self.reject()

    def on_world_click(self):
        index = self.world_list.currentRow()

        assert index >= 0

        self.level_list.clear()

        # skip first meaningless item
        for level in Level.offsets[1:]:
            if level.game_world == index:
                if level.name:
                    self.level_list.addItem(level.name)

        if self.level_list.count():
            self.level_list.setCurrentRow(0)

            self.on_level_click()

    def on_level_click(self):
        index = self.level_list.currentRow()

        assert index >= 0

        level_is_overworld = self.world_list.currentRow(
        ) == OVERWORLD_MAPS_INDEX

        if level_is_overworld:
            level_array_offset = index + 1
            self.level_name = ""
        else:
            level_array_offset = Level.world_indexes[
                self.world_list.currentRow()] + index + 1
            self.level_name = f"World {self.world_list.currentRow()}, "

        self.level_name += f"{Level.offsets[level_array_offset].name}"

        object_data_for_lvl = Level.offsets[
            level_array_offset].rom_level_offset

        if not level_is_overworld:
            object_data_for_lvl -= Level.HEADER_LENGTH

        if not level_is_overworld:
            enemy_data_for_lvl = Level.offsets[level_array_offset].enemy_offset
        else:
            enemy_data_for_lvl = 0

        if enemy_data_for_lvl > 0:
            # data in look up table is off by one, since workshop ignores the first byte
            enemy_data_for_lvl -= 1

        self.enemy_data_spinner.setEnabled(not level_is_overworld)

        # if self.world_list.currentRow() >= WORLD_1_INDEX:
        object_set_index = Level.offsets[level_array_offset].real_obj_set
        self.button_ok.setDisabled(level_is_overworld)

        self._fill_in_data(object_set_index, object_data_for_lvl,
                           enemy_data_for_lvl)

    def _fill_in_data(self, object_set: int, layout_address: int,
                      enemy_address: int):
        self.object_set_dropdown.setCurrentIndex(object_set)
        self.object_data_spinner.setValue(layout_address)
        self.enemy_data_spinner.setValue(enemy_address)

    def _on_level_selected_via_world_map(self, level_name: str,
                                         object_set: int, layout_address: int,
                                         enemy_address: int):
        self.level_name = level_name

        self._fill_in_data(object_set, layout_address, enemy_address)

        self.on_ok()

    def on_ok(self, _=None):
        self.object_set = self.object_set_dropdown.currentIndex()
        self.object_data_offset = self.object_data_spinner.value()
        # skip the first byte, because it seems useless
        self.enemy_data_offset = self.enemy_data_spinner.value() + 1

        self.accept()

    def closeEvent(self, _close_event: QCloseEvent):
        self.reject()
예제 #11
0
 def create_torna_selection(self):
     self.tournaments = QComboBox()
     self.tournaments.setModelColumn(0)
     self.tournaments.currentIndexChanged.connect(self.torna_valasztas)
     self.main_layout.addWidget(self.tournaments)
     self.load_torna()
예제 #12
0
class RootsApp(QMainWindow):
    standard_deviation_threshold = 0.1                      # when I receive a measurement from the sensor I check if its standard deviation; if it's too low it means the sensor is not working
    temporary_database_filename = "temporary.db"            # the current session is stored in a temporary database. When the user saves, it is copied at the desired location
    def __init__(self):
        super().__init__();
        self.setWindowTitle("Roots")
        self.setFixedWidth(1200)
        self.resize(1200, 1200)
        self.threadpool = QThreadPool();
        self.object_list = list()
        self.is_training_on = False
        self.interaction_under_training = None
        self.n_measurements_collected = 0
        self.n_measurements_to_collect = 3
        self.sensor_not_responding = True
        self.sensor_not_responding_timeout = 2000        # milliseconds
        self.database_connection = self.create_temporary_database()
        self.active_object = None
        self.number_of_objects_added = 0
        self.sensor_start_freq = 250000
        self.sensor_end_freq = 3000000

    # creates the plot
        self.plotWidget = pyqtgraph.PlotWidget(title = "Sensor Response")
        self.plotWidget.setFixedHeight(300)
        self.plotWidget.getAxis("bottom").setLabel("Excitation frequency", "Hz")
        self.plotWidget.getAxis("left").setLabel("Volts", "V")
        self.dataPlot = self.plotWidget.plot()

    # timer used to see if the sensor is responding
        self.timer = QTimer()
        self.timer.setInterval(self.sensor_not_responding_timeout)
        self.timer.timeout.connect(self.timer_timeout)
        self.timer_timeout()

    # defines the actions in the file menu with button actions
        iconExit = QIcon("icons/icon_exit.png")
        btnActionExit = QAction(iconExit, "Exit", self)
        btnActionExit.setStatusTip("Click to terminate the program")
        btnActionExit.triggered.connect(self.exit)

        iconSave = QIcon("icons/icon_save.ico")
        buttonActionSave = QAction(iconSave, "Save current set of objects", self)
        # buttonActionSave.setStatusTip("Click to perform action 2")
        buttonActionSave.triggered.connect(self.save)

        iconOpen = QIcon("icons/icon_load.png")
        buttonActionOpen = QAction(iconOpen, "Load set of objects", self)
        buttonActionOpen.triggered.connect(self.open)

    # toolbar
        toolBar = QToolBar("Toolbar")
        toolBar.addAction(buttonActionSave)
        toolBar.addAction(buttonActionOpen)
        toolBar.setIconSize(QSize(64, 64))
        toolBar.setStyleSheet(styles.toolbar)
        self.addToolBar(toolBar)

    # menu
        menuBar = self.menuBar()
        menuBar.setStyleSheet(styles.menuBar)
        menuFile = menuBar.addMenu("File")
        menuOptions = menuBar.addMenu("Options")
        menuView = menuBar.addMenu("View")
        menuConnect = menuBar.addMenu("Connect")
        menuFile.addAction(buttonActionSave)
        menuFile.addAction(buttonActionOpen)
        menuFile.addAction(btnActionExit)

    # status bar
        self.setStatusBar(QStatusBar(self))

    # creates the "My Objects" label
        labelMyObjects = QLabel("My Objects")
        labelMyObjects.setFixedHeight(100)
        labelMyObjects.setAlignment(Qt.AlignCenter)
        labelMyObjects.setStyleSheet(styles.labelMyObjects)

    # button "add object"
        icon_plus = QIcon("icons/icon_add.png")
        self.btn_create_object = QPushButton("Add Object")
        self.btn_create_object.setCheckable(False)
        self.btn_create_object.setIcon(icon_plus)
        self.btn_create_object.setFixedHeight(80)
        self.btn_create_object.setStyleSheet(styles.addObjectButton)
        self.btn_create_object.clicked.connect(self.create_object)

    # defines the layout of the "My Objects" section
        self.verticalLayout = QVBoxLayout()
        self.verticalLayout.setContentsMargins(0,0,0,0)
        self.verticalLayout.addWidget(labelMyObjects)
        self.verticalLayout.addWidget(self.btn_create_object)
        self.spacer = QSpacerItem(0,2000, QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.verticalLayout.setSpacing(0)
        self.verticalLayout.addSpacerItem(self.spacer)  #adds spacer

    # defines the ComboBox which holds the names of the objects
        self.comboBox = QComboBox()
        self.comboBox.addItem("- no object selected")
        self.comboBox.currentIndexChanged.connect(self.comboBox_index_changed)
        self.comboBox.setFixedSize(300, 40)
        self.comboBox.setStyleSheet(styles.comboBox)
        self.update_comboBox()

    # defines the label "Selected Object" (above the comboBox)
        self.labelComboBox = QLabel()
        self.labelComboBox.setText("Selected Object:")
        self.labelComboBox.setStyleSheet(styles.labelComboBox)
        self.labelComboBox.adjustSize()

    # vertical layout for the combobox and its label
        self.VLayoutComboBox = QVBoxLayout()
        self.VLayoutComboBox.addWidget(self.labelComboBox)
        self.VLayoutComboBox.addWidget(self.comboBox)

    # label with the output text (the big one on the right)
        self.labelClassification = QLabel()
        self.labelClassification.setText("No interaction detected")
        self.labelClassification.setFixedHeight(80)
        self.labelClassification.setStyleSheet(styles.labelClassification)
        self.labelClassification.adjustSize()

        HLayoutComboBox = QHBoxLayout()
        HLayoutComboBox.addLayout(self.VLayoutComboBox)
        HLayoutComboBox.addSpacerItem(QSpacerItem(1000,0, QSizePolicy.Expanding, QSizePolicy.Expanding));  #adds spacer
        HLayoutComboBox.addWidget(self.labelClassification)

    # creates a frame that contains the combobox and the labels
        frame = QFrame()
        frame.setStyleSheet(styles.frame)
        frame.setLayout(HLayoutComboBox)

    # sets the window layout with the elements created before
        self.windowLayout = QVBoxLayout()
        self.windowLayout.addWidget(self.plotWidget)
        self.windowLayout.addWidget(frame)
        self.windowLayout.addLayout(self.verticalLayout)

    # puts everything into a frame and displays it on the window
        self.mainWindowFrame = QFrame()
        self.mainWindowFrame.setLayout(self.windowLayout)
        self.mainWindowFrame.setStyleSheet(styles.mainWindowFrame)
        self.setCentralWidget(self.mainWindowFrame)

        self.create_object()        # creates one object at the beginning



# -----------------------------------------------------------------------------------------------------------
# Shows a welcome message
    def show_welcome_msg(self):
        welcome_msg = QMessageBox()
        welcome_msg.setText("Welcome to the Roots application!")
        welcome_msg.setIcon(QMessageBox.Information)
        welcome_msg.setInformativeText(strings.welcome_text)
        welcome_msg.setWindowTitle("Welcome")
        welcome_msg.exec_()


# -----------------------------------------------------------------------------------------------------------
# When the user changes the object in the combobox, updates the active object
    def comboBox_index_changed(self, index):
        object_name = self.comboBox.currentText()
        for object in self.object_list:
            if object.name == object_name:
                self.set_active_object(object)
                print("DEBUG: selected object changed. Object name: {0}".format(object.name))
                return

# -----------------------------------------------------------------------------------------------------------
# This function allows to save the current objects on a file
    def save(self):
        current_path = os.getcwd()
        directory_path = current_path + "/Saved_Workspaces"

        if not os.path.exists(directory_path):
            os.mkdir(directory_path)

        file_path = None
        [file_path, file_extension] = QFileDialog.getSaveFileName(self,"Roots", directory_path, "Roots database (*.db)")
        if file_path is None:
            return

        temp_database_path = current_path + "/" + RootsApp.temporary_database_filename
        shutil.copyfile(temp_database_path, file_path)      # copies the temporary database to save the current workspace
        return



# -----------------------------------------------------------------------------------------------------------
# this function creates a clean database where all the data of this session will be temporarily stored
    def create_temporary_database(self):
        current_path = os.getcwd()
        file_path = current_path + "/" + RootsApp.temporary_database_filename

        if os.path.exists(file_path):   # if the database is already there it deletes it to reset it
            os.remove(file_path)
            print("DEBUG: removing database. (in 'RootsApp.create_temporary_database()'")

        database_connection = database.create_connection(RootsApp.temporary_database_filename)  # creates the temporary database
        database.create_tables(database_connection)                                             # initializes the database
        database.reset_db(database_connection)                                                  # resets the database (not needed but it doesn't cost anything to put it)

        return database_connection


# -----------------------------------------------------------------------------------------------------------
# This function allows to load previously created objects from a file
    def open(self):
        current_path = os.getcwd()
        saved_files_directory = current_path + "/Saved_Workspaces"

        [file_path, file_extension] = QFileDialog.getOpenFileName(self,"Roots", saved_files_directory, "Roots database (*.db)");
        if file_path == '':
            return

        for object in self.object_list.copy():     # deletes all the objects
            print("DEBUG: deleting object {0} (in 'open()')".format(object.name))
            self.delete_object(object)

        temp_database_path = current_path + "/" + RootsApp.temporary_database_filename
        self.database_connection.close()
        os.remove(temp_database_path)
        shutil.copyfile(file_path, temp_database_path)      # replaces the temporary database with the file to open
        self.database_connection = database.create_connection(temp_database_path)

        object_tuples = database.get_all_objects(self.database_connection)
        for object_tuple in object_tuples:
            object_ID, object_name = object_tuple
            location_IDs = database.get_locations_id_for_object(self.database_connection, object_ID)
            formatted_location_IDs = []
            for location_ID in location_IDs:
                formatted_location_IDs.append(location_ID[0])

            print("DEBUG: loading object {0} with location IDs {1}. (in 'RootsApp.open()')".format(object_name, formatted_location_IDs))
            self.add_object(object_name, object_ID, formatted_location_IDs)
            self.train_classifiers()
        return


# -----------------------------------------------------------------------------------------------------------
# This function updates the ComboBox whenever objects are created, destroyed or the active object has changed
    def update_comboBox(self):
        print("DEBUG: repainting ComboBox. (in 'RootsApp.update_comboBox()'")
        self.comboBox.clear()
        self.comboBox.addItem("none")
        for object in self.object_list:
            self.comboBox.addItem(object.name)
        self.comboBox.adjustSize()


# -----------------------------------------------------------------------------------------------------------
# This is a timer which is restarted every time a measurement is received. If it elapses it means that the sesnor is not connected
    def timer_timeout(self):
        print("DEBUG: timer timeout. (in 'RootsApp.timer_timeout()'")
        self.sensor_not_responding = True
        self.statusBar().showMessage(strings.sensor_disconnected)
        self.statusBar().setStyleSheet(styles.statusBarError)
        self.plotWidget.setTitle("Sensor not connected")

# -----------------------------------------------------------------------------------------------------------
# This function creates a new object in the database and then calls the "add_object" function, which adds the newly created object to the application
    def create_object(self):
        new_object_name = "Object {0}".format(self.number_of_objects_added + 1)
        [new_object_ID, location_IDs] = database.create_object(self.database_connection, new_object_name)
        self.add_object(new_object_name, new_object_ID, location_IDs)


# -----------------------------------------------------------------------------------------------------------
# This function deletes an object from the database, and from the application object list. It alsos destroys the object
    def delete_object(self, object):
        print("DEBUG: deleting object {0}. (in 'RootsApp.delete_object()')".format(object.ID))
        database.delete_object(self.database_connection, object.ID)
        self.object_list.remove(object)
        self.verticalLayout.removeItem(object.layout)
        self.update_comboBox()
        object.delete()


# -----------------------------------------------------------------------------------------------------------
# This function adds an object to the current application. Note that if you want to create an object ex-novo you should call "create_object". This function is useful when loading existing objects from a file
    def add_object(self, name, object_ID, location_IDs):
        self.number_of_objects_added += 1
        new_object = Object(name, object_ID, location_IDs, self)
        self.object_list.append(new_object)

        for ID in location_IDs:                                         # initializes the measurements with 0 if the measurement is empty
            #print("DEBUG: initializing location ID {0}".format(ID))
            measurements = database.get_measurements_for_location(self.database_connection, ID)

            print("DEBUG: location {0} of object {1} is trained: {2}. (in 'RootsApp.add_object()')".format(ID, new_object.name, database.is_location_trained(self.database_connection, ID)))
            if len(measurements) == 0:
                database.save_points(self.database_connection, [0], ID)
                database.set_location_trained(self.database_connection, ID, "FALSE")
            elif database.is_location_trained(self.database_connection, ID) == "TRUE":
                new_object.get_interaction_by_ID(ID).setCalibrated(True)

        # inserts the newly created object before the "Add Object" button
        index = self.verticalLayout.indexOf(self.btn_create_object)
        self.verticalLayout.insertLayout(index, new_object.layout)
        self.update_comboBox()
        print("DEBUG: object {0} added. (in 'RootsApp.add_object()')".format(new_object.name))
        return



# -----------------------------------------------------------------------------------------------------------
# This function takes as input the measurement data and formats it to plot it on the graph
    def update_graph(self, data):
        frequency_step = (self.sensor_end_freq - self.sensor_start_freq) / len(data)
        x_axis = numpy.arange(self.sensor_start_freq, self.sensor_end_freq, frequency_step)
        formatted_data = numpy.transpose(numpy.asarray([x_axis, data]))
        self.dataPlot.setData(formatted_data)


# -----------------------------------------------------------------------------------------------------------
# This function starts the UDP server that receives the measurements
    def run_UDP_server(self, UDP_IP, UDP_PORT):
        self.UDPServer = UDPServer(UDP_IP, UDP_PORT)
        self.UDPServer.signals.measurementReceived.connect(self.process_measurement)
        self.threadpool.start(self.UDPServer)


# -----------------------------------------------------------------------------------------------------------
# This function changes some global variables to tell the application to save the incoming measurements into the database. The measurements belong to the interaction passed as argument
    def start_collecting_measurements(self, interaction):
        if self.sensor_not_responding:
            print("DEBUG: warning! Can't start calibration, the sensor is not responding! (in 'RootsApp.start_collecting_measurements()')")
            error_msg = QMessageBox()
            error_msg.setText("Can't start calibration!")
            error_msg.setIcon(QMessageBox.Critical)
            error_msg.setInformativeText('The sensor is not responding, make sure it is connected')
            error_msg.setWindowTitle("Error")
            error_msg.exec_()
        else:
            print("starting to collect measurements into the database at location ID {0} (in 'RootsApp.start_collecting_measurements()')".format(interaction.ID));
            self.is_training_on = True
            self.interaction_under_training = interaction
            database.delete_measurements_from_location(self.database_connection, interaction.ID)   # resets the location measurements

            self.progress_dialog = QProgressDialog("Calibrating", "Abort", 0, self.n_measurements_to_collect, self)
            self.progress_dialog.setWindowModality(Qt.WindowModal)
            self.progress_dialog.setWindowTitle("Calibration")
            self.progress_dialog.setFixedSize(400, 200)
            self.progress_dialog.setValue(0)
            self.progress_dialog.exec_()



# -----------------------------------------------------------------------------------------------------------
# This function is called by the UDP thread every time that a measurement is received. It does the following:
#   1. Plots the incoming measurement
#   2. IF training mode IS on:
#           Predicts the interaction (tries to guess where the user is touching)
#      ELSE:
#           Saves the measurement and retrains the classifier with the new data
    def process_measurement(self, received_data):
        self.sensor_not_responding = False
        self.plotWidget.setTitle("Sensor response")
        self.timer.start()                                          # starts the timer that checks if we are receiving data from the sensor

        measurement = received_data.split(' ')                      # get rid of separator
        measurement = [float(i) for i in measurement]               # convert strings to float
        self.update_graph(measurement)
        self.predict_interaction(measurement)

        # checks the standard deviation of the received data to see if the sensor is working well
        if (numpy.std(measurement) < self.standard_deviation_threshold):
            self.statusBar().showMessage(strings.sensor_not_working)
            self.statusBar().setStyleSheet(styles.statusBarError)
        else:
            self.statusBar().setStyleSheet(styles.statusBar)

        if self.is_training_on:
            print("saving measurement {0} into database at location_ID {1}. (in 'RootsApp.process_measurement()')".format(self.n_measurements_collected + 1, self.interaction_under_training.ID))
            database.save_points(self.database_connection, measurement, self.interaction_under_training.ID)
            self.n_measurements_collected += 1
            self.progress_dialog.setValue(self.n_measurements_collected)
            if (self.n_measurements_collected >= self.n_measurements_to_collect):
                self.is_training_on = False
                self.n_measurements_collected = 0
                print("DEBUG: {0} measurements were saved at location_ID {1}. (in 'RootsApp.process_measurement()')".format(self.n_measurements_to_collect, self.interaction_under_training.ID))
                self.train_classifiers()
                self.interaction_under_training.setCalibrated(True)     # this makes the button "Calibrate" change coulour


# -----------------------------------------------------------------------------------------------------------
# This function retrains the classifiers using all the measurements present in the database and assigns to each object its classifier
    def train_classifiers(self):
        #[objects_ID, classifiers]
        classifiers = classifier.get_classifiers(self.database_connection)
        print("DEBUG: the following classifiers were created: {0}. (in 'RootsApp.train_classifiers')".format(classifiers))
        for object in self.object_list:
            for index, tuple in enumerate(classifiers):
                object_ID, classif = tuple;  # extracts the object ID and the classifier from the tuple
                if object_ID == object.ID:
                    object.classifier = classif
                    del classifiers[index]


# -----------------------------------------------------------------------------------------------------------
# This function changes the current active object (the software tries to guess where the user is touching using the calibration data from the active object)
    def set_active_object(self, active_object):
        self.active_object = active_object

        for obj in self.object_list:
            if obj == active_object:
                active_object.set_highlighted(True)
            else:
                obj.set_highlighted(False)

        index = self.comboBox.findText(self.active_object.name)     # updates the index of the ComboBox
        self.comboBox.setCurrentIndex(index)


# -----------------------------------------------------------------------------------------------------------
# This function changes the name of an object. It updates the database AND the application data structure.
    def rename_object(self, object, new_name):
        print("DEBUG: changing name of object '{0}' (in 'RootsApp.rename_object')".format(object.name))
        object.set_name(new_name)
        database.rename_object(self.database_connection, object.ID, new_name)
        self.update_comboBox()



# -----------------------------------------------------------------------------------------------------------
# This function uses the classifier of the active object to guess where the user is touching, based on the incoming measurement
    def predict_interaction(self, measurement):
        if (len(self.object_list) <= 0):
            self.labelClassification.setText("No objects available")
            self.statusBar().showMessage(strings.no_objects)
            return
        if self.active_object is None:
            self.labelClassification.setText("No object selected")
            self.statusBar().showMessage(strings.no_object_selected)
            return
        if self.active_object.classifier is None:
            self.labelClassification.setText("The object is not calibrated")
            self.statusBar().showMessage(strings.object_not_calibrated)
            return
        else:
            predicted_interaction_id = self.active_object.classifier(measurement)
            interaction = self.active_object.get_interaction_by_ID(predicted_interaction_id)
            self.labelClassification.setText(interaction.name)
            self.statusBar().showMessage("")
            #print("DEBUG: predicted interaction ID: ", interaction.ID)



# -----------------------------------------------------------------------------------------------------------
# This is a system event that gets called whenever the user tries to close the application. It calls the "exit()"
# function (just below) to open a dialog to make sure the user really wants to quit.
    def closeEvent(self, event):
        if not self.exit():
            event.ignore()


# -----------------------------------------------------------------------------------------------------------
# This function gets called when the user cliks on the "Exit" button in the "File" menu or when it tries to close the window (indirectly)
# Here we open a dialog to make sure the user really wants to quit.
    def exit(self):
        dialogWindow = DialogExit()
        answer = dialogWindow.exec_()
        if (answer == True):
            self.UDPServer.stop()
            self.close()
        return answer
예제 #13
0
    def createPropertyTab(self, property_kind):
        propertyTab = QWidget()
        propertyTab.property_kind = property_kind
        propertyTab.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        propertyLayout = QVBoxLayout()

        propertyTab.minMaxCheckBox = QCheckBox()
        propertyTab.minMaxCheckBox.setCheckable(True)
        connector1 = partial(self.main_window.toggleUserMinMax,
                             property=property_kind)
        propertyTab.minMaxCheckBox.stateChanged.connect(connector1)

        propertyTab.minBox = ScientificDoubleSpinBox(self)
        propertyTab.minBox.setMaximum(1E9)
        propertyTab.minBox.setMinimum(0)
        propertyTab.maxBox = ScientificDoubleSpinBox(self)
        propertyTab.maxBox.setMaximum(1E9)
        propertyTab.maxBox.setMinimum(0)

        connector2 = partial(self.main_window.editColorbarMin,
                             property_type=property_kind)
        propertyTab.minBox.valueChanged.connect(connector2)
        connector3 = partial(self.main_window.editColorbarMax,
                             property_type=property_kind)
        propertyTab.maxBox.valueChanged.connect(connector3)

        propertyTab.colormapBox = QComboBox(self)
        cmaps = sorted(m for m in mcolormaps.datad if not m.endswith("_r"))
        for cmap in cmaps:
            propertyTab.colormapBox.addItem(cmap)

        connector = partial(self.main_window.editColorMap,
                            property_type=property_kind)

        propertyTab.colormapBox.currentTextChanged[str].connect(connector)

        propertyTab.dataIndicatorCheckBox = QCheckBox()
        propertyTab.dataIndicatorCheckBox.setCheckable(True)
        connector4 = partial(self.main_window.toggleDataIndicatorCheckBox,
                             property=property_kind)
        propertyTab.dataIndicatorCheckBox.stateChanged.connect(connector4)

        propertyTab.colorBarScaleCheckBox = QCheckBox()
        propertyTab.colorBarScaleCheckBox.setCheckable(True)
        connector5 = partial(self.main_window.toggleColorbarScale,
                             property=property_kind)
        propertyTab.colorBarScaleCheckBox.stateChanged.connect(connector5)

        formLayout = QFormLayout()
        formLayout.setAlignment(QtCore.Qt.AlignHCenter)
        formLayout.setFormAlignment(QtCore.Qt.AlignHCenter)
        formLayout.setLabelAlignment(QtCore.Qt.AlignLeft)

        formLayout.addRow('Colormap:', propertyTab.colormapBox)

        formLayout.addRow('Custom Min/Max', propertyTab.minMaxCheckBox)
        formLayout.addRow('Data Indicator', propertyTab.dataIndicatorCheckBox)
        formLayout.addRow('Log Scale', propertyTab.colorBarScaleCheckBox)
        formLayout.addRow(HorizontalLine())
        formLayout.addRow('Max: ', propertyTab.maxBox)
        formLayout.addRow('Min: ', propertyTab.minBox)

        propertyTab.setLayout(formLayout)

        return propertyTab
예제 #14
0
    def __init__(self):
        super(Window, self).__init__()

        self.renderArea = RenderArea()

        self.shapeComboBox = QComboBox()
        self.shapeComboBox.addItem("Polygon", RenderArea.Polygon)
        self.shapeComboBox.addItem("Rectangle", RenderArea.Rect)
        self.shapeComboBox.addItem("Rounded Rectangle", RenderArea.RoundedRect)
        self.shapeComboBox.addItem("Ellipse", RenderArea.Ellipse)
        self.shapeComboBox.addItem("Pie", RenderArea.Pie)
        self.shapeComboBox.addItem("Chord", RenderArea.Chord)
        self.shapeComboBox.addItem("Path", RenderArea.Path)
        self.shapeComboBox.addItem("Line", RenderArea.Line)
        self.shapeComboBox.addItem("Polyline", RenderArea.Polyline)
        self.shapeComboBox.addItem("Arc", RenderArea.Arc)
        self.shapeComboBox.addItem("Points", RenderArea.Points)
        self.shapeComboBox.addItem("Text", RenderArea.Text)
        self.shapeComboBox.addItem("Pixmap", RenderArea.Pixmap)

        shapeLabel = QLabel("&Shape:")
        shapeLabel.setBuddy(self.shapeComboBox)

        self.penWidthSpinBox = QSpinBox()
        self.penWidthSpinBox.setRange(0, 20)
        self.penWidthSpinBox.setSpecialValueText("0 (cosmetic pen)")

        penWidthLabel = QLabel("Pen &Width:")
        penWidthLabel.setBuddy(self.penWidthSpinBox)

        self.penStyleComboBox = QComboBox()
        self.penStyleComboBox.addItem("Solid", Qt.SolidLine)
        self.penStyleComboBox.addItem("Dash", Qt.DashLine)
        self.penStyleComboBox.addItem("Dot", Qt.DotLine)
        self.penStyleComboBox.addItem("Dash Dot", Qt.DashDotLine)
        self.penStyleComboBox.addItem("Dash Dot Dot", Qt.DashDotDotLine)
        self.penStyleComboBox.addItem("None", Qt.NoPen)

        penStyleLabel = QLabel("&Pen Style:")
        penStyleLabel.setBuddy(self.penStyleComboBox)

        self.penCapComboBox = QComboBox()
        self.penCapComboBox.addItem("Flat", Qt.FlatCap)
        self.penCapComboBox.addItem("Square", Qt.SquareCap)
        self.penCapComboBox.addItem("Round", Qt.RoundCap)

        penCapLabel = QLabel("Pen &Cap:")
        penCapLabel.setBuddy(self.penCapComboBox)

        self.penJoinComboBox = QComboBox()
        self.penJoinComboBox.addItem("Miter", Qt.MiterJoin)
        self.penJoinComboBox.addItem("Bevel", Qt.BevelJoin)
        self.penJoinComboBox.addItem("Round", Qt.RoundJoin)

        penJoinLabel = QLabel("Pen &Join:")
        penJoinLabel.setBuddy(self.penJoinComboBox)

        self.brushStyleComboBox = QComboBox()
        self.brushStyleComboBox.addItem("Linear Gradient",
                Qt.LinearGradientPattern)
        self.brushStyleComboBox.addItem("Radial Gradient",
                Qt.RadialGradientPattern)
        self.brushStyleComboBox.addItem("Conical Gradient",
                Qt.ConicalGradientPattern)
        self.brushStyleComboBox.addItem("Texture", Qt.TexturePattern)
        self.brushStyleComboBox.addItem("Solid", Qt.SolidPattern)
        self.brushStyleComboBox.addItem("Horizontal", Qt.HorPattern)
        self.brushStyleComboBox.addItem("Vertical", Qt.VerPattern)
        self.brushStyleComboBox.addItem("Cross", Qt.CrossPattern)
        self.brushStyleComboBox.addItem("Backward Diagonal", Qt.BDiagPattern)
        self.brushStyleComboBox.addItem("Forward Diagonal", Qt.FDiagPattern)
        self.brushStyleComboBox.addItem("Diagonal Cross", Qt.DiagCrossPattern)
        self.brushStyleComboBox.addItem("Dense 1", Qt.Dense1Pattern)
        self.brushStyleComboBox.addItem("Dense 2", Qt.Dense2Pattern)
        self.brushStyleComboBox.addItem("Dense 3", Qt.Dense3Pattern)
        self.brushStyleComboBox.addItem("Dense 4", Qt.Dense4Pattern)
        self.brushStyleComboBox.addItem("Dense 5", Qt.Dense5Pattern)
        self.brushStyleComboBox.addItem("Dense 6", Qt.Dense6Pattern)
        self.brushStyleComboBox.addItem("Dense 7", Qt.Dense7Pattern)
        self.brushStyleComboBox.addItem("None", Qt.NoBrush)

        brushStyleLabel = QLabel("&Brush Style:")
        brushStyleLabel.setBuddy(self.brushStyleComboBox)

        otherOptionsLabel = QLabel("Other Options:")
        self.antialiasingCheckBox = QCheckBox("&Antialiasing")
        self.transformationsCheckBox = QCheckBox("&Transformations")

        self.shapeComboBox.activated.connect(self.shapeChanged)
        self.penWidthSpinBox.valueChanged.connect(self.penChanged)
        self.penStyleComboBox.activated.connect(self.penChanged)
        self.penCapComboBox.activated.connect(self.penChanged)
        self.penJoinComboBox.activated.connect(self.penChanged)
        self.brushStyleComboBox.activated.connect(self.brushChanged)
        self.antialiasingCheckBox.toggled.connect(self.renderArea.setAntialiased)
        self.transformationsCheckBox.toggled.connect(self.renderArea.setTransformed)

        mainLayout = QGridLayout()
        mainLayout.setColumnStretch(0, 1)
        mainLayout.setColumnStretch(3, 1)
        mainLayout.addWidget(self.renderArea, 0, 0, 1, 4)
        mainLayout.setRowMinimumHeight(1, 6)
        mainLayout.addWidget(shapeLabel, 2, 1, Qt.AlignRight)
        mainLayout.addWidget(self.shapeComboBox, 2, 2)
        mainLayout.addWidget(penWidthLabel, 3, 1, Qt.AlignRight)
        mainLayout.addWidget(self.penWidthSpinBox, 3, 2)
        mainLayout.addWidget(penStyleLabel, 4, 1, Qt.AlignRight)
        mainLayout.addWidget(self.penStyleComboBox, 4, 2)
        mainLayout.addWidget(penCapLabel, 5, 1, Qt.AlignRight)
        mainLayout.addWidget(self.penCapComboBox, 5, 2)
        mainLayout.addWidget(penJoinLabel, 6, 1, Qt.AlignRight)
        mainLayout.addWidget(self.penJoinComboBox, 6, 2)
        mainLayout.addWidget(brushStyleLabel, 7, 1, Qt.AlignRight)
        mainLayout.addWidget(self.brushStyleComboBox, 7, 2)
        mainLayout.setRowMinimumHeight(8, 6)
        mainLayout.addWidget(otherOptionsLabel, 9, 1, Qt.AlignRight)
        mainLayout.addWidget(self.antialiasingCheckBox, 9, 2)
        mainLayout.addWidget(self.transformationsCheckBox, 10, 2)
        self.setLayout(mainLayout)

        self.shapeChanged()
        self.penChanged()
        self.brushChanged()
        self.antialiasingCheckBox.setChecked(True)

        self.setWindowTitle("Basic Drawing")
예제 #15
0
class pdf_ui(QWidget):
    """pdf_ui is a widget that allow you to create a contact sheet

    e_generate: font_path, columns, rows, export_path, font_size
    """

    e_generate = Signal(str, int, int, str, int)

    export_path = None
    font = None

    def __init__(self, settings, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.settings = settings
        self.setSizePolicy(QSizePolicy.MinimumExpanding,
                           QSizePolicy.MinimumExpanding)

        self.system_fonts = pdf_api.get_system_fonts()

        # Setup UI view
        v_main_box = QVBoxLayout()

        # Setup list for production handoff export option
        self.fonts_list = QComboBox()
        for f in self.system_fonts:
            self.fonts_list.addItem(f)
        self.fonts_list_label = QLabel('Font')
        self.fonts_list_label.setBuddy(self.fonts_list)
        self.fonts_list.currentTextChanged.connect(self.__on_font_changed)
        if len(self.system_fonts) > 0:
            self.__on_font_changed(self.system_fonts[0])

        self.wg_font_size, self.wg_font_size_label = self.__create_line_label(
            self.settings.get("font_size", '8'), 'Font Size (1-8)', 200,
            "[1-8]")
        self.wg_columns, self.wg_columns_label = self.__create_line_label(
            self.settings.get("columns", '3'), 'Columns (1-5)', 350, "[1-5]")
        self.wg_rows, self.wg_rows_label = self.__create_line_label(
            self.settings.get("rows", '3'), 'Rows (1-5)', 200, "[1-5]")

        # Setup Local Export option
        self.export_layout = QHBoxLayout()
        self.export_path_button = QPushButton('Browse')
        self.export_path_button.clicked.connect(self.__browse_export_path)

        self.export_path, self.export_path_label = self.__create_line_label(
            self.settings.get("export_path", ''), 'Export Path', 200)
        self.__add_widget_to_layout(self.export_layout, self.export_path,
                                    self.export_path_button)

        generate_btn = QPushButton('Generate Contact Sheet')
        generate_btn.clicked.connect(self.__generate)

        self.__add_widget_to_layout(v_main_box, self.fonts_list_label,
                                    self.fonts_list, self.wg_font_size_label,
                                    self.wg_font_size, self.wg_columns_label,
                                    self.wg_columns, self.wg_rows_label,
                                    self.wg_rows, self.export_path_label)
        v_main_box.addLayout(self.export_layout)
        self.__add_widget_to_layout(v_main_box, generate_btn)

        self.setLayout(v_main_box)

    def generate_contact_sheet(self, font, columns, rows, export_path, panels,
                               header, font_size):
        pdf = pdf_api.Pdf(font, columns, rows, export_path, panels, header,
                          font_size)
        return pdf.build_canvas()

    def __create_line_label(self,
                            name: str,
                            label: str,
                            min_width: int = 200,
                            reg_exp: str = None) -> Tuple[Dict, Dict]:
        """__create_line_label will create a line edit button and his label

        Arguments:
            name {str} -- Default value

            label {str} -- Label name

            min_width {int} -- Minium width (default: {200})

        Returns:
            Tuple[Dict, Dict] -- Line Edit, Label
        """
        line_edit = QLineEdit(name)
        line_edit.setMinimumWidth(min_width)
        if reg_exp is not None:
            rx = QRegExp(reg_exp)
            validator = QRegExpValidator(rx, self)
            line_edit.setValidator(validator)
        label = QLabel(label)
        label.setBuddy(line_edit)
        return line_edit, label

    def __add_widget_to_layout(self, layout: Dict, *widgets: Dict):
        """__add_widget_to_layout will add all the widget to a layout
        __add_widget_to_layout(layout, widget1, widget2, widget3)

        Arguments:
            layout {Dict} -- Layout to add widget to

            widgets {*Dict} -- All the widgets to add
        """

        for w in widgets:
            layout.addWidget(w)

    def __error(self, message: str):
        """__error will show a error message with a given message

        Arguments:
            message {str} -- Message to show
        """
        err = QErrorMessage(self.parent())
        err.setWindowTitle('Flix')
        err.showMessage(message)
        err.exec_()

    def __info(self, message: str):
        """__info will show a message with a given message

        Arguments:
            message {str} -- Message to show
        """
        msgbox = QMessageBox(self.parent())
        msgbox.setWindowTitle('Flix')
        msgbox.setText(message)
        msgbox.exec_()

    def __browse_export_path(self):
        """__browse_export_path will create a dialog window to
        browse and set an export path
        """
        dialog = QFileDialog()
        export_p = None
        if self.export_path.text() != '':
            if os.path.exists(self.export_path.text()):
                export_p = self.export_path.text()
        export_p = dialog.getExistingDirectory(dir=export_p)
        if len(export_p) < 1:
            return
        self.export_path.setText(export_p)

    def __on_font_changed(self, ft: str):
        """__on_font_changed is triggered when the font changed

        Arguments:
            ft {str} -- Font path
        """
        self.font = ft

    def __generate(self):
        """__generate is triggered when the generate button is clicked.
        It will ensure the font, rows, columns and font size are set correctly
        before emitting a signal to e_generate
        """
        if self.font is None:
            self.__error("You need to select a font")
            return
        if int(self.wg_columns.text()) < 1 or int(self.wg_rows.text()) < 1:
            self.__error("You need to set columns / rows within 1-5")
            return
        if self.export_path is None or self.export_path.text() == '':
            self.__error("You need to select an export path")
            return
        if int(self.wg_font_size.text()) < 1:
            self.__error("You need to set columns / rows within 1-8")
            return
        self.e_generate.emit(self.font, int(self.wg_columns.text()),
                             int(self.wg_rows.text()), self.export_path.text(),
                             int(self.wg_font_size.text()))
예제 #16
0
    def __init__(self):
        QWidget.__init__(self)
        self.items = 0

        # Left
        self.table = QTableWidget()
        self.table.setColumnCount(2)
        self.table.setHorizontalHeaderLabels(["Ports", "Services"])
        self.table.horizontalHeader().setStretchLastSection(True)
        self.table.clicked.connect(self.item_clicked)

        # Right
        self.base_ip = QLineEdit()
        self.process = QPushButton("Scan")
        self.clear = QPushButton("Clear")
        self.quit = QPushButton("Quit")

        self.process.setEnabled(False)

        # Creating layout
        self.right = QVBoxLayout()
        self.right.setMargin(10)

        # IP
        label = QLabel("Enter IP addr:")
        label.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed)
        self.right.addWidget(label)
        self.right.addWidget(self.base_ip)

        # Types of scan
        scan_types = QGroupBox("Types of scan:")
        self.scan_type_all = QCheckBox("All (-A)")
        self.scan_type_all.stateChanged.connect(self.box_changed_all)
        self.scan_type_script = QCheckBox("Script Scan (-sC)")
        self.scan_type_script.stateChanged.connect(self.box_changed_other)
        self.scan_type_version = QCheckBox("Version Scan (-sV)")
        self.scan_type_version.stateChanged.connect(self.box_changed_other)
        self.scan_type_os = QCheckBox("OS Scan (-O)")
        self.scan_type_os.stateChanged.connect(self.box_changed_other)
        check_layout = QVBoxLayout()
        check_layout.addWidget(self.scan_type_all)
        check_layout.addWidget(self.scan_type_script)
        check_layout.addWidget(self.scan_type_version)
        check_layout.addWidget(self.scan_type_os)
        scan_types.setLayout(check_layout)
        self.right.addWidget(scan_types)

        # Speed
        label = QLabel("Speed [0-5]:")
        label.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed)
        self.right.addWidget(label)
        self.speed_slider = QSlider(Qt.Horizontal)
        self.speed_slider.setMinimum(0)
        self.speed_slider.setMaximum(5)
        self.speed_slider.setValue(4)
        self.speed_slider.setTickPosition(QSlider.TicksBelow)
        self.right.addWidget(self.speed_slider)

        # Ports
        label = QLabel("Ports:")
        label.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed)
        self.right.addWidget(label)
        self.ports = QComboBox()
        self.ports.addItems([
            "Well-known (0-1023)",
            "Well-known Extended (0-6667)",
            "Well-known + Registered ports (0-49151)",
            "All (0-65535)",
        ])
        self.right.addWidget(self.ports)

        # Fill Space
        self.right.addWidget(QFrame())

        self.right.addWidget(self.process)
        self.right.addWidget(self.clear)
        self.right.addWidget(self.quit)

        # QWidget Layout
        self.layout = QHBoxLayout()

        self.layout.addWidget(self.table)
        self.layout.addLayout(self.right)

        # Set the layout to the QWidget
        self.setLayout(self.layout)

        # Signals and Slots
        self.process.clicked.connect(self.start_scan)
        self.quit.clicked.connect(self.quit_application)
        self.clear.clicked.connect(self.clear_table)
        self.base_ip.textChanged[str].connect(self.check_disable)
예제 #17
0
class NmapScanTab(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.items = 0

        # Left
        self.table = QTableWidget()
        self.table.setColumnCount(2)
        self.table.setHorizontalHeaderLabels(["Ports", "Services"])
        self.table.horizontalHeader().setStretchLastSection(True)
        self.table.clicked.connect(self.item_clicked)

        # Right
        self.base_ip = QLineEdit()
        self.process = QPushButton("Scan")
        self.clear = QPushButton("Clear")
        self.quit = QPushButton("Quit")

        self.process.setEnabled(False)

        # Creating layout
        self.right = QVBoxLayout()
        self.right.setMargin(10)

        # IP
        label = QLabel("Enter IP addr:")
        label.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed)
        self.right.addWidget(label)
        self.right.addWidget(self.base_ip)

        # Types of scan
        scan_types = QGroupBox("Types of scan:")
        self.scan_type_all = QCheckBox("All (-A)")
        self.scan_type_all.stateChanged.connect(self.box_changed_all)
        self.scan_type_script = QCheckBox("Script Scan (-sC)")
        self.scan_type_script.stateChanged.connect(self.box_changed_other)
        self.scan_type_version = QCheckBox("Version Scan (-sV)")
        self.scan_type_version.stateChanged.connect(self.box_changed_other)
        self.scan_type_os = QCheckBox("OS Scan (-O)")
        self.scan_type_os.stateChanged.connect(self.box_changed_other)
        check_layout = QVBoxLayout()
        check_layout.addWidget(self.scan_type_all)
        check_layout.addWidget(self.scan_type_script)
        check_layout.addWidget(self.scan_type_version)
        check_layout.addWidget(self.scan_type_os)
        scan_types.setLayout(check_layout)
        self.right.addWidget(scan_types)

        # Speed
        label = QLabel("Speed [0-5]:")
        label.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed)
        self.right.addWidget(label)
        self.speed_slider = QSlider(Qt.Horizontal)
        self.speed_slider.setMinimum(0)
        self.speed_slider.setMaximum(5)
        self.speed_slider.setValue(4)
        self.speed_slider.setTickPosition(QSlider.TicksBelow)
        self.right.addWidget(self.speed_slider)

        # Ports
        label = QLabel("Ports:")
        label.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed)
        self.right.addWidget(label)
        self.ports = QComboBox()
        self.ports.addItems([
            "Well-known (0-1023)",
            "Well-known Extended (0-6667)",
            "Well-known + Registered ports (0-49151)",
            "All (0-65535)",
        ])
        self.right.addWidget(self.ports)

        # Fill Space
        self.right.addWidget(QFrame())

        self.right.addWidget(self.process)
        self.right.addWidget(self.clear)
        self.right.addWidget(self.quit)

        # QWidget Layout
        self.layout = QHBoxLayout()

        self.layout.addWidget(self.table)
        self.layout.addLayout(self.right)

        # Set the layout to the QWidget
        self.setLayout(self.layout)

        # Signals and Slots
        self.process.clicked.connect(self.start_scan)
        self.quit.clicked.connect(self.quit_application)
        self.clear.clicked.connect(self.clear_table)
        self.base_ip.textChanged[str].connect(self.check_disable)

    @Slot()
    def box_changed_all(self, state):
        if state:
            self.scan_type_script.setChecked(True)
            self.scan_type_version.setChecked(True)
            self.scan_type_os.setChecked(True)
        else:
            if (self.scan_type_script.isChecked()
                    and self.scan_type_version.isChecked()
                    and self.scan_type_os.isChecked()):
                self.scan_type_os.setChecked(False)
                self.scan_type_version.setChecked(False)
                self.scan_type_script.setChecked(False)

    @Slot()
    def box_changed_other(self, state):
        if self.scan_type_all.isChecked():
            if not state:
                self.scan_type_all.setChecked(False)
        if (self.scan_type_script.isChecked()
                and self.scan_type_version.isChecked()
                and self.scan_type_os.isChecked()):
            self.scan_type_all.setChecked(True)

    @Slot()
    def add_element(self, port, service):
        self.table.insertRow(self.items)
        port_item = QTableWidgetItem(str(port))
        port_item.setTextAlignment(Qt.AlignCenter)
        port_item.setFlags(port_item.flags() ^ Qt.ItemIsEditable)

        service_item = QTableWidgetItem(str(service))
        service_item.setFlags(service_item.flags() ^ Qt.ItemIsEditable)
        service_item.setToolTip("Open in Exploit-db")

        self.table.setItem(self.items, 0, port_item)
        self.table.setItem(self.items, 1, service_item)

        self.items += 1

    def remove_item(self, line_number):
        if 0 <= line_number < self.items:
            self.table.removeRow(line_number)
            self.items -= 1

    @Slot()
    def item_clicked(self, item):
        context_menu = QMenu(self)

        browser_item = QWidgetAction(context_menu)
        browser_item.setText("Open exploit-db")
        browser_item.setIcon(QIcon("assets/spider.png"))
        context_menu.addAction(browser_item)

        remove_item = QWidgetAction(context_menu)
        remove_item.setText("Remove Line")
        remove_item.setIcon(QIcon("assets/delete.png"))
        context_menu.addAction(remove_item)

        close_item = QWidgetAction(context_menu)
        close_item.setText("Close")
        close_item.setIcon(QIcon("assets/close.png"))
        context_menu.addAction(close_item)

        action = context_menu.exec_(QCursor.pos())

        if action == browser_item:
            if os.getuid() == 0:
                os.setuid(1000)

            if item.column():
                webbrowser.open(
                    "https://www.exploit-db.com/search?q=" + item.data(),
                    "--no-sandbox")
            else:
                webbrowser.open(
                    "https://www.exploit-db.com/search?q=" +
                    self.table.item(item.row(), 1).text(),
                    "--no-sandbox",
                )
        elif action == remove_item:
            self.remove_item(item.row())

    @Slot()
    def check_disable(self):
        if not self.base_ip.text():
            self.process.setEnabled(False)
        else:
            if check_valid_ip(self.base_ip.text()):
                self.process.setEnabled(True)
            else:
                self.process.setEnabled(False)

    @Slot()
    def start_scan(self):
        self.process.setText("Scan running ...")

        ip_addr = self.base_ip.text()

        scan_types = ""
        if self.scan_type_all.isChecked():
            scan_types = "-A"
        if self.scan_type_script.isChecked(
        ) and not self.scan_type_all.isChecked():
            scan_types += "-sC "
        if self.scan_type_version.isChecked(
        ) and not self.scan_type_all.isChecked():
            scan_types += "-sV "
        if self.scan_type_os.isChecked(
        ) and not self.scan_type_all.isChecked():
            scan_types += "-O "

        speed = f"-T{self.speed_slider.sliderPosition()}"

        index = self.ports.currentIndex()
        if index == 0:
            ports_range = "0-1023"
        elif index == 1:
            ports_range = "0-6667"
        elif index == 2:
            ports_range = "0-49151"
        else:
            ports_range = "-p-"

        print(ip_addr, scan_types, speed, ports_range)
        output = nmap_scan(ip_addr, scan_types, speed, ports_range)

        self.fill_table(output)

        self.process.setText("Scan")

    def fill_table(self, data):
        for status_code, url in data.items():
            self.add_element(status_code, url)

    @Slot()
    def clear_table(self):
        self.table.setRowCount(0)
        self.items = 0
        self.base_ip.setText("")

    @Slot()
    def quit_application(self):
        QApplication.quit()
예제 #18
0
    def initialize_ui(self):
        self.main_layout = QGridLayout(self)
        self.device_label = QLabel(self.tr("Device"))
        self.device_label.setToolTip(
            self.
            tr("The neural netowrk framwork, pytorch, also can use the GPU of Nvidia to do calculations."
               ))
        self.device_combo_box = QComboBox()
        self.device_combo_box.addItem("cpu")
        if torch.cuda.is_available():
            self.device_combo_box.addItem("cuda")
        self.main_layout.addWidget(self.device_label, 0, 0)
        self.main_layout.addWidget(self.device_combo_box, 0, 1)

        self.distance_label = QLabel(self.tr("Distance (Loss) Function"))
        self.distance_label.setToolTip(
            self.
            tr("It's the function to calculate the difference (on the contrary, similarity) between two samples."
               ))
        self.distance_combo_box = QComboBox()
        self.distance_combo_box.addItems(built_in_distances)
        # self.distance_combo_box.setCurrentText("log10MSE")
        self.distance_combo_box.currentTextChanged.connect(
            self.on_distance_changed)
        self.main_layout.addWidget(self.distance_label, 1, 0)
        self.main_layout.addWidget(self.distance_combo_box, 1, 1)

        self.min_niter_label = QLabel(self.tr("Minimum N<sub>iteration</sub>"))
        self.min_niter_label.setToolTip(
            self.tr("Minimum number of iterations to perform"))
        self.min_niter_input = QSpinBox()
        self.min_niter_input.setRange(10, 10000)
        self.min_niter_input.setValue(2000)
        self.main_layout.addWidget(self.min_niter_label, 2, 0)
        self.main_layout.addWidget(self.min_niter_input, 2, 1)

        self.max_niter_label = QLabel(self.tr("Maximum N<sub>iteration</sub>"))
        self.max_niter_label.setToolTip(
            self.tr("Maximum number of iterations to perform"))
        self.max_niter_input = QSpinBox()
        self.max_niter_input.setRange(100, 100000)
        self.max_niter_input.setValue(5000)
        self.main_layout.addWidget(self.max_niter_label, 3, 0)
        self.main_layout.addWidget(self.max_niter_input, 3, 1)

        self.tol_label = QLabel(self.tr("-lg(loss<sub>tolerance</sub>)"))
        self.tol_label.setToolTip(
            self.
            tr("Controls the tolerance of the loss function for termination."))
        self.tol_input = QSpinBox()
        self.tol_input.setRange(1, 100)
        self.tol_input.setValue(10)
        self.main_layout.addWidget(self.tol_label, 4, 0)
        self.main_layout.addWidget(self.tol_input, 4, 1)

        self.ftol_label = QLabel(self.tr("-lg(δ<sub>loss</sub>)"))
        self.ftol_label.setToolTip(
            self.
            tr("Controls the precision goal for the value of loss function in the stopping criterion."
               ))
        self.ftol_input = QSpinBox()
        self.ftol_input.setRange(1, 100)
        self.ftol_input.setValue(10)
        self.main_layout.addWidget(self.ftol_label, 5, 0)
        self.main_layout.addWidget(self.ftol_input, 5, 1)

        self.lr_label = QLabel(self.tr("Learning Rate (x10<sup>-3</sup>)"))
        self.lr_label.setToolTip(
            self.
            tr("The learning rate of the neural network to update its weights from gradient."
               ))
        self.lr_input = QDoubleSpinBox()
        self.lr_input.setDecimals(3)
        self.lr_input.setRange(0.001, 1000)
        self.lr_input.setValue(15)
        self.main_layout.addWidget(self.lr_label, 6, 0)
        self.main_layout.addWidget(self.lr_input, 6, 1)

        self.eps_label = QLabel(self.tr("-lg(δ<sub>eps</sub>)"))
        self.eps_label.setToolTip(
            self.
            tr("Controls the step size used for numerical approximation of the jacobian"
               ))
        self.eps_input = QSpinBox()
        self.eps_input.setRange(1, 100)
        self.eps_input.setValue(8)
        self.main_layout.addWidget(self.eps_label, 7, 0)
        self.main_layout.addWidget(self.eps_input, 7, 1)
예제 #19
0
class NNResolverSettingWidget(QDialog):
    def __init__(self, parent=None, filename=None, group=None):
        super().__init__(parent=parent, f=Qt.Window)
        self.setWindowTitle(self.tr("NN Resolver Setting"))
        if filename is not None:
            self.setting_file = QSettings(filename, QSettings.Format.IniFormat)
            if group is not None:
                self.setting_file.beginGroup(group)
        else:
            self.setting_file = None
        self.setAttribute(Qt.WA_StyledBackground, True)
        self.initialize_ui()

    def initialize_ui(self):
        self.main_layout = QGridLayout(self)
        self.device_label = QLabel(self.tr("Device"))
        self.device_label.setToolTip(
            self.
            tr("The neural netowrk framwork, pytorch, also can use the GPU of Nvidia to do calculations."
               ))
        self.device_combo_box = QComboBox()
        self.device_combo_box.addItem("cpu")
        if torch.cuda.is_available():
            self.device_combo_box.addItem("cuda")
        self.main_layout.addWidget(self.device_label, 0, 0)
        self.main_layout.addWidget(self.device_combo_box, 0, 1)

        self.distance_label = QLabel(self.tr("Distance (Loss) Function"))
        self.distance_label.setToolTip(
            self.
            tr("It's the function to calculate the difference (on the contrary, similarity) between two samples."
               ))
        self.distance_combo_box = QComboBox()
        self.distance_combo_box.addItems(built_in_distances)
        # self.distance_combo_box.setCurrentText("log10MSE")
        self.distance_combo_box.currentTextChanged.connect(
            self.on_distance_changed)
        self.main_layout.addWidget(self.distance_label, 1, 0)
        self.main_layout.addWidget(self.distance_combo_box, 1, 1)

        self.min_niter_label = QLabel(self.tr("Minimum N<sub>iteration</sub>"))
        self.min_niter_label.setToolTip(
            self.tr("Minimum number of iterations to perform"))
        self.min_niter_input = QSpinBox()
        self.min_niter_input.setRange(10, 10000)
        self.min_niter_input.setValue(2000)
        self.main_layout.addWidget(self.min_niter_label, 2, 0)
        self.main_layout.addWidget(self.min_niter_input, 2, 1)

        self.max_niter_label = QLabel(self.tr("Maximum N<sub>iteration</sub>"))
        self.max_niter_label.setToolTip(
            self.tr("Maximum number of iterations to perform"))
        self.max_niter_input = QSpinBox()
        self.max_niter_input.setRange(100, 100000)
        self.max_niter_input.setValue(5000)
        self.main_layout.addWidget(self.max_niter_label, 3, 0)
        self.main_layout.addWidget(self.max_niter_input, 3, 1)

        self.tol_label = QLabel(self.tr("-lg(loss<sub>tolerance</sub>)"))
        self.tol_label.setToolTip(
            self.
            tr("Controls the tolerance of the loss function for termination."))
        self.tol_input = QSpinBox()
        self.tol_input.setRange(1, 100)
        self.tol_input.setValue(10)
        self.main_layout.addWidget(self.tol_label, 4, 0)
        self.main_layout.addWidget(self.tol_input, 4, 1)

        self.ftol_label = QLabel(self.tr("-lg(δ<sub>loss</sub>)"))
        self.ftol_label.setToolTip(
            self.
            tr("Controls the precision goal for the value of loss function in the stopping criterion."
               ))
        self.ftol_input = QSpinBox()
        self.ftol_input.setRange(1, 100)
        self.ftol_input.setValue(10)
        self.main_layout.addWidget(self.ftol_label, 5, 0)
        self.main_layout.addWidget(self.ftol_input, 5, 1)

        self.lr_label = QLabel(self.tr("Learning Rate (x10<sup>-3</sup>)"))
        self.lr_label.setToolTip(
            self.
            tr("The learning rate of the neural network to update its weights from gradient."
               ))
        self.lr_input = QDoubleSpinBox()
        self.lr_input.setDecimals(3)
        self.lr_input.setRange(0.001, 1000)
        self.lr_input.setValue(15)
        self.main_layout.addWidget(self.lr_label, 6, 0)
        self.main_layout.addWidget(self.lr_input, 6, 1)

        self.eps_label = QLabel(self.tr("-lg(δ<sub>eps</sub>)"))
        self.eps_label.setToolTip(
            self.
            tr("Controls the step size used for numerical approximation of the jacobian"
               ))
        self.eps_input = QSpinBox()
        self.eps_input.setRange(1, 100)
        self.eps_input.setValue(8)
        self.main_layout.addWidget(self.eps_label, 7, 0)
        self.main_layout.addWidget(self.eps_input, 7, 1)

    def on_distance_changed(self, distance: str):
        if distance == "log10MSE":
            self.tol_label.setText(self.tr("-loss<sub>tolerance</sub>"))
        else:
            self.tol_label.setText(self.tr("-lg(loss<sub>tolerance</sub>)"))

    @property
    def setting(self):
        devices = ["cpu", "cuda"]
        device = devices[self.device_combo_box.currentIndex()]
        distance = self.distance_combo_box.currentText()
        min_niter = self.min_niter_input.value()
        max_niter = self.max_niter_input.value()
        # when using Lg(MSE) distance
        tol = -self.tol_input.value() if distance == "log10MSE" else 10**(
            -self.tol_input.value())
        ftol = 10**(-self.ftol_input.value())
        lr = self.lr_input.value() / 1000.0
        eps = 10**(-self.eps_input.value())

        setting = NNResolverSetting(device=device,
                                    distance=distance,
                                    min_niter=min_niter,
                                    max_niter=max_niter,
                                    tol=tol,
                                    ftol=ftol,
                                    lr=lr,
                                    eps=eps)
        return setting

    @setting.setter
    def setting(self, setting: NNResolverSetting):
        self.device_combo_box.setCurrentText(setting.device)
        self.distance_combo_box.setCurrentText(setting.distance)
        self.min_niter_input.setValue(setting.min_niter)
        self.max_niter_input.setValue(setting.max_niter)
        if setting.distance == "log10MSE":
            self.tol_input.setValue(-setting.tol)
        else:
            self.tol_input.setValue(-np.log10(setting.tol))
        self.ftol_input.setValue(-np.log10(setting.ftol))
        self.lr_input.setValue(setting.lr * 1000.0)
        self.eps_input.setValue(-np.log10(setting.eps))

    def save(self):
        if self.setting_file is not None:
            setting_bytes = pickle.dumps(self.setting)
            self.setting_file.setValue("nn_resolver_setting", setting_bytes)

    def restore(self):
        if self.setting_file is not None:
            setting_bytes = self.setting_file.value("nn_resolver_setting",
                                                    defaultValue=None)
            if setting_bytes is not None:
                setting = pickle.loads(setting_bytes)
                self.setting = setting
        else:
            self.setting = NNResolverSetting()
예제 #20
0
파일: minmax.py 프로젝트: Vidocapt/sherloq
class MinMaxWidget(ToolWidget):
    def __init__(self, image, parent=None):
        super(MinMaxWidget, self).__init__(parent)

        self.chan_combo = QComboBox()
        self.chan_combo.addItems([
            self.tr('Luminance'),
            self.tr('Red'),
            self.tr('Green'),
            self.tr('Blue'),
            self.tr('RGB Norm')
        ])
        colors = [
            self.tr('Red'),
            self.tr('Green'),
            self.tr('Blue'),
            self.tr('White'),
            self.tr('Black')
        ]
        self.process_button = QPushButton(self.tr('Process'))

        self.min_combo = QComboBox()
        self.min_combo.addItems(colors)
        self.min_combo.setCurrentIndex(1)

        self.max_combo = QComboBox()
        self.max_combo.addItems(colors)
        self.max_combo.setCurrentIndex(0)

        self.filter_spin = QSpinBox()
        self.filter_spin.setRange(0, 5)
        self.filter_spin.setSpecialValueText(self.tr('Off'))

        self.image = image
        self.viewer = ImageViewer(self.image, self.image)
        self.low = self.high = None
        self.stopped = False
        self.change()

        self.process_button.clicked.connect(self.preprocess)
        self.chan_combo.currentIndexChanged.connect(self.change)
        self.min_combo.currentIndexChanged.connect(self.process)
        self.max_combo.currentIndexChanged.connect(self.process)
        self.filter_spin.valueChanged.connect(self.process)

        top_layout = QHBoxLayout()
        top_layout.addWidget(QLabel(self.tr('Channel:')))
        top_layout.addWidget(self.chan_combo)
        top_layout.addWidget(self.process_button)
        top_layout.addStretch()
        top_layout.addWidget(QLabel(self.tr('Minimum:')))
        top_layout.addWidget(self.min_combo)
        top_layout.addWidget(QLabel(self.tr('Maximum:')))
        top_layout.addWidget(self.max_combo)
        top_layout.addWidget(QLabel(self.tr('Filter:')))
        top_layout.addWidget(self.filter_spin)
        main_layout = QVBoxLayout()
        main_layout.addLayout(top_layout)
        main_layout.addWidget(self.viewer)
        self.setLayout(main_layout)

    @staticmethod
    def minmax_dev(patch, mask):
        c = patch[1, 1]
        minimum, maximum, _, _ = cv.minMaxLoc(patch, mask)
        if c < minimum:
            return -1
        if c > maximum:
            return +1
        return 0

    @staticmethod
    def blk_filter(img, radius):
        result = np.zeros_like(img, np.float32)
        rows, cols = result.shape
        block = 2 * radius + 1
        for i in range(radius, rows, block):
            for j in range(radius, cols, block):
                result[i - radius:i + radius + 1, j - radius:j + radius +
                       1] = np.std(img[i - radius:i + radius + 1,
                                       j - radius:j + radius + 1])
        return cv.normalize(result, None, 0, 127, cv.NORM_MINMAX, cv.CV_8UC1)

    def change(self):
        self.min_combo.setEnabled(False)
        self.max_combo.setEnabled(False)
        self.filter_spin.setEnabled(False)
        self.process_button.setEnabled(True)
        self.viewer.update_processed(self.image)

    def preprocess(self):
        start = time()
        channel = self.chan_combo.currentIndex()
        if channel == 0:
            img = cv.cvtColor(self.image, cv.COLOR_BGR2GRAY)
        elif channel == 4:
            b, g, r = cv.split(self.image.astype(np.float64))
            img = cv.sqrt(cv.pow(b, 2) + cv.pow(g, 2) + cv.pow(r, 2))
        else:
            img = self.image[:, :, 3 - channel]
        kernel = 3
        border = kernel // 2
        shape = (img.shape[0] - kernel + 1, img.shape[1] - kernel + 1, kernel,
                 kernel)
        strides = 2 * img.strides
        patches = np.lib.stride_tricks.as_strided(img,
                                                  shape=shape,
                                                  strides=strides)
        patches = patches.reshape((-1, kernel, kernel))
        mask = np.full((kernel, kernel), 255, dtype=np.uint8)
        mask[border, border] = 0
        progress = QProgressDialog(self.tr('Computing deviation...'),
                                   self.tr('Cancel'), 0,
                                   shape[0] * shape[1] - 1, self)
        progress.canceled.connect(self.cancel)
        progress.setWindowModality(Qt.WindowModal)
        blocks = [0] * shape[0] * shape[1]
        for i, patch in enumerate(patches):
            blocks[i] = self.minmax_dev(patch, mask)
            progress.setValue(i)
            if self.stopped:
                self.stopped = False
                return
        output = np.array(blocks).reshape(shape[:-2])
        output = cv.copyMakeBorder(output, border, border, border, border,
                                   cv.BORDER_CONSTANT)
        self.low = output == -1
        self.high = output == +1
        self.min_combo.setEnabled(True)
        self.max_combo.setEnabled(True)
        self.filter_spin.setEnabled(True)
        self.process_button.setEnabled(False)
        self.process()
        self.info_message.emit(
            self.tr('Min/Max Deviation = {}'.format(elapsed_time(start))))

    def cancel(self):
        self.stopped = True

    def process(self):
        minmax = np.zeros_like(self.image)
        minimum = self.min_combo.currentIndex()
        maximum = self.max_combo.currentIndex()
        radius = self.filter_spin.value()
        if radius > 0:
            start = time()
            radius += 2
            if minimum < 4:
                low = self.blk_filter(self.low, radius)
                if minimum <= 2:
                    minmax[:, :, 2 - minimum] = low
                else:
                    minmax = np.repeat(low[:, :, np.newaxis], 3, axis=2)
            if maximum < 4:
                high = self.blk_filter(self.high, radius)
                if maximum <= 2:
                    minmax[:, :, 2 - maximum] += high
                else:
                    minmax += np.repeat(high[:, :, np.newaxis], 3, axis=2)
            minmax = normalize_mat(minmax)
            self.info_message.emit(
                self.tr('Min/Max Filter = {}'.format(elapsed_time(start))))
        else:
            if minimum == 0:
                minmax[self.low] = [0, 0, 255]
            elif minimum == 1:
                minmax[self.low] = [0, 255, 0]
            elif minimum == 2:
                minmax[self.low] = [255, 0, 0]
            elif minimum == 3:
                minmax[self.low] = [255, 255, 255]
            if maximum == 0:
                minmax[self.high] = [0, 0, 255]
            elif maximum == 1:
                minmax[self.high] = [0, 255, 0]
            elif maximum == 2:
                minmax[self.high] = [255, 0, 0]
            elif maximum == 3:
                minmax[self.high] = [255, 255, 255]
        self.viewer.update_processed(minmax)
 def __init__(self, parent=None):
     QAbstractItemDelegate.__init__(self, parent)
     self.comboBox = QComboBox()
     self.comboBox.addItem(id_text)
예제 #22
0
class DisplayPerson(QWidget):
    def __init__(self, parent):
        QWidget.__init__(self)
        self.setWindowTitle("View person")
        self.setWindowIcon(QIcon("assets/icons/logo-dark.png"))
        self.setGeometry(450, 150, 750, 650)

        self.Parent = parent

        self.UI()
        self.show()

    def UI(self):
        self.personDetails()
        self.widgets()
        self.layouts()

    def personDetails(self):
        row = self.Parent.peopleTable.currentRow()
        personId = self.Parent.peopleTable.item(row, 0).text()

        # Adding prefixes to tables changed the format of the Id from and integer to a string PRN#+id
        # Following code strips letters
        personId = personId.lstrip("PRN#")

        query = "SELECT * FROM people WHERE person_id=?"

        person = db.cur.execute(query, (personId, )).fetchone()

        self.id = person[0]
        self.firstName = person[1]
        self.lastName = person[2]
        self.title = person[3]
        self.phone = person[4]
        self.email = person[5]
        self.location = person[6]
        self.emplType = person[7]

    def widgets(self):
        # Top layout widgets
        self.personImg = QLabel()
        self.img = QPixmap('assets/icons/logo-dark.png')
        self.personImg.setPixmap(self.img)
        self.personImg.setAlignment(Qt.AlignCenter)
        self.titleText = QLabel("Display person")
        self.titleText.setAlignment(Qt.AlignCenter)
        # Bottom layout widgets
        self.idEntry = QLabel(str(self.id))
        self.firstNameEntry = QLineEdit()
        self.firstNameEntry.setText(self.firstName)
        self.lastNameEntry = QLineEdit()
        self.lastNameEntry.setText(self.lastName)
        self.titleEntry = QLineEdit()
        self.titleEntry.setText(self.title)
        self.phoneEntry = QLineEdit()
        self.phoneEntry.setText(self.phone)
        self.emailEntry = QLineEdit()
        self.emailEntry.setText(self.email)
        self.locationEntry = QLineEdit()
        self.locationEntry.setText(self.location)

        emplTypes = ["Employee", "Contractor", "Subcontractor"]
        self.employmentTypeEntry = QComboBox()
        self.employmentTypeEntry.addItems(emplTypes)
        self.employmentTypeEntry.setCurrentText(self.emplType)

        self.updateBtn = QPushButton("Update")
        self.updateBtn.clicked.connect(self.updatePerson)
        self.deleteBtn = QPushButton("Delete")
        self.deleteBtn.clicked.connect(self.Parent.funcDeletePerson)

    def layouts(self):
        self.mainLayout = QVBoxLayout()
        self.topLayout = QVBoxLayout()
        self.bottomLayout = QFormLayout()
        self.topFrame = QFrame()
        self.bottomFrame = QFrame()

        # Add widgets
        self.topLayout.addWidget(self.titleText)
        self.topLayout.addWidget(self.personImg)
        self.topFrame.setLayout(self.topLayout)

        self.bottomLayout.addRow("ID: ", self.idEntry)
        self.bottomLayout.addRow("First name: ", self.firstNameEntry)
        self.bottomLayout.addRow("Last name: ", self.lastNameEntry)
        self.bottomLayout.addRow("Title: ", self.titleEntry)
        self.bottomLayout.addRow("Phone: ", self.phoneEntry)
        self.bottomLayout.addRow("Email: ", self.emailEntry)
        self.bottomLayout.addRow("Location: ", self.locationEntry)
        self.bottomLayout.addRow("Employment type: ", self.employmentTypeEntry)
        self.bottomLayout.addRow("", self.updateBtn)
        self.bottomLayout.addRow("", self.deleteBtn)
        self.bottomFrame.setLayout(self.bottomLayout)

        self.mainLayout.addWidget(self.topFrame)
        self.mainLayout.addWidget(self.bottomFrame)

        self.setLayout(self.mainLayout)

    def updatePerson(self):
        row = self.Parent.peopleTable.currentRow()
        personId = self.Parent.peopleTable.item(row, 0).text()
        personId = personId.lstrip("PRN#")

        firstName = self.firstNameEntry.text()
        lastName = self.lastNameEntry.text()
        title = self.titleEntry.text()
        phone = self.phoneEntry.text()
        email = self.emailEntry.text()
        location = self.locationEntry.text()
        emplType = self.employmentTypeEntry.currentText()

        if (firstName and lastName and title and phone and email
                and emplType != ""):
            try:
                query = "UPDATE people SET person_first_name=?, person_last_name=?, person_title=?," \
                        "person_phone=?, person_email=?, person_location=?, person_empl_type=? WHERE person_id=?"
                db.cur.execute(query, (firstName, lastName, title, phone,
                                       email, location, emplType, personId))
                db.conn.commit()
                QMessageBox.information(self, "Info", "Person info updated")
            except:
                QMessageBox.information(self, "Info", "No changes made")
        else:
            QMessageBox.information(self, "Info", "Fields cannot be empty")

        self.Parent.displayPeople()
        self.close()
예제 #23
0
    def _create_from_until_combo(self, row: RowWidgets, cur_serial: int, on_func: Callable) -> QComboBox:
        combo = QComboBox(row.parent)
        combo.setMinimumWidth(100)

        combo.addItem('', 0)
        sorted_date_serials = sorted(x.serial for x in self._contacts_model.iter_dates())
        for date_serial in sorted_date_serials:
            date = self._contacts_model.get_date(date_serial)
            item_text = self._create_vague_date_combo_text(date)
            combo.addItem(item_text, date.serial)

        cur_index = combo.findData(cur_serial)
        combo.setCurrentIndex(cur_index)
        combo.currentIndexChanged.connect(on_func)
        combo.row = row
        return combo
예제 #24
0
    def __init__(self, parent=None):
        super().__init__(parent)

        options = {
            #"pen_pos_down": ("Pen position down:", (0, 100), 40),
            #"pen_pos_up": ("Pen position up:", (0, 100), 60),
            "pen_rate_lower": ("Pen rate lower:", (1, 100), 50),
            "pen_rate_raise": ("Pen rate raise:", (1, 100), 75),
            "pen_delay_down": ("Pen delay down:", (-500, 500), 0),
            "pen_delay_up": ("Pen delay up:", (-500, 500), 0),
            "speed_pendown": ("Speed (pen down):", (1, 110), 25),
            "speed_penup": ("Speed (pen up):", (1, 110), 75),
            "accel": ("Acceleration:", (1, 100), 75),
        }

        settings = QSettings()
        layout = QFormLayout()

        for key, (label, (min_val, max_val), default) in options.items():
            spin_box = AxySettingsSpinBox(settings, key, default)
            spin_box.setRange(min_val, max_val)
            spin_box.setSingleStep(1)
            layout.addRow(label, spin_box)

        model = QComboBox()
        model.addItem("Axidraw V2 or V3", 1)
        model.addItem("Axidraw V3/A3 or SE/A3", 2)
        model.addItem("Axidraw V3 XLX", 3)
        model.addItem("Axidraw MiniKit", 4)
        model.currentIndexChanged.connect(
            lambda index: axy.set_option("model", model.itemData(index))
        )
        model.setCurrentIndex(settings.value("model", 0))
        model.currentIndexChanged.connect(lambda index: settings.setValue("model", index))
        layout.addRow("Model:", model)

        btn_box = QDialogButtonBox()
        btn_box.setStandardButtons(QDialogButtonBox.Ok)
        btn_box.accepted.connect(self.accept)
        btn_box.rejected.connect(self.reject)
        layout.addRow(btn_box)

        self.setLayout(layout)
    class FrmPanelItem(QWidget):
        def __init__(self, parent: QWidget = None):
            super(FrmPanelItem, self).__init__(parent)
            self.items: List[PanelItem] = []

            layout = QGridLayout()
            self.panelItem1 = PanelItem()
            self.panelItem2 = PanelItem()
            self.panelItem3 = PanelItem()
            self.panelItem4 = PanelItem()
            layout.addWidget(self.panelItem1, 0, 0)
            layout.addWidget(self.panelItem2, 0, 1)
            layout.addWidget(self.panelItem3, 1, 0)
            layout.addWidget(self.panelItem4, 1, 1)

            layout2 = QHBoxLayout()
            self.cboxAlignment = QComboBox()
            self.cboxAlignment.clear()
            self.cboxAlignment.addItems(['左对齐', '居中对齐', '右对齐'])
            self.cboxColor = QComboBox()
            self.cboxColor.clear()
            self.cboxColor.addItems(['绿色', '蓝色', '水红色', '黑色'])
            self.btnDisable = QPushButton('禁用')
            layout2.addWidget(self.cboxAlignment)
            layout2.addWidget(self.cboxColor)
            layout2.addWidget(self.btnDisable)
            layout3 = QHBoxLayout()
            self.btnEnable = QPushButton('启用')
            self.btnAlarm = QPushButton('报警')
            self.btnNormal = QPushButton('正常')
            layout3.addWidget(self.btnEnable)
            layout3.addWidget(self.btnAlarm)
            layout3.addWidget(self.btnNormal)

            layout.addLayout(layout2, 2, 0)
            layout.addLayout(layout3, 2, 1)
            self.setLayout(layout)
            self.initForm()

            self.btnDisable.clicked.connect(self.on_btnDisable_clicked)
            self.btnEnable.clicked.connect(self.on_btnEnable_clicked)
            self.btnAlarm.clicked.connect(self.on_btnAlarm_clicked)
            self.btnNormal.clicked.connect(self.on_btnNormal_clicked)
            self.cboxAlignment.activated.connect(self.on_cboxAlignment_activated)
            self.cboxColor.activated.connect(self.on_cboxColor_activated)

        def initForm(self) -> None:
            self.items.append(self.panelItem1)
            self.items.append(self.panelItem2)
            self.items.append(self.panelItem3)
            self.items.append(self.panelItem4)

            self.cboxAlignment.setCurrentIndex(1)

            for i in range(len(self.items)):
                self.items[i].titleText = "标题%d" % (i + 1)

        def on_btnDisable_clicked(self) -> None:
            for item in self.items:
                item.isEnable = False

        def on_btnEnable_clicked(self) -> None:
            for item in self.items:
                item.isEnable = True

        def on_btnAlarm_clicked(self) -> None:
            for item in self.items:
                item.isAlarm = True

        def on_btnNormal_clicked(self) -> None:
            for item in self.items:
                item.isAlarm = False

        def on_cboxAlignment_activated(self, index: int) -> None:
            for item in self.items:
                item.titleAlignment = PanelItem.Alignment(index)

        def on_cboxColor_activated(self, index: int) -> None:
            colors: List[QColor] = [
                QColor("#16A085"),
                QColor("#2980B9"),
                QColor("#8E44AD"),
                QColor("#2C3E50")
            ]

            for item in self.items:
                item.borderColor = colors[index]
class Dialog(QDialog):
    def __init__(self, conversion, test_mode=False):
        super(Dialog, self).__init__()
        self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)
        self.setStyleSheet(style.get_style_sheet())

        self.conversion = conversion
        self.source_button = widgets.create_button(
            'Select Source', event=self.open_file_name_dialog)

        self.status_list = QGroupBox()
        self.status_list_layout = QVBoxLayout()
        self.status_list.setLayout(self.status_list_layout)

        self.jobs = Jobs()
        self.jobs.observers.append(self)
        self.selected_source = QLabel('')
        self.dest_type_picker = QComboBox()
        self.job_widgets: dict = {}

        if test_mode:
            for i in range(400):
                item = widgets.JobWidget(123, 'Text.mp4', 'Text.mp3')
                self.status_list_layout.addWidget(item)

        if not test_mode and conversion is None:
            raise Exception('Conversion backend not found')

        if conversion:
            for t in conversion.get_supported_types():
                self.dest_type_picker.addItem(t)

        self.create_form_group_box()

        self.convert_button = widgets.create_button('Start Converting',
                                                    event=self.handle_start)
        self.cancel_button = widgets.create_button('Exit',
                                                   event=self.close_app)
        buttonBox = widgets.create_button_layout(
            [self.convert_button, self.cancel_button])

        mainLayout = QVBoxLayout()
        mainLayout.addWidget(self.formGroupBox)
        mainLayout.addLayout(buttonBox, stretch=False)
        self.setLayout(mainLayout)
        self.setWindowTitle("FILE CONVERTER")

    def notify(self, job, *args, **kwargs) -> bool:
        if job.id not in self.job_widgets:
            return False
        widget: widgets.JobWidget = self.job_widgets[job.id]

        success = job.success

        if not success:
            widget.set_error(True)
        else:
            widget.set_done(True)

        del self.job_widgets[job.id]

        return True

    def close_app(self, *args, **kwargs):
        self.close()

    def handle_start(self, *args, **kwargs):
        selected_conversion_type = self.dest_type_picker.currentText()
        selected_source = self.get_selected_source()
        if not selected_source:
            utils.prompt_message_box(self,
                                     'Nothing Selected...',
                                     options=[],
                                     default_option=QMessageBox.Ok)
            return

        thread = None
        params = (selected_source, selected_conversion_type)
        kwparams = {}
        convert = self.conversion.convert
        try:
            thread = convert(*params, **kwparams)
        except FileExistsError:
            if utils.prompt_message_box(
                    self, 'File already exists...do you want to overwrite?'
            ) == QMessageBox.Yes:
                try:
                    kwparams['check_file_path'] = False
                    thread = convert(*params, **kwparams)
                except FileExistsError:
                    utils.prompt_message_box(
                        self,
                        'Destination and Source are the same...no need to convert',
                        options=[],
                        default_option=QMessageBox.Ok)
                    thread = None

        if thread is not None:
            text = 'Currently converting ' + self.get_selected_source()
            src_path_without_ext, ext = os.path.splitext(
                self.get_selected_source())
            dest_path = os.path.join(src_path_without_ext + '.' +
                                     selected_conversion_type)
            self.jobs.add_job(thread, text, self.get_selected_source(),
                              dest_path)
            job_id = self.jobs[-1].id
            item = widgets.JobWidget(job_id, text, dest_path)
            self.status_list_layout.addWidget(item)
            self.job_widgets[job_id] = item

    def set_selected_source(self, path):
        if path:
            self.selected_source.setText(path)

    def get_selected_source(self):
        return self.selected_source.text()

    def move_top_left(self):
        qtRectangle = self.frameGeometry()
        centerPoint = QDesktopWidget().availableGeometry().center()
        qtRectangle.moveCenter(centerPoint)
        self.move(qtRectangle.topLeft())

    def create_form_group_box(self):
        self.formGroupBox = QGroupBox("Convert File")
        layout = QFormLayout()
        layout.addRow(QLabel("Source Path"), self.source_button)
        layout.addRow(self.selected_source)
        layout.addRow(QLabel("Convert to type:"), self.dest_type_picker)
        layout.addRow(self.status_list)
        self.formGroupBox.setLayout(layout)

    def open_file_name_dialog(self, *args, **kwargs):
        options = QFileDialog.Options()
        # options |= QFileDialog.DontUseNativeDialog
        fileName, _ = QFileDialog.getOpenFileName(
            self,
            "QFileDialog.getOpenFileName()",
            "",
            "All Files (*);;Python Files (*.py)",
            options=options)
        self.set_selected_source(fileName)

    def closeEvent(self, QCloseEvent):
        self.jobs.stop_polling_for_jobs(wait=True)
class load_img(QWidget):

    switch_window = Signal()

    def __init__(self, parentData):
        QWidget.__init__(self)
        self.data = parentData
        self.file_open()
        self.setup_ui()
        self.shortcuts()
        self.setFixedSize(200, 150)
        self.setWindowTitle('Import timeseries')

    def shortcuts(self):
        self.quit = QShortcut(QKeySequence("Ctrl+q"), self)
        self.quit.activated.connect(self.close)

    def def_combobox_changed(self, value):
        self.def_val.clear()
        if self.def_lbl.currentText() != ' ':
            self.def_val.addItems(
                [str(a) for a in range(self.dims[self.def_lbl.currentText()])])

    def setup_ui(self):
        """Initialize widgets.
        """
        layout = QVBoxLayout()
        label = QLabel('Dimensions: ' +
                       (' ').join(list(self.frame.sizes.keys())))

        iter_axis = QHBoxLayout()
        self.iter_lable = QLabel('Iter axis')
        self.iter_lbl = QComboBox()
        self.iter_lbl.addItems(
            [a for a in self.dims.keys() if a not in ['x', 'y']])
        iter_axis.addWidget(self.iter_lable)
        iter_axis.addWidget(self.iter_lbl)

        def_axis = QHBoxLayout()
        self.def_lable = QLabel('Default coord')
        self.def_lbl = QComboBox()
        self.def_lbl.addItems(
            [' '] + [a for a in self.dims.keys() if a not in ['x', 'y']])
        self.def_lbl.currentTextChanged.connect(self.def_combobox_changed)
        self.def_val = QComboBox()
        if self.def_lbl.currentText() == ' ':
            pass
        else:
            self.def_val.addItems(
                [str(a) for a in range(self.dims[self.def_lbl.currentText()])])
        def_axis.addWidget(self.def_lable)
        def_axis.addWidget(self.def_lbl)
        def_axis.addWidget(self.def_val)

        load_button = QPushButton('Load')
        load_button.clicked.connect(self.load)
        close_button = QPushButton('Cancel')
        close_button.clicked.connect(self.close)

        buttons = QHBoxLayout()
        buttons.addWidget(load_button)
        buttons.addWidget(close_button)

        layout.addWidget(label)
        layout.addLayout(iter_axis)
        layout.addLayout(def_axis)
        layout.addLayout(buttons)
        self.setLayout(layout)

    def load(self):
        assigned = [self.def_lbl.currentText(), self.iter_lbl.currentText()]
        print(''.join([a for a in list(self.dims.keys())
                       if a not in assigned])[::-1])
        self.frame.bundle_axis = ''.join(
            [a for a in list(self.dims.keys()) if a not in assigned])[::-1]
        if self.def_lbl.currentText() != ' ':
            self.frame.default_coords[self.def_lbl.currentText()] = int(
                self.def_val.currentText())
        self.frame.iter_axis = self.iter_lbl.currentText()
        self.data.field = int(self.def_val.currentText())
        STORE = self.frame.parser._raw_metadata.image_metadata[
            b'SLxExperiment'][b'ppNextLevelEx'][b''][b'uLoopPars'][b'Points'][
                b'']
        self.data.field_name = {
            i: point[b'dPosName'].decode("utf-8")
            for i, point in enumerate(STORE)
        }
        self.data.image = self.frame
        self.switch_window.emit()
        self.close()

    def file_open(self):
        name = QFileDialog.getOpenFileName(
            self,
            'Open File',
            filter="ND2 files (*.nd2);;TIFF (*.tif);;All files (*)")
        self.frame = nd2.ND2Reader(name[0])
        self.dims = self.frame.sizes
예제 #28
0
    def __init__(self):
        super().__init__();
        self.setWindowTitle("Roots")
        self.setFixedWidth(1200)
        self.resize(1200, 1200)
        self.threadpool = QThreadPool();
        self.object_list = list()
        self.is_training_on = False
        self.interaction_under_training = None
        self.n_measurements_collected = 0
        self.n_measurements_to_collect = 3
        self.sensor_not_responding = True
        self.sensor_not_responding_timeout = 2000        # milliseconds
        self.database_connection = self.create_temporary_database()
        self.active_object = None
        self.number_of_objects_added = 0
        self.sensor_start_freq = 250000
        self.sensor_end_freq = 3000000

    # creates the plot
        self.plotWidget = pyqtgraph.PlotWidget(title = "Sensor Response")
        self.plotWidget.setFixedHeight(300)
        self.plotWidget.getAxis("bottom").setLabel("Excitation frequency", "Hz")
        self.plotWidget.getAxis("left").setLabel("Volts", "V")
        self.dataPlot = self.plotWidget.plot()

    # timer used to see if the sensor is responding
        self.timer = QTimer()
        self.timer.setInterval(self.sensor_not_responding_timeout)
        self.timer.timeout.connect(self.timer_timeout)
        self.timer_timeout()

    # defines the actions in the file menu with button actions
        iconExit = QIcon("icons/icon_exit.png")
        btnActionExit = QAction(iconExit, "Exit", self)
        btnActionExit.setStatusTip("Click to terminate the program")
        btnActionExit.triggered.connect(self.exit)

        iconSave = QIcon("icons/icon_save.ico")
        buttonActionSave = QAction(iconSave, "Save current set of objects", self)
        # buttonActionSave.setStatusTip("Click to perform action 2")
        buttonActionSave.triggered.connect(self.save)

        iconOpen = QIcon("icons/icon_load.png")
        buttonActionOpen = QAction(iconOpen, "Load set of objects", self)
        buttonActionOpen.triggered.connect(self.open)

    # toolbar
        toolBar = QToolBar("Toolbar")
        toolBar.addAction(buttonActionSave)
        toolBar.addAction(buttonActionOpen)
        toolBar.setIconSize(QSize(64, 64))
        toolBar.setStyleSheet(styles.toolbar)
        self.addToolBar(toolBar)

    # menu
        menuBar = self.menuBar()
        menuBar.setStyleSheet(styles.menuBar)
        menuFile = menuBar.addMenu("File")
        menuOptions = menuBar.addMenu("Options")
        menuView = menuBar.addMenu("View")
        menuConnect = menuBar.addMenu("Connect")
        menuFile.addAction(buttonActionSave)
        menuFile.addAction(buttonActionOpen)
        menuFile.addAction(btnActionExit)

    # status bar
        self.setStatusBar(QStatusBar(self))

    # creates the "My Objects" label
        labelMyObjects = QLabel("My Objects")
        labelMyObjects.setFixedHeight(100)
        labelMyObjects.setAlignment(Qt.AlignCenter)
        labelMyObjects.setStyleSheet(styles.labelMyObjects)

    # button "add object"
        icon_plus = QIcon("icons/icon_add.png")
        self.btn_create_object = QPushButton("Add Object")
        self.btn_create_object.setCheckable(False)
        self.btn_create_object.setIcon(icon_plus)
        self.btn_create_object.setFixedHeight(80)
        self.btn_create_object.setStyleSheet(styles.addObjectButton)
        self.btn_create_object.clicked.connect(self.create_object)

    # defines the layout of the "My Objects" section
        self.verticalLayout = QVBoxLayout()
        self.verticalLayout.setContentsMargins(0,0,0,0)
        self.verticalLayout.addWidget(labelMyObjects)
        self.verticalLayout.addWidget(self.btn_create_object)
        self.spacer = QSpacerItem(0,2000, QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.verticalLayout.setSpacing(0)
        self.verticalLayout.addSpacerItem(self.spacer)  #adds spacer

    # defines the ComboBox which holds the names of the objects
        self.comboBox = QComboBox()
        self.comboBox.addItem("- no object selected")
        self.comboBox.currentIndexChanged.connect(self.comboBox_index_changed)
        self.comboBox.setFixedSize(300, 40)
        self.comboBox.setStyleSheet(styles.comboBox)
        self.update_comboBox()

    # defines the label "Selected Object" (above the comboBox)
        self.labelComboBox = QLabel()
        self.labelComboBox.setText("Selected Object:")
        self.labelComboBox.setStyleSheet(styles.labelComboBox)
        self.labelComboBox.adjustSize()

    # vertical layout for the combobox and its label
        self.VLayoutComboBox = QVBoxLayout()
        self.VLayoutComboBox.addWidget(self.labelComboBox)
        self.VLayoutComboBox.addWidget(self.comboBox)

    # label with the output text (the big one on the right)
        self.labelClassification = QLabel()
        self.labelClassification.setText("No interaction detected")
        self.labelClassification.setFixedHeight(80)
        self.labelClassification.setStyleSheet(styles.labelClassification)
        self.labelClassification.adjustSize()

        HLayoutComboBox = QHBoxLayout()
        HLayoutComboBox.addLayout(self.VLayoutComboBox)
        HLayoutComboBox.addSpacerItem(QSpacerItem(1000,0, QSizePolicy.Expanding, QSizePolicy.Expanding));  #adds spacer
        HLayoutComboBox.addWidget(self.labelClassification)

    # creates a frame that contains the combobox and the labels
        frame = QFrame()
        frame.setStyleSheet(styles.frame)
        frame.setLayout(HLayoutComboBox)

    # sets the window layout with the elements created before
        self.windowLayout = QVBoxLayout()
        self.windowLayout.addWidget(self.plotWidget)
        self.windowLayout.addWidget(frame)
        self.windowLayout.addLayout(self.verticalLayout)

    # puts everything into a frame and displays it on the window
        self.mainWindowFrame = QFrame()
        self.mainWindowFrame.setLayout(self.windowLayout)
        self.mainWindowFrame.setStyleSheet(styles.mainWindowFrame)
        self.setCentralWidget(self.mainWindowFrame)

        self.create_object()        # creates one object at the beginning
예제 #29
0
 def get_value_widget(parent, column):
     choice = QComboBox(parent, editable=False)
     enum = Enum.with_name(column.type_name)
     for name in enum.members.keys():
         choice.addItem(underscored_to_words(name))
     return choice
예제 #30
0
class TornaSettingsDialog(QDialog):
    def __init__(self, parent=None, torna_id=None):
        super(TornaSettingsDialog, self).__init__(parent)
        self.parent = parent
        self.setModal(True)
        self.setWindowTitle("Verseny beállítások")
        self.torna_id = torna_id
        self.main_layout = QVBoxLayout()
        self.setLayout(self.main_layout)
        if self.torna_id is not None:
            self.create_torna_selection()

        self.set_layouts()
        self.add_variables()
        self.alapertekek()
        self.add_buttonbox()

    def set_layouts(self):
        self.tartalom_layout = QHBoxLayout()
        self.main_layout.addLayout(self.tartalom_layout)
        self.layout = QVBoxLayout()
        self.gomb_layout = QVBoxLayout()
        self.tartalom_layout.addLayout(self.layout)
        self.tartalom_layout.addLayout(self.gomb_layout)

    def add_variables(self):
        self.layout.addWidget(QLabel("A verseny megnevezése:"))
        self.torna_name = QLineEdit()
        self.torna_name.setPlaceholderText("A verseny megnevezése")
        self.layout.addWidget(self.torna_name)
        self.layout.addWidget(QLabel("Legyen csoportkör?"))
        self.is_roundrobin = QCheckBox()
        self.is_roundrobin.stateChanged.connect(self.roundrobin_changed)
        self.layout.addWidget(self.is_roundrobin)
        self.layout.addWidget(QLabel("Csoportok száma:"))
        self.csoport_number = CustomSpinBox(1, 16)
        self.layout.addWidget(self.csoport_number)
        self.layout.addWidget(QLabel("Játékosok száma csoportonként:"))
        self.jatekos_per_csoport = CustomSpinBox(3, 8)
        self.layout.addWidget(self.jatekos_per_csoport)
        self.layout.addWidget(QLabel("Játéknem:"))
        self.variant = CustomSpinBox(301, 1001)
        self.layout.addWidget(self.variant)
        self.layout.addWidget(QLabel("Set-ek?:"))
        self.is_sets = QCheckBox()
        self.is_sets.stateChanged.connect(self.is_sets_changed)
        self.layout.addWidget(self.is_sets)
        self.layout.addWidget(QLabel("Set-ek száma:"))
        self.sets_number = CustomSpinBox(1, 8)
        self.sets_number.setDisabled(True)
        self.layout.addWidget(self.sets_number)
        self.layout.addWidget(QLabel("Leg-ek száma:"))
        self.legs_number = CustomSpinBox(2, 30)
        self.layout.addWidget(self.legs_number)
        self.layout.addWidget(QLabel("Best of..."))
        self.is_best = QCheckBox()
        self.layout.addWidget(self.is_best)
        self.layout.addWidget(QLabel("Döntetlen"))
        self.is_draw = QCheckBox()
        self.is_draw.stateChanged.connect(self.is_draw_changed)
        self.layout.addWidget(self.is_draw)
        self.layout.addWidget(QLabel("Pont(Győzelem):"))
        self.pont_win = CustomSpinBox(2, 5)
        self.layout.addWidget(self.pont_win)
        self.layout.addWidget(QLabel("Pont(Döntetlen):"))
        self.pont_draw = CustomSpinBox(1, 3)
        self.pont_draw.setDisabled(True)
        self.layout.addWidget(self.pont_draw)
        self.layout.addWidget(QLabel("Pont(Vereség):"))
        self.pont_lost = CustomSpinBox(0, 2)
        self.layout.addWidget(self.pont_lost)
        self.layout.addWidget(QLabel("Főág"))
        self.is_single_elim = QCheckBox()
        self.is_single_elim.stateChanged.connect(self.is_single_changed)
        self.layout.addWidget(self.is_single_elim)
        self.layout.addWidget(QLabel("Főág száma:"))
        self.num_single = CustomSpinBox(4, 128)
        self.num_single.setDisabled(True)
        self.layout.addWidget(self.num_single)
        self.layout.addWidget(QLabel("Leg-ek száma a főágon:"))
        self.leg_num_single = CustomSpinBox(3, 20)
        self.leg_num_single.setDisabled(True)
        self.layout.addWidget(self.leg_num_single)
        self.layout.addWidget(QLabel("Leg-ek száma az elődöntőben:"))
        self.leg_num_semifinal = CustomSpinBox(4, 20)
        self.leg_num_semifinal.setDisabled(True)
        self.layout.addWidget(self.leg_num_semifinal)
        self.layout.addWidget(QLabel("Leg-ek száma a döntőben:"))
        self.leg_num_final = CustomSpinBox(5, 20)
        self.leg_num_final.setDisabled(True)
        self.layout.addWidget(self.leg_num_final)
        self.layout.addWidget(QLabel("3. hely kijátszva"))
        self.is_3place = QCheckBox()
        self.is_3place.stateChanged.connect(self.is_3place_changed)
        self.is_3place.setDisabled(True)
        self.layout.addWidget(self.is_3place)
        self.layout.addWidget(QLabel("Leg-ek száma a 3. helyért:"))
        self.leg_num_3place = CustomSpinBox(4, 20)
        self.leg_num_3place.setDisabled(True)
        self.layout.addWidget(self.leg_num_3place)

    def create_torna_selection(self):
        self.tournaments = QComboBox()
        self.tournaments.setModelColumn(0)
        self.tournaments.currentIndexChanged.connect(self.torna_valasztas)
        self.main_layout.addWidget(self.tournaments)
        self.load_torna()

    def load_torna(self):
        torna = QSqlQueryModel()
        query = QSqlQuery("select * from torna_settings where aktiv=2")
        torna.setQuery(query)
        if torna.record(0).value(0):
            for i in range(torna.rowCount()):
                self.tournaments.addItem(
                    torna.record(i).value(1),
                    torna.record(i).value(0))  # a value(0) a torna_id
        else:
            print("Nincs aktív torna")

    def torna_valasztas(self, i):
        self.torna_id = self.tournaments.itemData(i)
        self.alapertekek()

    def alapertekek(self):
        if not self.torna_id:
            self.torna_name.clear()
            self.is_roundrobin.setChecked(True)
            self.csoport_number.setValue(1)
            self.jatekos_per_csoport.setValue(4)
            self.variant.setValue(501)
            self.is_sets.setChecked(False)
            self.sets_number.setValue(1)
            self.legs_number.setValue(2)
            self.is_best.setChecked(False)
            self.is_draw.setChecked(False)
            self.pont_win.setValue(2)
            self.pont_draw.setValue(1)
            self.pont_lost.setValue(0)
            self.is_single_elim.setChecked(False)
            self.num_single.setValue(8)
            self.leg_num_single.setValue(3)
            self.leg_num_semifinal.setValue(4)
            self.leg_num_final.setValue(5)
            self.is_3place.setChecked(False)
            self.leg_num_3place.setValue(4)
        else:
            model = QSqlTableModel(db=db)
            model.setTable("torna_settings")
            model.setFilter(f"torna_id={self.torna_id}")
            model.select()
            # print(model.record(0))
            self.torna_name.setText(model.record(0).value(1))
            self.is_roundrobin.setChecked(model.record(0).value(2))
            self.csoport_number.setValue(model.record(0).value(3))
            self.jatekos_per_csoport.setValue(model.record(0).value(4))
            self.variant.setValue(int(model.record(0).value(5)))
            self.is_sets.setChecked(model.record(0).value(6))
            self.sets_number.setValue(model.record(0).value(7))
            self.legs_number.setValue(model.record(0).value(8))
            self.is_best.setChecked(model.record(0).value(9))
            self.is_draw.setChecked(model.record(0).value(10))
            self.pont_win.setValue(model.record(0).value(11))
            self.pont_draw.setValue(model.record(0).value(12))
            self.pont_lost.setValue(model.record(0).value(13))
            self.is_single_elim.setChecked(model.record(0).value(14))
            self.num_single.setValue(model.record(0).value(15))
            self.leg_num_single.setValue(model.record(0).value(17))
            self.leg_num_semifinal.setValue(model.record(0).value(18))
            self.leg_num_final.setValue(model.record(0).value(20))
            self.is_3place.setChecked(model.record(0).value(16))
            self.leg_num_3place.setValue(model.record(0).value(19))

    def add_buttonbox(self):
        self.buttonbox = QDialogButtonBox()
        self.buttonbox.setOrientation(Qt.Vertical)
        self.buttonbox.addButton("Mentés", QDialogButtonBox.ActionRole)
        self.buttonbox.addButton("Alaphelyzet", QDialogButtonBox.ActionRole)
        # self.gomb_members = QPushButton("Résztvevők")
        # self.gomb_members.setDisabled(True)
        # self.buttonbox.addButton(self.gomb_members, QDialogButtonBox.ActionRole)
        # self.gomb_tabella = QPushButton("Tabella")
        # self.gomb_tabella.setDisabled(True)
        # self.buttonbox.addButton(self.gomb_tabella, QDialogButtonBox.ActionRole)
        self.buttonbox.addButton("Mégsem", QDialogButtonBox.ActionRole)
        self.buttonbox.clicked.connect(self.buttonbox_click)
        self.gomb_layout.addWidget(self.buttonbox)

    def roundrobin_changed(self, state):
        if state == Qt.Checked:
            self.csoport_number.setDisabled(False)
            self.jatekos_per_csoport.setDisabled(False)
        else:
            self.csoport_number.setDisabled(True)
            self.jatekos_per_csoport.setDisabled(True)

    def is_sets_changed(self, state):
        if state == Qt.Checked:
            self.sets_number.setDisabled(False)
        else:
            self.sets_number.setDisabled(True)

    def is_draw_changed(self, state):
        if state == Qt.Checked:
            self.pont_draw.setDisabled(False)
        else:
            self.pont_draw.setDisabled(True)

    def is_single_changed(self, state):
        # a főághoz kapcsolódó paraméterek tiltása/engedélyezése
        if state == Qt.Checked:
            self.num_single.setDisabled(False)
            self.is_3place.setDisabled(False)
            self.leg_num_single.setDisabled(False)
            self.leg_num_semifinal.setDisabled(False)
            if self.is_3place.isChecked():
                self.leg_num_3place.setDisabled(False)
            else:
                self.leg_num_3place.setDisabled(True)
            self.leg_num_final.setDisabled(False)
        else:
            self.num_single.setDisabled(True)
            self.is_3place.setDisabled(True)
            self.leg_num_single.setDisabled(True)
            self.leg_num_semifinal.setDisabled(True)
            self.leg_num_3place.setDisabled(True)
            self.leg_num_final.setDisabled(True)

    def is_3place_changed(self, state):
        if state == Qt.Checked:
            self.leg_num_3place.setDisabled(False)
        else:
            self.leg_num_3place.setDisabled(True)

    def buttonbox_click(self, b):
        if b.text() == "Mentés":
            self.save()
        elif b.text() == "Alaphelyzet":
            self.alapertekek()
        # elif b.text() == "Résztvevők":
        #     self.members()
        # elif b.text() == "Tabella":
        #     self.tabella()
        elif b.text() == "Mégsem":
            self.reject()
        else:
            pass

    def save(self):
        if not self.torna_id:
            self.insert_torna_settings()
        else:
            self.update_torna_settings()
        self.close()

    def insert_torna_settings(self):
        van_ilyen_nev = False
        if len(self.torna_name.text()) != 0:
            torna_id_model = QSqlQueryModel()
            query = QSqlQuery(
                "select torna_id, torna_name from torna_settings", db=db)
            torna_id_model.setQuery(query)
            for i in range(torna_id_model.rowCount()):
                if torna_id_model.record(i).value(1) == self.torna_name.text():
                    msg = QMessageBox(self)
                    msg.setStyleSheet("fonz-size: 20px")
                    msg.setWindowTitle("Név ütközés!")
                    msg.setText(
                        '<html style="font-size: 14px; color: red">Már van ilyen nevű verseny!<br></html>'
                        +
                        '<html style="font-size: 16px">Kérem adjon a versenynek egyedi nevet!</html>'
                    )
                    msg.exec_()
                    van_ilyen_nev = True
            if not van_ilyen_nev:
                torna_settings_model = QSqlTableModel(
                    db=db
                )  # !!!!!!! Ha több db van, akkor itt konkrétan meg kell adni
                torna_settings_model.setTable("torna_settings")
                record = torna_settings_model.record()

                record.setValue(1, self.torna_name.text())
                if self.is_roundrobin.isChecked():
                    record.setValue(2, 1)
                else:
                    record.setValue(2, 0)
                record.setValue(3, self.csoport_number.value())
                record.setValue(4, self.jatekos_per_csoport.value())
                record.setValue(5, self.variant.value())
                if self.is_sets.isChecked():
                    record.setValue(6, 1)
                else:
                    record.setValue(6, 0)
                record.setValue(7, self.sets_number.value())
                record.setValue(8, self.legs_number.value())
                # print(record.value(2))
                if self.is_best.isChecked():
                    record.setValue(9, 1)
                else:
                    record.setValue(9, 0)
                if self.is_draw.isChecked():
                    record.setValue(10, 1)
                else:
                    record.setValue(10, 0)
                record.setValue(11, self.pont_win.value())
                record.setValue(12, self.pont_draw.value())
                record.setValue(13, self.pont_lost.value())
                if self.is_single_elim.isChecked():
                    record.setValue(14, 1)
                else:
                    record.setValue(14, 0)
                record.setValue(15, self.num_single.value())
                if self.is_3place.isChecked():
                    record.setValue(16, 1)
                else:
                    record.setValue(16, 0)
                record.setValue(17, self.leg_num_single.value())
                record.setValue(18, self.leg_num_semifinal.value())
                record.setValue(19, self.leg_num_3place.value())
                record.setValue(20, self.leg_num_final.value())
                record.setValue(21, 2)
                # aktiv flag:  0: vége, 1: folyamatban, 2: szerkesztés alatt
                # print(record)
                if torna_settings_model.insertRecord(-1, record):
                    torna_settings_model.submitAll()
                else:
                    db.rollback()

                torna_id_model2 = QSqlQueryModel()
                query2 = QSqlQuery(
                    f"select torna_id from torna_settings where torna_name='{self.torna_name.text()}'",
                    db=db)
                torna_id_model2.setQuery(query2)
                self.torna_id = int(torna_id_model2.record(0).value(0))
                self.gomb_members.setDisabled(False)
        else:
            msg = QMessageBox(self)
            msg.setStyleSheet("fonz-size: 20px")
            msg.setWindowTitle("Hiányzik a verseny neve!")
            msg.setText(
                '<html style="font-size: 14px; color: red">A létrehozott versenynek kell egy elnevezés!<br></html>'
                +
                '<html style="font-size: 16px">Kérem adja meg a verseny nevét!</html>'
            )
            msg.exec_()

    def update_torna_settings(self):
        torna_settings_model = QSqlTableModel(db=db)
        torna_settings_model.setTable("torna_settings")
        record = torna_settings_model.record()
        torna_settings_model.select()
        # for x in range(torna_settings_model.rowCount()):
        #     record.setGenerated(x, False)
        record.setValue(0, self.torna_id)
        record.setValue(1, self.torna_name.text())
        if self.is_roundrobin.isChecked():
            record.setValue(2, 1)
        else:
            record.setValue(2, 0)
        record.setValue(3, self.csoport_number.value())
        record.setValue(4, self.jatekos_per_csoport.value())
        record.setValue(5, self.variant.value())
        if self.is_sets.isChecked():
            record.setValue(6, 1)
        else:
            record.setValue(6, 0)
        record.setValue(7, self.sets_number.value())
        record.setValue(8, self.legs_number.value())
        if self.is_best.isChecked():
            record.setValue(9, 1)
        else:
            record.setValue(9, 0)
        if self.is_draw.isChecked():
            record.setValue(10, 1)
        else:
            record.setValue(10, 0)
        record.setValue(11, self.pont_win.value())
        record.setValue(12, self.pont_draw.value())
        record.setValue(13, self.pont_lost.value())
        if self.is_single_elim.isChecked():
            record.setValue(14, 1)
        else:
            record.setValue(14, 0)
        record.setValue(15, self.num_single.value())
        if self.is_3place.isChecked():
            record.setValue(16, 1)
        else:
            record.setValue(16, 0)
        record.setValue(17, self.leg_num_single.value())
        record.setValue(18, self.leg_num_semifinal.value())
        record.setValue(19, self.leg_num_3place.value())
        record.setValue(20, self.leg_num_final.value())
        record.setValue(21, 2)

        for i in range(torna_settings_model.rowCount()):
            if torna_settings_model.record(i).value(0) == self.torna_id:
                # print(torna_settings_model.record(i).value(0), ":", i)
                record_number = i
        # print(record)
        if torna_settings_model.setRecord(record_number, record):
            torna_settings_model.submitAll()
        else:
            db.rollback()

    # def members(self):
    #     # todo Itt kell a verseny résztvevőit öszerakni
    #     pass
    #
    # def tabella(self):
    #     # todo Itt kell a sorsolást, tabella összeállítást megcsinálni
    #     pass

    def accept(self):
        # todo Ez majd csak a bezáráshoz kell
        super().accept()

    def reject(self):
        print("CANCEL")
        super().reject()
예제 #31
0
 def __init__(self):
     super().__init__()
     self.setWindowTitle("Cobaya input generator for Cosmology")
     self.setStyleSheet("* {font-size:%s;}" % font_size)
     # Menu bar for defaults
     self.menubar = QMenuBar()
     defaults_menu = self.menubar.addMenu(
         '&Show defaults and bibliography for a component...')
     menu_actions = {}
     for kind in kinds:
         submenu = defaults_menu.addMenu(subfolders[kind])
         components = get_available_internal_class_names(kind)
         menu_actions[kind] = {}
         for component in components:
             menu_actions[kind][component] = QAction(component, self)
             menu_actions[kind][component].setData((kind, component))
             menu_actions[kind][component].triggered.connect(
                 self.show_defaults)
             submenu.addAction(menu_actions[kind][component])
     # Main layout
     self.menu_layout = QVBoxLayout()
     self.menu_layout.addWidget(self.menubar)
     self.setLayout(self.menu_layout)
     self.layout = QHBoxLayout()
     self.menu_layout.addLayout(self.layout)
     self.layout_left = QVBoxLayout()
     self.layout.addLayout(self.layout_left)
     self.layout_output = QVBoxLayout()
     self.layout.addLayout(self.layout_output)
     # LEFT: Options
     self.options = QWidget()
     self.layout_options = QVBoxLayout()
     self.options.setLayout(self.layout_options)
     self.options_scroll = QScrollArea()
     self.options_scroll.setWidget(self.options)
     self.options_scroll.setWidgetResizable(True)
     self.layout_left.addWidget(self.options_scroll)
     self.combos = dict()
     for group, fields in _combo_dict_text:
         group_box = QGroupBox(group)
         self.layout_options.addWidget(group_box)
         group_layout = QVBoxLayout(group_box)
         for a, desc in fields:
             self.combos[a] = QComboBox()
             # Combo box label only if not single element in group
             if len(fields) > 1:
                 label = QLabel(desc)
                 group_layout.addWidget(label)
             group_layout.addWidget(self.combos[a])
             self.combos[a].addItems([
                 text(k, v) for k, v in getattr(input_database, a).items()
             ])
     # PLANCK NAMES CHECKBOX TEMPORARILY DISABLED
     #                if a == "theory":
     #                    # Add Planck-naming checkbox
     #                    self.planck_names = QCheckBox(
     #                        "Keep common parameter names "
     #                        "(useful for fast CLASS/CAMB switching)")
     #                    group_layout.addWidget(self.planck_names)
     # Connect to refreshers -- needs to be after adding all elements
     for field, combo in self.combos.items():
         if field == "preset":
             combo.currentIndexChanged.connect(self.refresh_preset)
         else:
             combo.currentIndexChanged.connect(self.refresh)
     #        self.planck_names.stateChanged.connect(self.refresh_keep_preset)
     # RIGHT: Output + buttons
     self.display_tabs = QTabWidget()
     self.display = {}
     for k in ["yaml", "python", "bibliography"]:
         self.display[k] = QTextEdit()
         self.display[k].setLineWrapMode(QTextEdit.NoWrap)
         self.display[k].setFontFamily("mono")
         self.display[k].setCursorWidth(0)
         self.display[k].setReadOnly(True)
         self.display_tabs.addTab(self.display[k], k)
     self.display["covmat"] = QWidget()
     covmat_tab_layout = QVBoxLayout()
     self.display["covmat"].setLayout(covmat_tab_layout)
     self.covmat_text = QLabel()
     self.covmat_text.setWordWrap(True)
     self.covmat_table = QTableWidget(0, 0)
     self.covmat_table.setEditTriggers(
         QAbstractItemView.NoEditTriggers)  # ReadOnly!
     covmat_tab_layout.addWidget(self.covmat_text)
     covmat_tab_layout.addWidget(self.covmat_table)
     self.display_tabs.addTab(self.display["covmat"], "covariance matrix")
     self.layout_output.addWidget(self.display_tabs)
     # Buttons
     self.buttons = QHBoxLayout()
     self.save_button = QPushButton('Save as...', self)
     self.copy_button = QPushButton('Copy to clipboard', self)
     self.buttons.addWidget(self.save_button)
     self.buttons.addWidget(self.copy_button)
     self.save_button.released.connect(self.save_file)
     self.copy_button.released.connect(self.copy_clipb)
     self.layout_output.addLayout(self.buttons)
     self.save_dialog = QFileDialog()
     self.save_dialog.setFileMode(QFileDialog.AnyFile)
     self.save_dialog.setAcceptMode(QFileDialog.AcceptSave)
     self.read_settings()
     self.show()
예제 #32
0
class MainWindow(QDialog):
    signals = signal.signalClass()  # message signal
    settings = None
    settings_batch = None
    Well_Map = None
    Well_Targets = None

    ## @brief MainWindow::__init__ initializes the window with widgets, layouts and groupboxes and opens initialization files.
    def __init__(self):
        super().__init__()

        ## Create QSettings variables in order to be able to access the initialisation parameters
        self.openBatchIniFile()
        self.openSettingsIniFile()

        ## Load wells to process in batch from batch settings initialisation file and calculate the coordinates
        self.wellInitialisation()
        self.Well_Scanner = Scanner()

        ## Overall gridlayout
        self.mainWindowLayout = QGridLayout()

        ## @param mgb is a groupbox with manual control widgets
        mgb = self.createManualGroupBox()

        ## @param is a groupbox with batch process control widgets
        bgb = self.createBatchGroupBox()

        ## @param is a groupbox with log window
        lgb = self.createLogWindow()

        ## @param is a groupbox with video stream window
        vgb = self.Well_Scanner.createVideoWindow()  #self.createVideoWindow()

        ## Fill mainWindowLayout with the just created groupboxes in the mainWindowLayout gridlayout
        self.mainWindowLayout.addWidget(bgb, 0, 0)
        self.mainWindowLayout.addWidget(mgb, 1, 0)
        self.mainWindowLayout.addWidget(vgb, 0, 1)
        self.mainWindowLayout.addWidget(lgb, 1, 1)

        self.setWindowTitle("WELL READER")

        #self.mainWindowLayout.setStyleSheet('background-color: #a9a9a9')

        self.backgroundPalette = QPalette()
        self.backgroundColor = QColor(50, 50, 50)
        self.backgroundPalette.setColor(QPalette.Background,
                                        self.backgroundColor)
        self.setPalette(self.backgroundPalette)

        self.setLayout(self.mainWindowLayout)
        self.resize(self.width(), self.height())

    ## @brief Mainwindow(QDialog)::msg(self, message) emits the message signal. This emit will be catched by the logging slot function in main.py.
    ## @param message is the string message to be emitted.
    def msg(self, message):
        if message is not None:
            self.signals.mes.emit(self.__class__.__name__ + ": " +
                                  str(message))
        return

    ## @brief MainWindow::LogWindowInsert(self, message) appends the message to the log window. This is a slot function called when a mesnal message is emitted from any class which uses the message signal. This Slot is connected which each class which uses this signal.
    # @param message is the message to be displayed.
    @Slot(str)
    def LogWindowInsert(self, message):
        self.log.appendPlainText(str(message) + "\n")
        return

    ## @brief MainWindow::wait_ms(self, milliseconds) is a delay function.
    ## @param milliseconds is the number of milliseconds to wait.
    def wait_ms(self, milliseconds):
        GeneralEventLoop = QEventLoop()
        QTimer.singleShot(milliseconds, GeneralEventLoop.exit)
        GeneralEventLoop.exec_()
        return

    ## @brief MainWindow::createBatchGroupBox(self) creates the groupbox and the widgets in it which are used for the batch control.
    # @return self.batchGroupBox. This is the groupbox containing the Batch process widgets.
    def createBatchGroupBox(self):
        self.processControlGridLayout = QGridLayout()

        self.batchGroupBox = QGroupBox()
        self.batchGroupBox.setStyleSheet("color: #000000;")

        ## label of QGroupbox content
        self.gb_label = QLabel("Batch control")
        self.gb_label.setStyleSheet(
            'QLabel {color: #ffffff; font-weight: bold}')
        self.gb_label.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.processControlGridLayout.addWidget(self.gb_label, 0, 0, 1, 3,
                                                Qt.AlignHCenter)

        ## Button FIRMWARE_RESTART
        self.b_firmware_restart = QPushButton("FIRMWARE_RESTART")
        self.b_firmware_restart.setStyleSheet(
            'QPushButton {background-color: #AAAAAA; border: none}')
        self.b_firmware_restart.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.processControlGridLayout.addWidget(self.b_firmware_restart, 1, 0,
                                                1, 1)

        ## Button Read STM buffer
        self.b_stm_read = QPushButton("STM READ")
        self.b_stm_read.setStyleSheet(
            'QPushButton {background-color: #AAAAAA; border: none}')
        self.b_stm_read.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.processControlGridLayout.addWidget(self.b_stm_read, 1, 1, 1, 1)

        ## Button START BATCH
        self.b_start_batch = QPushButton("START BATCH")
        self.b_start_batch.setStyleSheet(
            'QPushButton {background-color: #AAAAAA; border: none}')
        self.b_start_batch.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.processControlGridLayout.addWidget(self.b_start_batch, 2, 0, 1, 2)

        ## Button STOP BATCH
        self.b_stop_batch = QPushButton("STOP BATCH")
        self.b_stop_batch.setStyleSheet(
            'QPushButton {background-color: #AAAAAA; border: none}')
        self.b_stop_batch.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.processControlGridLayout.addWidget(self.b_stop_batch, 3, 0, 1, 2)

        ## Button Snapshot.
        self.b_snapshot = QPushButton("Snapshot")
        self.b_snapshot.setStyleSheet(
            'QPushButton {background-color: #AAAAAA; border: none}')
        self.b_snapshot.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.processControlGridLayout.addWidget(self.b_snapshot, 4, 0, 1, 2)

        ## Button Doxygen. Creates and opens Doxygen documentation
        self.b_doxygen = QPushButton("Doxygen")
        self.b_doxygen.setStyleSheet(
            'QPushButton {background-color: #ffa500; border: none}')
        self.b_doxygen.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.processControlGridLayout.addWidget(self.b_doxygen, 5, 0, 1, 2)

        self.batchGroupBox.setLayout(self.processControlGridLayout)

        return self.batchGroupBox

    ## @brief MainWindow::createManualGroupBox(self) creates the groupbox and the widgets in it which are used for the manual motor control.
    # @return self.manualGroupBox. This is the groupbox containing the manual control process widgets.
    def createManualGroupBox(self):
        self.manualControlGridLayout = QGridLayout()
        self.manualGroupBox = QGroupBox()
        self.manualGroupBox.setStyleSheet("color: #000000;")

        ## label of QGroupbox content
        self.gb_label = QLabel("Manual XY-control")
        self.gb_label.setStyleSheet(
            'QLabel {color: #ffffff; font-weight: bold}')
        self.gb_label.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.manualControlGridLayout.addWidget(self.gb_label, 0, 0, 1, 4,
                                               Qt.AlignHCenter)

        ## Button HOME X
        self.b_home_x = QPushButton("HOME X0 Y0")
        self.b_home_x.setStyleSheet(
            'QPushButton {background-color: #55afff; border: none}')
        self.b_home_x.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.manualControlGridLayout.addWidget(self.b_home_x, 1, 0, 1, 4)

        ## Button GET_POSITION
        self.b_get_pos = QPushButton("GET_POSITION")
        self.b_get_pos.setStyleSheet(
            'QPushButton {background-color: #55afff; border: none}')
        self.b_get_pos.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.manualControlGridLayout.addWidget(self.b_get_pos, 2, 0, 1, 4)

        ## Row selection label
        self.x_label = QLabel("X")
        self.x_label.setStyleSheet('QLabel {color: #ffffff}')
        self.x_label.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.manualControlGridLayout.addWidget(self.x_label, 3, 0, 1, 1)

        ## X position input field
        self.x_pos = QLineEdit()
        self.x_pos.setStyleSheet(
            'QLineEdit {background-color: #AAAAAA; color: #000000; border: none}'
        )
        self.x_pos.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.x_pos.setText('0.00')
        self.x_pos.setFont(QFont("Arial", 20))
        self.manualControlGridLayout.addWidget(self.x_pos, 4, 0)

        ## Row selection label
        self.y_label = QLabel("Y")
        self.y_label.setStyleSheet('QLabel {color: #ffffff}')
        self.y_label.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.manualControlGridLayout.addWidget(self.y_label, 3, 1, 1, 1)

        ## Y position input field
        self.y_pos = QLineEdit()
        self.y_pos.setStyleSheet(
            'QLineEdit {background-color: #AAAAAA; color: #000000; border: none}'
        )
        self.y_pos.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.y_pos.setText('0.00')
        self.y_pos.setFont(QFont("Arial", 20))
        self.manualControlGridLayout.addWidget(self.y_pos, 4, 1)

        ## Button goto XY
        self.b_gotoXY = QPushButton("Goto XY")
        self.b_gotoXY.setStyleSheet(
            'QPushButton {background-color: #00cc33; border: none}')
        self.b_gotoXY.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.manualControlGridLayout.addWidget(self.b_gotoXY, 5, 0, 1, 2)

        ## Row selection label
        self.row_label = QLabel("Row")
        self.row_label.setStyleSheet('QLabel {color: #ffffff}')
        self.row_label.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.manualControlGridLayout.addWidget(self.row_label, 3, 2, 1, 1)

        ## Row well combobox
        self.row_well_combo_box = QComboBox(self)
        self.row_well_combo_box.setStyleSheet(
            'QComboBox {background-color: #AAAAAA; border: none}')
        self.row_well_combo_box.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.manualControlGridLayout.addWidget(self.row_well_combo_box, 4, 2,
                                               1, 1)

        self.row_well_combo_box.addItem(str(0) + " position")
        for row in range(0, self.Well_Map.shape[0] - 1, 1):
            self.row_well_combo_box.addItem(chr(ord('A') + row))

        ## Column selection label
        self.column_label = QLabel("Column")
        self.column_label.setStyleSheet('QLabel {color: #ffffff}')
        self.column_label.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.manualControlGridLayout.addWidget(self.column_label, 3, 3, 1, 1)

        ## Column well combobox
        self.column_well_combo_box = QComboBox(self)
        self.column_well_combo_box.setStyleSheet(
            'QComboBox {background-color: #AAAAAA; border: none}')
        self.column_well_combo_box.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.manualControlGridLayout.addWidget(self.column_well_combo_box, 4,
                                               3, 1, 1)

        self.column_well_combo_box.addItem(str(0) + " position")
        for column in range(1, self.Well_Map.shape[1], 1):
            self.column_well_combo_box.addItem(str(column))

        ## Button Goto well
        self.b_goto_well = QPushButton("Goto well")
        self.b_goto_well.setStyleSheet(
            'QPushButton {background-color: #00cc33; border: none}')
        self.b_goto_well.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.manualControlGridLayout.addWidget(self.b_goto_well, 5, 2, 1, 2)

        ## Button TURN UP
        self.b_turn_up = QPushButton("^")
        self.b_turn_up.setStyleSheet(
            'QPushButton {background-color: #00cc33; border: none}')
        self.b_turn_up.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.manualControlGridLayout.addWidget(self.b_turn_up, 6, 0, 1, 4)

        ## Button TURN LEFT
        self.b_turn_left = QPushButton("<")
        self.b_turn_left.setStyleSheet(
            'QPushButton {background-color: #00cc33; border: none}')
        self.b_turn_left.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.manualControlGridLayout.addWidget(self.b_turn_left, 7, 0, 1, 2)

        ## Button TURN RIGHT
        self.b_turn_right = QPushButton(">")
        self.b_turn_right.setStyleSheet(
            'QPushButton {background-color: #00cc33; border: none}')
        self.b_turn_right.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.manualControlGridLayout.addWidget(self.b_turn_right, 7, 2, 1, 2)

        ## Button TURN DOWN
        self.b_turn_down = QPushButton("v")
        self.b_turn_down.setStyleSheet(
            'QPushButton {background-color: #00cc33; border: none}')
        self.b_turn_down.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.manualControlGridLayout.addWidget(self.b_turn_down, 8, 0, 1, 4)

        ## Button Emergency break
        self.b_emergency_break = QPushButton("Emergency break")
        self.b_emergency_break.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.b_emergency_break.setStyleSheet(
            'QPushButton {background-color: #cc0000; border: none}')
        self.manualControlGridLayout.addWidget(self.b_emergency_break, 9, 0, 1,
                                               4)
        self.manualGroupBox.setLayout(self.manualControlGridLayout)

        return self.manualGroupBox

    ## @brief MainWindow::createLogWindow(self) creates the groupbox and the log widget in it which is used for displaying debug messages.
    # @return self.logGroupBox. This is the groupbox containing the Log window widgets.
    def createLogWindow(self):
        self.logGridLayout = QGridLayout()
        self.logGroupBox = QGroupBox()
        self.logGroupBox.setStyleSheet("color: #000000;")

        ## label of QGroupbox content
        self.gb_label = QLabel("Debug information")
        self.gb_label.setStyleSheet(
            'QLabel {color: #ffffff; font-weight: bold}')
        self.gb_label.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.logGridLayout.addWidget(self.gb_label, 0, 0, 1, 1,
                                     Qt.AlignHCenter)

        ## Logger screen widget (QPlainTextEdit)
        self.log = QPlainTextEdit()
        self.log.setReadOnly(True)
        self.log.setStyleSheet("background-color: #AAAAAA;")
        self.logGridLayout.addWidget(self.log, 1, 0, 1, 1)

        self.logGroupBox.setLayout(self.logGridLayout)

        return self.logGroupBox

    ## @brief MainWindow::setBatchWindow disables buttons which should not be used during the batch process. This function is called when the batch process is started.
    @Slot()
    def setBatchWindow(self):
        self.b_snapshot.setVisible(False)
        self.b_home_x.setVisible(False)
        self.b_get_pos.setVisible(False)
        self.x_label.setVisible(False)
        self.x_pos.setVisible(False)
        self.y_label.setVisible(False)
        self.y_pos.setVisible(False)
        self.b_gotoXY.setVisible(False)
        self.row_label.setVisible(False)
        self.row_well_combo_box.setVisible(False)
        self.column_label.setVisible(False)
        self.column_well_combo_box.setVisible(False)
        self.b_goto_well.setVisible(False)
        self.b_turn_up.setVisible(False)
        self.b_turn_right.setVisible(False)
        self.b_turn_left.setVisible(False)
        self.b_turn_down.setVisible(False)
        return

    ## @brief MainWindow::setBatchWindow enables all buttons. This function is called when the batch process is stopped.
    @Slot()
    def setFullWindow(self):
        self.b_snapshot.setVisible(True)
        self.b_home_x.setVisible(True)
        self.b_get_pos.setVisible(True)
        self.x_label.setVisible(True)
        self.x_pos.setVisible(True)
        self.y_label.setVisible(True)
        self.y_pos.setVisible(True)
        self.b_gotoXY.setVisible(True)
        self.row_label.setVisible(True)
        self.row_well_combo_box.setVisible(True)
        self.column_label.setVisible(True)
        self.column_well_combo_box.setVisible(True)
        self.b_goto_well.setVisible(True)
        self.b_turn_up.setVisible(True)
        self.b_turn_right.setVisible(True)
        self.b_turn_left.setVisible(True)
        self.b_turn_down.setVisible(True)
        return

    ## @brief MainWindow::wellInitialisation(self) declares and defines the wellpositions in millimeters of the specified targets using the batch initialisation file.
    ## @author Robin Meekers
    ## @author Gert van lagen (ported to new well reader prototype software)
    def wellInitialisation(self):
        ## Declare well map
        self.Well_Map = np.empty(
            (int(self.settings_batch.value("Plate/rows")) + 1,
             int(self.settings_batch.value("Plate/columns")) + 1, 2),
            dtype=object)

        ## Position 00 on the wellplate derived from the calibration data
        self.Well_Map[0:][0:] = ((float(
            self.settings_batch.value("Plate/posColumn00"))), (float(
                self.settings_batch.value("Plate/posRow00"))))

        self.msg("Initialising well plate with " +
                 str(self.Well_Map.shape[0]) + " rows and " +
                 str(self.Well_Map.shape[1]) + " columns.")

        ## Fill Well_Map with well positions in mm based on the distances of batch.ini
        for row in range(1, self.Well_Map.shape[0], 1):
            for column in range(1, self.Well_Map.shape[1], 1):
                self.Well_Map[row][column] = (
                    (float(self.settings_batch.value("Plate/posColumn00")) +
                     float(self.settings_batch.value("Plate/p1")) +
                     ((column - 1) *
                      float(self.settings_batch.value("Plate/p2")))),
                    (float(self.settings_batch.value("Plate/posRow00")) +
                     float(self.settings_batch.value("Plate/p3")) +
                     ((row - 1) *
                      float(self.settings_batch.value("Plate/p4")))))

        ## load the wells to process
        size = self.settings_batch.beginReadArray("Wells")

        Well_KeyList = []
        for i in range(0, size):
            self.settings_batch.setArrayIndex(i)
            Well_KeyList.append(self.settings_batch.childKeys()[0])
##            val = self.settings_batch.value(key)
        self.settings_batch.endArray()

        ##        Well_KeyList = self.settings_batch.childKeys()
        print("Found (" + str(len(Well_KeyList)) + "): " + str(Well_KeyList))

        self.Well_Targets = np.empty((len(Well_KeyList), 1),
                                     dtype=[('X', 'i2'), ('Y', 'i2'),
                                            ('POS', 'U3'),
                                            ('Description', 'U100')])
        index = 0
        for Well_Key in Well_KeyList:
            Key_Characters = list(Well_Key)
            X_POS = (int(Key_Characters[1]) * 10) + (int(Key_Characters[2]))
            Y_POS = ord(Key_Characters[0].lower()) - 96
            self.Well_Targets[index] = (
                X_POS, Y_POS, str(Well_Key),
                str(self.settings_batch.value("Wells/" + Well_Key)))
            index = index + 1
        print("Well targets: ")
        print(self.Well_Targets)
        print("Well_Map:     ")
        print(self.Well_Map)
        return

    ## @brief getSec(self, time_str) converts a current_milli_time() string into seconds
    ## @param time_str is the time string to be converted
    ## @return time in seconds
    def getSec(self, time_str):
        h, m, s = time_str.split(':')
        return int(h) * 3600 + int(m) * 60 + int(s)

    ## @brief MainWindow::openSettingsIniFile(self) opens the initialisation file with the technical settings of the device.
    def openSettingsIniFile(self):
        print("\nDEBUG: in function MainWindow::openSettingsIniFile()")
        self.settings = QSettings(
            os.path.dirname(os.path.realpath(__file__)) +
            "/system_config/settings.ini", QSettings.IniFormat)
        self.msg("Opened settingsfile: " +
                 os.path.dirname(os.path.realpath(__file__)) +
                 "/system_config/settings.ini\n")
        return

    ## @brief MainWindow::openBatchIniFile(self) opens the initialisation file with the batch process settings of the device and wells.
    def openBatchIniFile(self):
        print("\nDEBUG: in function MainWindow::openBatchIniFile()")
        self.settings_batch = QSettings(
            os.path.dirname(os.path.realpath(__file__)) +
            "/system_config/batch.ini", QSettings.IniFormat)
        self.msg("Opened batch file: " +
                 os.path.dirname(os.path.realpath(__file__)) +
                 "/system_config/batch.ini\n")
        return

    ## @brief mainWindow::doxygen(self) generates Doxygen documentation and opens a chromium-browser with the ./Documentation/html/index.html documentation website.
    def doxygen(self):
        os.system(
            "cd Documentation && if [ -d "
            "html"
            " ]; then rm -r html; fi && cd ../ && doxygen Documentation/Doxyfile && chromium-browser ./Documentation/html/index.html"
        )
        self.msg("Generated Doxygen documentation")
        return

    def closeEvent(self, event):
        self.signals.windowClosing.emit()
        event.accept()
        return
예제 #33
0
 def setUp(self):
     super(QGraphicsSceneOnQVariantTest, self).setUp()
     self.s = MyDiagram()
     self.i = MyItem()
     self.combo = QComboBox()
예제 #34
0
    def createManualGroupBox(self):
        self.manualControlGridLayout = QGridLayout()
        self.manualGroupBox = QGroupBox()
        self.manualGroupBox.setStyleSheet("color: #000000;")

        ## label of QGroupbox content
        self.gb_label = QLabel("Manual XY-control")
        self.gb_label.setStyleSheet(
            'QLabel {color: #ffffff; font-weight: bold}')
        self.gb_label.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.manualControlGridLayout.addWidget(self.gb_label, 0, 0, 1, 4,
                                               Qt.AlignHCenter)

        ## Button HOME X
        self.b_home_x = QPushButton("HOME X0 Y0")
        self.b_home_x.setStyleSheet(
            'QPushButton {background-color: #55afff; border: none}')
        self.b_home_x.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.manualControlGridLayout.addWidget(self.b_home_x, 1, 0, 1, 4)

        ## Button GET_POSITION
        self.b_get_pos = QPushButton("GET_POSITION")
        self.b_get_pos.setStyleSheet(
            'QPushButton {background-color: #55afff; border: none}')
        self.b_get_pos.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.manualControlGridLayout.addWidget(self.b_get_pos, 2, 0, 1, 4)

        ## Row selection label
        self.x_label = QLabel("X")
        self.x_label.setStyleSheet('QLabel {color: #ffffff}')
        self.x_label.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.manualControlGridLayout.addWidget(self.x_label, 3, 0, 1, 1)

        ## X position input field
        self.x_pos = QLineEdit()
        self.x_pos.setStyleSheet(
            'QLineEdit {background-color: #AAAAAA; color: #000000; border: none}'
        )
        self.x_pos.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.x_pos.setText('0.00')
        self.x_pos.setFont(QFont("Arial", 20))
        self.manualControlGridLayout.addWidget(self.x_pos, 4, 0)

        ## Row selection label
        self.y_label = QLabel("Y")
        self.y_label.setStyleSheet('QLabel {color: #ffffff}')
        self.y_label.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.manualControlGridLayout.addWidget(self.y_label, 3, 1, 1, 1)

        ## Y position input field
        self.y_pos = QLineEdit()
        self.y_pos.setStyleSheet(
            'QLineEdit {background-color: #AAAAAA; color: #000000; border: none}'
        )
        self.y_pos.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.y_pos.setText('0.00')
        self.y_pos.setFont(QFont("Arial", 20))
        self.manualControlGridLayout.addWidget(self.y_pos, 4, 1)

        ## Button goto XY
        self.b_gotoXY = QPushButton("Goto XY")
        self.b_gotoXY.setStyleSheet(
            'QPushButton {background-color: #00cc33; border: none}')
        self.b_gotoXY.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.manualControlGridLayout.addWidget(self.b_gotoXY, 5, 0, 1, 2)

        ## Row selection label
        self.row_label = QLabel("Row")
        self.row_label.setStyleSheet('QLabel {color: #ffffff}')
        self.row_label.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.manualControlGridLayout.addWidget(self.row_label, 3, 2, 1, 1)

        ## Row well combobox
        self.row_well_combo_box = QComboBox(self)
        self.row_well_combo_box.setStyleSheet(
            'QComboBox {background-color: #AAAAAA; border: none}')
        self.row_well_combo_box.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.manualControlGridLayout.addWidget(self.row_well_combo_box, 4, 2,
                                               1, 1)

        self.row_well_combo_box.addItem(str(0) + " position")
        for row in range(0, self.Well_Map.shape[0] - 1, 1):
            self.row_well_combo_box.addItem(chr(ord('A') + row))

        ## Column selection label
        self.column_label = QLabel("Column")
        self.column_label.setStyleSheet('QLabel {color: #ffffff}')
        self.column_label.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.manualControlGridLayout.addWidget(self.column_label, 3, 3, 1, 1)

        ## Column well combobox
        self.column_well_combo_box = QComboBox(self)
        self.column_well_combo_box.setStyleSheet(
            'QComboBox {background-color: #AAAAAA; border: none}')
        self.column_well_combo_box.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.manualControlGridLayout.addWidget(self.column_well_combo_box, 4,
                                               3, 1, 1)

        self.column_well_combo_box.addItem(str(0) + " position")
        for column in range(1, self.Well_Map.shape[1], 1):
            self.column_well_combo_box.addItem(str(column))

        ## Button Goto well
        self.b_goto_well = QPushButton("Goto well")
        self.b_goto_well.setStyleSheet(
            'QPushButton {background-color: #00cc33; border: none}')
        self.b_goto_well.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.manualControlGridLayout.addWidget(self.b_goto_well, 5, 2, 1, 2)

        ## Button TURN UP
        self.b_turn_up = QPushButton("^")
        self.b_turn_up.setStyleSheet(
            'QPushButton {background-color: #00cc33; border: none}')
        self.b_turn_up.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.manualControlGridLayout.addWidget(self.b_turn_up, 6, 0, 1, 4)

        ## Button TURN LEFT
        self.b_turn_left = QPushButton("<")
        self.b_turn_left.setStyleSheet(
            'QPushButton {background-color: #00cc33; border: none}')
        self.b_turn_left.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.manualControlGridLayout.addWidget(self.b_turn_left, 7, 0, 1, 2)

        ## Button TURN RIGHT
        self.b_turn_right = QPushButton(">")
        self.b_turn_right.setStyleSheet(
            'QPushButton {background-color: #00cc33; border: none}')
        self.b_turn_right.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.manualControlGridLayout.addWidget(self.b_turn_right, 7, 2, 1, 2)

        ## Button TURN DOWN
        self.b_turn_down = QPushButton("v")
        self.b_turn_down.setStyleSheet(
            'QPushButton {background-color: #00cc33; border: none}')
        self.b_turn_down.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.manualControlGridLayout.addWidget(self.b_turn_down, 8, 0, 1, 4)

        ## Button Emergency break
        self.b_emergency_break = QPushButton("Emergency break")
        self.b_emergency_break.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.b_emergency_break.setStyleSheet(
            'QPushButton {background-color: #cc0000; border: none}')
        self.manualControlGridLayout.addWidget(self.b_emergency_break, 9, 0, 1,
                                               4)
        self.manualGroupBox.setLayout(self.manualControlGridLayout)

        return self.manualGroupBox
예제 #35
0
 def __init__(self, parent=None):
     QComboBox.__init__(self, parent)
     self.setEditable(True)
예제 #36
0
class LabeledComboBox(QWidget):
    currentTextChanged = Signal(str)

    def __init__(self, label_string, items=[]):
        super(LabeledComboBox, self).__init__()
        self.label = QLabel(label_string)
        self.combo_box = QComboBox(self)
        self.items = items
        for item in self.items:
            self.combo_box.addItem(item)
        self.previous_item = [None, None]
        self.combo_box.currentTextChanged.connect(self._currentTextChanged)

        ComboBoxLayout = QVBoxLayout(self)
        ComboBoxLayout.addWidget(self.label)
        ComboBoxLayout.addWidget(self.combo_box)

    def currentText(self):
        return self.combo_box.currentText()

    def _currentTextChanged(self, text):
        self.previous_item = [
            self.previous_item[1],
            self.combo_box.currentText()
        ]
        self.currentTextChanged.emit(text)

    def revert(self):
        self.setCurrentText(self.previous_item[0], quiet=True)
        self.previous_item = [None, self.previous_item[0]]

    def setCurrentText(self, value, quiet=False):
        if quiet:
            self.combo_box.blockSignals(True)
            self.combo_box.setCurrentText(value)
            self.combo_box.blockSignals(False)
        else:
            self.combo_box.setCurrentText(value)
예제 #37
0
파일: export.py 프로젝트: strohne/Facepager
    def __init__(self,*args,**kwargs):
        super(ExportFileDialog,self).__init__(*args,**kwargs)

        self.mainWindow = self.parent()
        self.setWindowTitle("Export nodes to CSV")
        self.setAcceptMode(QFileDialog.AcceptSave)
        self.setOption(QFileDialog.DontUseNativeDialog)
        #self.setFilter("CSV Files (*.csv)")
        self.setDefaultSuffix("csv")

        self.optionBOM = QCheckBox("Use a BOM",self)
        self.optionBOM.setCheckState(Qt.CheckState.Checked)

        self.optionLinebreaks = QCheckBox("Remove line breaks",self)
        self.optionLinebreaks.setCheckState(Qt.CheckState.Checked)

        self.optionSeparator = QComboBox(self)
        self.optionSeparator.insertItems(0, [";","\\t",","])
        self.optionSeparator.setEditable(True)

        #self.optionLinebreaks.setCheckState(Qt.CheckState.Checked)

        self.optionWide = QCheckBox("Convert to wide format (experimental feature)",self)
        self.optionWide.setCheckState(Qt.CheckState.Unchecked)

        # if none or all are selected, export all
        # if one or more are selected, export selective
        self.optionAll = QComboBox(self)
        self.optionAll.insertItems(0, ['All nodes (faster for large datasets, ordered by internal ID)','Selected nodes (ordered like shown in nodes view)'])
        if self.mainWindow.tree.noneOrAllSelected():
            self.optionAll.setCurrentIndex(0)
        else:
            self.optionAll.setCurrentIndex(1)

        layout = self.layout()
        row = layout.rowCount()
        layout.addWidget(QLabel('Options'),row,0)

        options = QHBoxLayout()
        options.addWidget(self.optionBOM)
        options.addWidget(self.optionLinebreaks)
        options.addWidget(QLabel('Separator'))
        options.addWidget(self.optionSeparator)
        options.addStretch(1)

        layout.addLayout(options,row,1,1,2)

        layout.addWidget(QLabel('Post processing'),row+1,0)
        layout.addWidget(self.optionWide,row+1,1,1,2)

        layout.addWidget(QLabel('Export mode'),row+2,0)
        layout.addWidget(self.optionAll,row+2,1,1,2)
        self.setLayout(layout)

        if self.exec_():

            if os.path.isfile(self.selectedFiles()[0]):
                os.remove(self.selectedFiles()[0])
            output = open(self.selectedFiles()[0], 'w', newline='', encoding='utf8')
            if self.optionBOM.isChecked() and not self.optionWide.isChecked():
                output.write('\ufeff')

            try:
                if self.optionAll.currentIndex() == 0:
                    self.exportAllNodes(output)
                else:
                    self.exportSelectedNodes(output)
            finally:
                output.close()

            if self.optionWide.isChecked():
                self.convertToWideFormat(self.selectedFiles()[0])
예제 #38
0
class AudioTest(QMainWindow):

    PUSH_MODE_LABEL = "Enable push mode"
    PULL_MODE_LABEL = "Enable pull mode"
    SUSPEND_LABEL = "Suspend playback"
    RESUME_LABEL = "Resume playback"

    DurationSeconds = 1
    ToneSampleRateHz = 600
    DataSampleRateHz = 44100

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

        self.m_device = QAudioDeviceInfo.defaultOutputDevice()
        self.m_output = None

        self.initializeWindow()
        self.initializeAudio()

    def initializeWindow(self):
        layout = QVBoxLayout()

        self.m_deviceBox = QComboBox()
        self.m_deviceBox.activated[int].connect(self.deviceChanged)
        for deviceInfo in QAudioDeviceInfo.availableDevices(QAudio.AudioOutput):
            self.m_deviceBox.addItem(deviceInfo.deviceName(), deviceInfo)

        layout.addWidget(self.m_deviceBox)

        self.m_modeButton = QPushButton()
        self.m_modeButton.clicked.connect(self.toggleMode)
        self.m_modeButton.setText(self.PUSH_MODE_LABEL)

        layout.addWidget(self.m_modeButton)

        self.m_suspendResumeButton = QPushButton(
                clicked=self.toggleSuspendResume)
        self.m_suspendResumeButton.setText(self.SUSPEND_LABEL)

        layout.addWidget(self.m_suspendResumeButton)

        volumeBox = QHBoxLayout()
        volumeLabel = QLabel("Volume:")
        self.m_volumeSlider = QSlider(Qt.Horizontal, minimum=0, maximum=100,
                singleStep=10)
        self.m_volumeSlider.valueChanged.connect(self.volumeChanged)

        volumeBox.addWidget(volumeLabel)
        volumeBox.addWidget(self.m_volumeSlider)

        layout.addLayout(volumeBox)

        window = QWidget()
        window.setLayout(layout)

        self.setCentralWidget(window)

    def initializeAudio(self):
        self.m_pullTimer = QTimer(self)
        self.m_pullTimer.timeout.connect(self.pullTimerExpired)
        self.m_pullMode = True

        self.m_format = QAudioFormat()
        self.m_format.setSampleRate(self.DataSampleRateHz)
        self.m_format.setChannelCount(1)
        self.m_format.setSampleSize(16)
        self.m_format.setCodec('audio/pcm')
        self.m_format.setByteOrder(QAudioFormat.LittleEndian)
        self.m_format.setSampleType(QAudioFormat.SignedInt)

        info = QAudioDeviceInfo(QAudioDeviceInfo.defaultOutputDevice())
        if not info.isFormatSupported(self.m_format):
            qWarning("Default format not supported - trying to use nearest")
            self.m_format = info.nearestFormat(self.m_format)

        self.m_generator = Generator(self.m_format,
                self.DurationSeconds * 1000000, self.ToneSampleRateHz, self)

        self.createAudioOutput()

    def createAudioOutput(self):
        self.m_audioOutput = QAudioOutput(self.m_device, self.m_format)
        self.m_audioOutput.notify.connect(self.notified)
        self.m_audioOutput.stateChanged.connect(self.handleStateChanged)

        self.m_generator.start()
        self.m_audioOutput.start(self.m_generator)
        self.m_volumeSlider.setValue(self.m_audioOutput.volume() * 100)

    def deviceChanged(self, index):
        self.m_pullTimer.stop()
        self.m_generator.stop()
        self.m_audioOutput.stop()
        self.m_device = self.m_deviceBox.itemData(index)

        self.createAudioOutput()

    def volumeChanged(self, value):
        if self.m_audioOutput is not None:
            self.m_audioOutput.setVolume(value / 100.0)

    def notified(self):
        qWarning("bytesFree = %d, elapsedUSecs = %d, processedUSecs = %d" % (
                self.m_audioOutput.bytesFree(),
                self.m_audioOutput.elapsedUSecs(),
                self.m_audioOutput.processedUSecs()))

    def pullTimerExpired(self):
        if self.m_audioOutput is not None and self.m_audioOutput.state() != QAudio.StoppedState:
            chunks = self.m_audioOutput.bytesFree() // self.m_audioOutput.periodSize()
            for _ in range(chunks):
                data = self.m_generator.read(self.m_audioOutput.periodSize())
                if data is None or len(data) != self.m_audioOutput.periodSize():
                    break

                self.m_output.write(data)

    def toggleMode(self):
        self.m_pullTimer.stop()
        self.m_audioOutput.stop()

        if self.m_pullMode:
            self.m_modeButton.setText(self.PULL_MODE_LABEL)
            self.m_output = self.m_audioOutput.start()
            self.m_pullMode = False
            self.m_pullTimer.start(20)
        else:
            self.m_modeButton.setText(self.PUSH_MODE_LABEL)
            self.m_pullMode = True
            self.m_audioOutput.start(self.m_generator)

        self.m_suspendResumeButton.setText(self.SUSPEND_LABEL)

    def toggleSuspendResume(self):
        if self.m_audioOutput.state() == QAudio.SuspendedState:
            qWarning("status: Suspended, resume()")
            self.m_audioOutput.resume()
            self.m_suspendResumeButton.setText(self.SUSPEND_LABEL)
        elif self.m_audioOutput.state() == QAudio.ActiveState:
            qWarning("status: Active, suspend()")
            self.m_audioOutput.suspend()
            self.m_suspendResumeButton.setText(self.RESUME_LABEL)
        elif self.m_audioOutput.state() == QAudio.StoppedState:
            qWarning("status: Stopped, resume()")
            self.m_audioOutput.resume()
            self.m_suspendResumeButton.setText(self.SUSPEND_LABEL)
        elif self.m_audioOutput.state() == QAudio.IdleState:
            qWarning("status: IdleState")

    stateMap = {
        QAudio.ActiveState: "ActiveState",
        QAudio.SuspendedState: "SuspendedState",
        QAudio.StoppedState: "StoppedState",
        QAudio.IdleState: "IdleState"}

    def handleStateChanged(self, state):
        qWarning("state = " + self.stateMap.get(state, "Unknown"))
예제 #39
0
class ColorDialog(QDialog):

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

        self.setWindowTitle('Color Options')

        self.model = model
        self.font_metric = font_metric
        self.main_window = parent

        self.createDialogLayout()

    def createDialogLayout(self):

        self.createGeneralTab()

        self.cellTable = self.createDomainTable(self.main_window.cellsModel)
        self.matTable = self.createDomainTable(self.main_window.materialsModel)
        self.tabs = {'cell': self.createDomainTab(self.cellTable),
                     'material': self.createDomainTab(self.matTable),
                     'temperature': self.createPropertyTab('temperature'),
                     'density': self.createPropertyTab('density')}

        self.tab_bar = QTabWidget()
        self.tab_bar.setMaximumHeight(800)
        self.tab_bar.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.tab_bar.addTab(self.generalTab, 'General')
        self.tab_bar.addTab(self.tabs['cell'], 'Cells')
        self.tab_bar.addTab(self.tabs['material'], 'Materials')
        self.tab_bar.addTab(self.tabs['temperature'], 'Temperature')
        self.tab_bar.addTab(self.tabs['density'], 'Density')

        self.createButtonBox()

        self.colorDialogLayout = QVBoxLayout()
        self.colorDialogLayout.addWidget(self.tab_bar)
        self.colorDialogLayout.addWidget(self.buttonBox)
        self.setLayout(self.colorDialogLayout)

    def createGeneralTab(self):

        main_window = self.main_window

        # Masking options
        self.maskingCheck = QCheckBox('')
        self.maskingCheck.stateChanged.connect(main_window.toggleMasking)

        self.maskColorButton = QPushButton()
        self.maskColorButton.setCursor(QtCore.Qt.PointingHandCursor)
        self.maskColorButton.setFixedWidth(self.font_metric.width("XXXXXXXXXX"))
        self.maskColorButton.setFixedHeight(self.font_metric.height() * 1.5)
        self.maskColorButton.clicked.connect(main_window.editMaskingColor)

        # Highlighting options
        self.hlCheck = QCheckBox('')
        self.hlCheck.stateChanged.connect(main_window.toggleHighlighting)

        self.hlColorButton = QPushButton()
        self.hlColorButton.setCursor(QtCore.Qt.PointingHandCursor)
        self.hlColorButton.setFixedWidth(self.font_metric.width("XXXXXXXXXX"))
        self.hlColorButton.setFixedHeight(self.font_metric.height() * 1.5)
        self.hlColorButton.clicked.connect(main_window.editHighlightColor)

        self.alphaBox = QDoubleSpinBox()
        self.alphaBox.setRange(0, 1)
        self.alphaBox.setSingleStep(.05)
        self.alphaBox.valueChanged.connect(main_window.editAlpha)

        self.seedBox = QSpinBox()
        self.seedBox.setRange(1, 999)
        self.seedBox.valueChanged.connect(main_window.editSeed)

        # General options
        self.bgButton = QPushButton()
        self.bgButton.setCursor(QtCore.Qt.PointingHandCursor)
        self.bgButton.setFixedWidth(self.font_metric.width("XXXXXXXXXX"))
        self.bgButton.setFixedHeight(self.font_metric.height() * 1.5)
        self.bgButton.clicked.connect(main_window.editBackgroundColor)

        self.colorbyBox = QComboBox(self)
        self.colorbyBox.addItem("material")
        self.colorbyBox.addItem("cell")
        self.colorbyBox.addItem("temperature")
        self.colorbyBox.addItem("density")

        # Overlap plotting
        self.overlapCheck = QCheckBox('', self)
        overlap_connector = partial(main_window.toggleOverlaps)
        self.overlapCheck.stateChanged.connect(overlap_connector)

        self.overlapColorButton = QPushButton()
        self.overlapColorButton.setCursor(QtCore.Qt.PointingHandCursor)
        self.overlapColorButton.setFixedWidth(self.font_metric.width("XXXXXXXXXX"))
        self.overlapColorButton.setFixedHeight(self.font_metric.height() * 1.5)
        self.overlapColorButton.clicked.connect(main_window.editOverlapColor)

        self.colorbyBox.currentTextChanged[str].connect(main_window.editColorBy)

        self.colorResetButton = QPushButton("&Reset Colors")
        self.colorResetButton.setCursor(QtCore.Qt.PointingHandCursor)
        self.colorResetButton.clicked.connect(main_window.resetColors)

        formLayout = QFormLayout()
        formLayout.setAlignment(QtCore.Qt.AlignHCenter)
        formLayout.setFormAlignment(QtCore.Qt.AlignHCenter)
        formLayout.setLabelAlignment(QtCore.Qt.AlignLeft)

        formLayout.addRow('Masking:', self.maskingCheck)
        formLayout.addRow('Mask Color:', self.maskColorButton)
        formLayout.addRow(HorizontalLine())
        formLayout.addRow('Highlighting:', self.hlCheck)
        formLayout.addRow('Highlight Color:', self.hlColorButton)
        formLayout.addRow('Highlight Alpha:', self.alphaBox)
        formLayout.addRow('Highlight Seed:', self.seedBox)
        formLayout.addRow(HorizontalLine())
        formLayout.addRow('Background Color:          ', self.bgButton)
        formLayout.addRow(HorizontalLine())
        formLayout.addRow('Show Overlaps:', self.overlapCheck)
        formLayout.addRow('OVerlap Color:', self.overlapColorButton)
        formLayout.addRow(HorizontalLine())
        formLayout.addRow('Color Plot By:', self.colorbyBox)
        formLayout.addRow(self.colorResetButton, None)

        generalLayout = QHBoxLayout()
        innerWidget = QWidget()
        generalLayout.setAlignment(QtCore.Qt.AlignVCenter)
        innerWidget.setLayout(formLayout)
        generalLayout.addStretch(1)
        generalLayout.addWidget(innerWidget)
        generalLayout.addStretch(1)

        self.generalTab = QWidget()
        self.generalTab.setLayout(generalLayout)

    def createDomainTable(self, domainmodel):

        domainTable = QTableView()
        domainTable.setModel(domainmodel)
        domainTable.setItemDelegate(DomainDelegate(domainTable))
        domainTable.verticalHeader().setVisible(False)
        domainTable.resizeColumnsToContents()
        domainTable.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        domainTable.horizontalHeader().setSectionResizeMode(1, QHeaderView.Stretch)

        return domainTable

    def createDomainTab(self, domaintable):

        domainTab = QWidget()
        domainTab.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        domainLayout = QVBoxLayout()
        domainLayout.addWidget(domaintable)
        domainTab.setLayout(domainLayout)

        return domainTab

    def createPropertyTab(self, property_kind):
        propertyTab = QWidget()
        propertyTab.property_kind = property_kind
        propertyTab.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        propertyLayout = QVBoxLayout()

        propertyTab.minMaxCheckBox = QCheckBox()
        propertyTab.minMaxCheckBox.setCheckable(True)
        connector1 = partial(self.main_window.toggleUserMinMax,
                             property=property_kind)
        propertyTab.minMaxCheckBox.stateChanged.connect(connector1)

        propertyTab.minBox = ScientificDoubleSpinBox(self)
        propertyTab.minBox.setMaximum(1E9)
        propertyTab.minBox.setMinimum(0)
        propertyTab.maxBox = ScientificDoubleSpinBox(self)
        propertyTab.maxBox.setMaximum(1E9)
        propertyTab.maxBox.setMinimum(0)

        connector2 = partial(self.main_window.editColorbarMin,
                             property_type=property_kind)
        propertyTab.minBox.valueChanged.connect(connector2)
        connector3 = partial(self.main_window.editColorbarMax,
                             property_type=property_kind)
        propertyTab.maxBox.valueChanged.connect(connector3)

        propertyTab.colormapBox = QComboBox(self)
        cmaps = sorted(m for m in mcolormaps.datad if not m.endswith("_r"))
        for cmap in cmaps:
            propertyTab.colormapBox.addItem(cmap)

        connector = partial(self.main_window.editColorMap,
                            property_type=property_kind)

        propertyTab.colormapBox.currentTextChanged[str].connect(connector)

        propertyTab.dataIndicatorCheckBox = QCheckBox()
        propertyTab.dataIndicatorCheckBox.setCheckable(True)
        connector4 = partial(self.main_window.toggleDataIndicatorCheckBox,
                             property=property_kind)
        propertyTab.dataIndicatorCheckBox.stateChanged.connect(connector4)

        propertyTab.colorBarScaleCheckBox = QCheckBox()
        propertyTab.colorBarScaleCheckBox.setCheckable(True)
        connector5 = partial(self.main_window.toggleColorbarScale,
                             property=property_kind)
        propertyTab.colorBarScaleCheckBox.stateChanged.connect(connector5)

        formLayout = QFormLayout()
        formLayout.setAlignment(QtCore.Qt.AlignHCenter)
        formLayout.setFormAlignment(QtCore.Qt.AlignHCenter)
        formLayout.setLabelAlignment(QtCore.Qt.AlignLeft)

        formLayout.addRow('Colormap:', propertyTab.colormapBox)

        formLayout.addRow('Custom Min/Max', propertyTab.minMaxCheckBox)
        formLayout.addRow('Data Indicator', propertyTab.dataIndicatorCheckBox)
        formLayout.addRow('Log Scale', propertyTab.colorBarScaleCheckBox)
        formLayout.addRow(HorizontalLine())
        formLayout.addRow('Max: ', propertyTab.maxBox)
        formLayout.addRow('Min: ', propertyTab.minBox)

        propertyTab.setLayout(formLayout)

        return propertyTab

    def updateDataIndicatorVisibility(self):
        av = self.model.activeView
        for key, val in av.data_indicator_enabled.items():
            self.tabs[key].dataIndicatorCheckBox.setChecked(val)

    def updateColorMaps(self):
        cmaps = self.model.activeView.colormaps
        for key, val in cmaps.items():
            idx = self.tabs[key].colormapBox.findText(
                    val,
                    QtCore.Qt.MatchFixedString)
            if idx >= 0:
                self.tabs[key].colormapBox.setCurrentIndex(idx)

    def updateColorMinMax(self):
        minmax = self.model.activeView.user_minmax
        for key, val in minmax.items():
            self.tabs[key].minBox.setValue(val[0])
            self.tabs[key].maxBox.setValue(val[1])
        custom_minmax = self.model.activeView.use_custom_minmax
        for key, val, in custom_minmax.items():
            self.tabs[key].minMaxCheckBox.setChecked(val)
            self.tabs[key].minBox.setEnabled(val)
            self.tabs[key].maxBox.setEnabled(val)

    def updateColorbarScale(self):
        av = self.model.activeView
        for key, val in av.color_scale_log.items():
            self.tabs[key].colorBarScaleCheckBox.setChecked(val)

    def createButtonBox(self):

        applyButton = QPushButton("Apply Changes")
        applyButton.clicked.connect(self.main_window.applyChanges)
        closeButton = QPushButton("Close")
        closeButton.clicked.connect(self.hide)

        buttonLayout = QHBoxLayout()
        buttonLayout.addStretch(1)
        buttonLayout.addWidget(applyButton)
        buttonLayout.addWidget(closeButton)

        self.buttonBox = QWidget()
        self.buttonBox.setLayout(buttonLayout)

    def updateDialogValues(self):

        self.updateMasking()
        self.updateMaskingColor()
        self.updateColorMaps()
        self.updateColorMinMax()
        self.updateColorbarScale()
        self.updateDataIndicatorVisibility()
        self.updateHighlighting()
        self.updateHighlightColor()
        self.updateAlpha()
        self.updateSeed()
        self.updateBackgroundColor()
        self.updateColorBy()
        self.updateDomainTabs()
        self.updateOverlap()
        self.updateOverlapColor()

    def updateMasking(self):
        masking = self.model.activeView.masking

        self.maskingCheck.setChecked(masking)
        self.maskColorButton.setDisabled(not masking)

        if masking:
            self.cellTable.showColumn(4)
            self.matTable.showColumn(4)
        else:
            self.cellTable.hideColumn(4)
            self.matTable.hideColumn(4)

    def updateMaskingColor(self):
        color = self.model.activeView.maskBackground
        style_values = "border-radius: 8px; background-color: rgb{}"
        self.maskColorButton.setStyleSheet(style_values.format(str(color)))

    def updateHighlighting(self):
        highlighting = self.model.activeView.highlighting

        self.hlCheck.setChecked(highlighting)
        self.hlColorButton.setDisabled(not highlighting)
        self.alphaBox.setDisabled(not highlighting)
        self.seedBox.setDisabled(not highlighting)

        if highlighting:
            self.cellTable.showColumn(5)
            self.cellTable.hideColumn(2)
            self.cellTable.hideColumn(3)
            self.matTable.showColumn(5)
            self.matTable.hideColumn(2)
            self.matTable.hideColumn(3)
        else:
            self.cellTable.hideColumn(5)
            self.cellTable.showColumn(2)
            self.cellTable.showColumn(3)
            self.matTable.hideColumn(5)
            self.matTable.showColumn(2)
            self.matTable.showColumn(3)

    def updateHighlightColor(self):
        color = self.model.activeView.highlightBackground
        style_values = "border-radius: 8px; background-color: rgb{}"
        self.hlColorButton.setStyleSheet(style_values.format(str(color)))

    def updateAlpha(self):
        self.alphaBox.setValue(self.model.activeView.highlightAlpha)

    def updateSeed(self):
        self.seedBox.setValue(self.model.activeView.highlightSeed)

    def updateBackgroundColor(self):
        color = self.model.activeView.domainBackground
        self.bgButton.setStyleSheet("border-radius: 8px;"
                                    "background-color: rgb%s" % (str(color)))

    def updateOverlapColor(self):
        color = self.model.activeView.overlap_color
        self.overlapColorButton.setStyleSheet("border-radius: 8px;"
                                              "background-color: rgb%s" % (str(color)))

    def updateOverlap(self):
        colorby = self.model.activeView.colorby
        overlap_val = self.model.activeView.color_overlaps
        if colorby in ('cell', 'material'):
            self.overlapCheck.setChecked(overlap_val)

    def updateColorBy(self):
        colorby = self.model.activeView.colorby
        self.colorbyBox.setCurrentText(colorby)
        self.overlapCheck.setEnabled(colorby in ("cell", "material"))

    def updateDomainTabs(self):
        self.cellTable.setModel(self.main_window.cellsModel)
        self.matTable.setModel(self.main_window.materialsModel)
예제 #40
0
class Window(QWidget):
    def __init__(self):
        super(Window, self).__init__()

        self.renderArea = RenderArea()

        self.shapeComboBox = QComboBox()
        self.shapeComboBox.addItem("Polygon", RenderArea.Polygon)
        self.shapeComboBox.addItem("Rectangle", RenderArea.Rect)
        self.shapeComboBox.addItem("Rounded Rectangle", RenderArea.RoundedRect)
        self.shapeComboBox.addItem("Ellipse", RenderArea.Ellipse)
        self.shapeComboBox.addItem("Pie", RenderArea.Pie)
        self.shapeComboBox.addItem("Chord", RenderArea.Chord)
        self.shapeComboBox.addItem("Path", RenderArea.Path)
        self.shapeComboBox.addItem("Line", RenderArea.Line)
        self.shapeComboBox.addItem("Polyline", RenderArea.Polyline)
        self.shapeComboBox.addItem("Arc", RenderArea.Arc)
        self.shapeComboBox.addItem("Points", RenderArea.Points)
        self.shapeComboBox.addItem("Text", RenderArea.Text)
        self.shapeComboBox.addItem("Pixmap", RenderArea.Pixmap)

        shapeLabel = QLabel("&Shape:")
        shapeLabel.setBuddy(self.shapeComboBox)

        self.penWidthSpinBox = QSpinBox()
        self.penWidthSpinBox.setRange(0, 20)
        self.penWidthSpinBox.setSpecialValueText("0 (cosmetic pen)")

        penWidthLabel = QLabel("Pen &Width:")
        penWidthLabel.setBuddy(self.penWidthSpinBox)

        self.penStyleComboBox = QComboBox()
        self.penStyleComboBox.addItem("Solid", Qt.SolidLine)
        self.penStyleComboBox.addItem("Dash", Qt.DashLine)
        self.penStyleComboBox.addItem("Dot", Qt.DotLine)
        self.penStyleComboBox.addItem("Dash Dot", Qt.DashDotLine)
        self.penStyleComboBox.addItem("Dash Dot Dot", Qt.DashDotDotLine)
        self.penStyleComboBox.addItem("None", Qt.NoPen)

        penStyleLabel = QLabel("&Pen Style:")
        penStyleLabel.setBuddy(self.penStyleComboBox)

        self.penCapComboBox = QComboBox()
        self.penCapComboBox.addItem("Flat", Qt.FlatCap)
        self.penCapComboBox.addItem("Square", Qt.SquareCap)
        self.penCapComboBox.addItem("Round", Qt.RoundCap)

        penCapLabel = QLabel("Pen &Cap:")
        penCapLabel.setBuddy(self.penCapComboBox)

        self.penJoinComboBox = QComboBox()
        self.penJoinComboBox.addItem("Miter", Qt.MiterJoin)
        self.penJoinComboBox.addItem("Bevel", Qt.BevelJoin)
        self.penJoinComboBox.addItem("Round", Qt.RoundJoin)

        penJoinLabel = QLabel("Pen &Join:")
        penJoinLabel.setBuddy(self.penJoinComboBox)

        self.brushStyleComboBox = QComboBox()
        self.brushStyleComboBox.addItem("Linear Gradient",
                Qt.LinearGradientPattern)
        self.brushStyleComboBox.addItem("Radial Gradient",
                Qt.RadialGradientPattern)
        self.brushStyleComboBox.addItem("Conical Gradient",
                Qt.ConicalGradientPattern)
        self.brushStyleComboBox.addItem("Texture", Qt.TexturePattern)
        self.brushStyleComboBox.addItem("Solid", Qt.SolidPattern)
        self.brushStyleComboBox.addItem("Horizontal", Qt.HorPattern)
        self.brushStyleComboBox.addItem("Vertical", Qt.VerPattern)
        self.brushStyleComboBox.addItem("Cross", Qt.CrossPattern)
        self.brushStyleComboBox.addItem("Backward Diagonal", Qt.BDiagPattern)
        self.brushStyleComboBox.addItem("Forward Diagonal", Qt.FDiagPattern)
        self.brushStyleComboBox.addItem("Diagonal Cross", Qt.DiagCrossPattern)
        self.brushStyleComboBox.addItem("Dense 1", Qt.Dense1Pattern)
        self.brushStyleComboBox.addItem("Dense 2", Qt.Dense2Pattern)
        self.brushStyleComboBox.addItem("Dense 3", Qt.Dense3Pattern)
        self.brushStyleComboBox.addItem("Dense 4", Qt.Dense4Pattern)
        self.brushStyleComboBox.addItem("Dense 5", Qt.Dense5Pattern)
        self.brushStyleComboBox.addItem("Dense 6", Qt.Dense6Pattern)
        self.brushStyleComboBox.addItem("Dense 7", Qt.Dense7Pattern)
        self.brushStyleComboBox.addItem("None", Qt.NoBrush)

        brushStyleLabel = QLabel("&Brush Style:")
        brushStyleLabel.setBuddy(self.brushStyleComboBox)

        otherOptionsLabel = QLabel("Other Options:")
        self.antialiasingCheckBox = QCheckBox("&Antialiasing")
        self.transformationsCheckBox = QCheckBox("&Transformations")

        self.shapeComboBox.activated.connect(self.shapeChanged)
        self.penWidthSpinBox.valueChanged.connect(self.penChanged)
        self.penStyleComboBox.activated.connect(self.penChanged)
        self.penCapComboBox.activated.connect(self.penChanged)
        self.penJoinComboBox.activated.connect(self.penChanged)
        self.brushStyleComboBox.activated.connect(self.brushChanged)
        self.antialiasingCheckBox.toggled.connect(self.renderArea.setAntialiased)
        self.transformationsCheckBox.toggled.connect(self.renderArea.setTransformed)

        mainLayout = QGridLayout()
        mainLayout.setColumnStretch(0, 1)
        mainLayout.setColumnStretch(3, 1)
        mainLayout.addWidget(self.renderArea, 0, 0, 1, 4)
        mainLayout.setRowMinimumHeight(1, 6)
        mainLayout.addWidget(shapeLabel, 2, 1, Qt.AlignRight)
        mainLayout.addWidget(self.shapeComboBox, 2, 2)
        mainLayout.addWidget(penWidthLabel, 3, 1, Qt.AlignRight)
        mainLayout.addWidget(self.penWidthSpinBox, 3, 2)
        mainLayout.addWidget(penStyleLabel, 4, 1, Qt.AlignRight)
        mainLayout.addWidget(self.penStyleComboBox, 4, 2)
        mainLayout.addWidget(penCapLabel, 5, 1, Qt.AlignRight)
        mainLayout.addWidget(self.penCapComboBox, 5, 2)
        mainLayout.addWidget(penJoinLabel, 6, 1, Qt.AlignRight)
        mainLayout.addWidget(self.penJoinComboBox, 6, 2)
        mainLayout.addWidget(brushStyleLabel, 7, 1, Qt.AlignRight)
        mainLayout.addWidget(self.brushStyleComboBox, 7, 2)
        mainLayout.setRowMinimumHeight(8, 6)
        mainLayout.addWidget(otherOptionsLabel, 9, 1, Qt.AlignRight)
        mainLayout.addWidget(self.antialiasingCheckBox, 9, 2)
        mainLayout.addWidget(self.transformationsCheckBox, 10, 2)
        self.setLayout(mainLayout)

        self.shapeChanged()
        self.penChanged()
        self.brushChanged()
        self.antialiasingCheckBox.setChecked(True)

        self.setWindowTitle("Basic Drawing")

    def shapeChanged(self):
        shape = self.shapeComboBox.itemData(self.shapeComboBox.currentIndex(),
                IdRole)
        self.renderArea.setShape(shape)

    def penChanged(self):
        width = self.penWidthSpinBox.value()
        style = Qt.PenStyle(self.penStyleComboBox.itemData(
                self.penStyleComboBox.currentIndex(), IdRole))
        cap = Qt.PenCapStyle(self.penCapComboBox.itemData(
                self.penCapComboBox.currentIndex(), IdRole))
        join = Qt.PenJoinStyle(self.penJoinComboBox.itemData(
                self.penJoinComboBox.currentIndex(), IdRole))

        self.renderArea.setPen(QPen(Qt.blue, width, style, cap, join))

    def brushChanged(self):
        style = Qt.BrushStyle(self.brushStyleComboBox.itemData(
                self.brushStyleComboBox.currentIndex(), IdRole))

        if style == Qt.LinearGradientPattern:
            linearGradient = QLinearGradient(0, 0, 100, 100)
            linearGradient.setColorAt(0.0, Qt.white)
            linearGradient.setColorAt(0.2, Qt.green)
            linearGradient.setColorAt(1.0, Qt.black)
            self.renderArea.setBrush(QBrush(linearGradient))
        elif style == Qt.RadialGradientPattern:
            radialGradient = QRadialGradient(50, 50, 50, 70, 70)
            radialGradient.setColorAt(0.0, Qt.white)
            radialGradient.setColorAt(0.2, Qt.green)
            radialGradient.setColorAt(1.0, Qt.black)
            self.renderArea.setBrush(QBrush(radialGradient))
        elif style == Qt.ConicalGradientPattern:
            conicalGradient = QConicalGradient(50, 50, 150)
            conicalGradient.setColorAt(0.0, Qt.white)
            conicalGradient.setColorAt(0.2, Qt.green)
            conicalGradient.setColorAt(1.0, Qt.black)
            self.renderArea.setBrush(QBrush(conicalGradient))
        elif style == Qt.TexturePattern:
            self.renderArea.setBrush(QBrush(QPixmap(':/images/brick.png')))
        else:
            self.renderArea.setBrush(QBrush(Qt.green, style))
예제 #41
0
    def createGeneralTab(self):

        main_window = self.main_window

        # Masking options
        self.maskingCheck = QCheckBox('')
        self.maskingCheck.stateChanged.connect(main_window.toggleMasking)

        self.maskColorButton = QPushButton()
        self.maskColorButton.setCursor(QtCore.Qt.PointingHandCursor)
        self.maskColorButton.setFixedWidth(self.font_metric.width("XXXXXXXXXX"))
        self.maskColorButton.setFixedHeight(self.font_metric.height() * 1.5)
        self.maskColorButton.clicked.connect(main_window.editMaskingColor)

        # Highlighting options
        self.hlCheck = QCheckBox('')
        self.hlCheck.stateChanged.connect(main_window.toggleHighlighting)

        self.hlColorButton = QPushButton()
        self.hlColorButton.setCursor(QtCore.Qt.PointingHandCursor)
        self.hlColorButton.setFixedWidth(self.font_metric.width("XXXXXXXXXX"))
        self.hlColorButton.setFixedHeight(self.font_metric.height() * 1.5)
        self.hlColorButton.clicked.connect(main_window.editHighlightColor)

        self.alphaBox = QDoubleSpinBox()
        self.alphaBox.setRange(0, 1)
        self.alphaBox.setSingleStep(.05)
        self.alphaBox.valueChanged.connect(main_window.editAlpha)

        self.seedBox = QSpinBox()
        self.seedBox.setRange(1, 999)
        self.seedBox.valueChanged.connect(main_window.editSeed)

        # General options
        self.bgButton = QPushButton()
        self.bgButton.setCursor(QtCore.Qt.PointingHandCursor)
        self.bgButton.setFixedWidth(self.font_metric.width("XXXXXXXXXX"))
        self.bgButton.setFixedHeight(self.font_metric.height() * 1.5)
        self.bgButton.clicked.connect(main_window.editBackgroundColor)

        self.colorbyBox = QComboBox(self)
        self.colorbyBox.addItem("material")
        self.colorbyBox.addItem("cell")
        self.colorbyBox.addItem("temperature")
        self.colorbyBox.addItem("density")

        # Overlap plotting
        self.overlapCheck = QCheckBox('', self)
        overlap_connector = partial(main_window.toggleOverlaps)
        self.overlapCheck.stateChanged.connect(overlap_connector)

        self.overlapColorButton = QPushButton()
        self.overlapColorButton.setCursor(QtCore.Qt.PointingHandCursor)
        self.overlapColorButton.setFixedWidth(self.font_metric.width("XXXXXXXXXX"))
        self.overlapColorButton.setFixedHeight(self.font_metric.height() * 1.5)
        self.overlapColorButton.clicked.connect(main_window.editOverlapColor)

        self.colorbyBox.currentTextChanged[str].connect(main_window.editColorBy)

        self.colorResetButton = QPushButton("&Reset Colors")
        self.colorResetButton.setCursor(QtCore.Qt.PointingHandCursor)
        self.colorResetButton.clicked.connect(main_window.resetColors)

        formLayout = QFormLayout()
        formLayout.setAlignment(QtCore.Qt.AlignHCenter)
        formLayout.setFormAlignment(QtCore.Qt.AlignHCenter)
        formLayout.setLabelAlignment(QtCore.Qt.AlignLeft)

        formLayout.addRow('Masking:', self.maskingCheck)
        formLayout.addRow('Mask Color:', self.maskColorButton)
        formLayout.addRow(HorizontalLine())
        formLayout.addRow('Highlighting:', self.hlCheck)
        formLayout.addRow('Highlight Color:', self.hlColorButton)
        formLayout.addRow('Highlight Alpha:', self.alphaBox)
        formLayout.addRow('Highlight Seed:', self.seedBox)
        formLayout.addRow(HorizontalLine())
        formLayout.addRow('Background Color:          ', self.bgButton)
        formLayout.addRow(HorizontalLine())
        formLayout.addRow('Show Overlaps:', self.overlapCheck)
        formLayout.addRow('OVerlap Color:', self.overlapColorButton)
        formLayout.addRow(HorizontalLine())
        formLayout.addRow('Color Plot By:', self.colorbyBox)
        formLayout.addRow(self.colorResetButton, None)

        generalLayout = QHBoxLayout()
        innerWidget = QWidget()
        generalLayout.setAlignment(QtCore.Qt.AlignVCenter)
        innerWidget.setLayout(formLayout)
        generalLayout.addStretch(1)
        generalLayout.addWidget(innerWidget)
        generalLayout.addStretch(1)

        self.generalTab = QWidget()
        self.generalTab.setLayout(generalLayout)
def _update_options_by_value(options: Options, combo: QComboBox,
                             new_index: int):
    with options:
        setattr(options, combo.options_field_name, combo.currentData())
예제 #43
0
class SonstigeAusgabenView(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        #self.setWindowTitle( "Sonstige Ausgaben: Rechnungen, Abgaben, Gebühren etc." )
        self._mainLayout = QtWidgets.QGridLayout(self)
        self._toolbarLayout = QHBoxLayout()
        self._summenLayout = QHBoxLayout()
        self._btnSave = QPushButton(self)
        self._editSearch = QLineEdit(self)
        self._btnSearchFwd = QPushButton(self)
        self._btnDbSearch = QPushButton(self)

        # self._idSummeAus = IntDisplay( self )
        # self._idSummeW = IntDisplay( self )
        # self._idSummeU = IntDisplay( self )
        # self._summenfont = QFont( "Times New Roman", 16, weight=QFont.Bold )
        # self._summenartfont = QFont( "Times New Roman", 9 )

        self._cboBuchungsjahr = QtWidgets.QComboBox(self)
        self._tvAuszahlungen = TableViewExt(self)

        self._buchungsdatumLayout = QHBoxLayout()
        self._sdBuchungsdatum = SmartDateEdit(self)
        self._btnAddDay = QPushButton(self)
        self._btnClearBuchungsdatum = QPushButton(self)

        self._objektRefLayout = QHBoxLayout()
        self._cboMasterobjekt = QComboBox(self)
        self._cboMietobjekt = QComboBox(self)

        self._editRechnungLineLayout = QHBoxLayout()
        self._cboKreditor = EditableCombo(self)
        self._cboBuchungstext = EditableCombo(self)
        self._sdRechnungsdatum = SmartDateEdit(self)
        self._feBetrag = FloatEdit(self)
        self._cboKostenart = QComboBox(self)
        self._cbUmlegbar = QCheckBox(self)
        self._cbWerterhaltend = QCheckBox(self)
        self._teBemerkung = QTextEdit(self)
        self._btnOk = QPushButton(self)
        self._btnClear = QPushButton(self)
        # actions für ContextMenu
        #self._contextMenuActions:List[QAction] = None
        # Callbacks
        self._buchungsjahrChangedCallback = None
        self._saveActionCallback = None
        self._searchActionCallback = None
        self._dbSearchActionCallback = None
        self._masterobjektChangedCallback = None
        self._mietobjektChangedCallback = None
        self._kreditorChangedCallback = None
        self._submitChangesCallback = None
        self._justEditing: XSonstAus = None
        self._suspendCallbacks = False

        self._createGui()

    def _createGui(self):
        self._assembleToolbar()
        self._mainLayout.addLayout(self._toolbarLayout,
                                   0,
                                   0,
                                   alignment=Qt.AlignLeft)
        #self._assembleSummen()
        # self._toolbarLayout.addStretch( 50 )
        # self._toolbarLayout.addLayout( self._summenLayout )
        ### tableView
        tv = self._tvAuszahlungen
        tv.setSelectionBehavior(QAbstractItemView.SelectRows)
        tv.setAlternatingRowColors(True)
        tv.verticalHeader().setVisible(False)
        tv.horizontalHeader().setMinimumSectionSize(0)
        self._mainLayout.addWidget(tv, 1, 0, 1, 1)
        self._assembleBuchungsUndRechnungsdatum()
        self._mainLayout.addLayout(self._buchungsdatumLayout,
                                   2,
                                   0,
                                   alignment=Qt.AlignLeft)
        self._assembleObjektReference()
        self._mainLayout.addLayout(self._objektRefLayout,
                                   3,
                                   0,
                                   alignment=Qt.AlignLeft)
        self._assembleRechnungsdaten()
        self._mainLayout.addLayout(self._editRechnungLineLayout,
                                   4,
                                   0,
                                   alignment=Qt.AlignLeft)

    def _assembleToolbar(self):
        #### Combobox Buchungsjahr
        font = QFont("Arial", 14, weight=QFont.Bold)
        self._cboBuchungsjahr.setFont(font)
        self._cboBuchungsjahr.setToolTip(
            "Das hier eingestellte Jahr bestimmt die Rechnungen, die in der Tabelle angezeigt werden."
        )
        self._cboBuchungsjahr.currentIndexChanged.connect(
            self.onBuchungsjahrChanged)
        self._toolbarLayout.addWidget(self._cboBuchungsjahr,
                                      stretch=0,
                                      alignment=Qt.AlignLeft)

        #### save button
        btn = self._btnSave
        btn.clicked.connect(self.onSave)
        btn.setFlat(True)
        btn.setEnabled(False)
        btn.setToolTip("Änderungen dieser View speichern")
        icon = QIcon("../images/save_30.png")
        btn.setIcon(icon)
        size = QSize(30, 30)
        btn.setFixedSize(size)
        iconsize = QSize(30, 30)
        btn.setIconSize(iconsize)
        self._toolbarLayout.addWidget(btn, stretch=0)

        ### search field for tableview search
        edi = self._editSearch
        edi.setPlaceholderText("Suche in Tabelle")
        edi.returnPressed.connect(self._onSearch)
        edi.setToolTip("Suchbegriff eingeben")
        self._toolbarLayout.addWidget(edi, stretch=0)
        btn = self._btnSearchFwd
        btn.clicked.connect(self._onSearch)
        size = QSize(30, 30)
        btn.setFixedSize(size)
        btn.setToolTip("Suche nach eingegebenem Begriff")
        icon = QIcon("../images/arrow_dn_30.png")
        btn.setIcon(icon)
        btn.setEnabled(True)
        self._toolbarLayout.addWidget(btn, stretch=0)

    def _assembleBuchungsUndRechnungsdatum(self):
        lbl = QLabel(self, text="Buchungsdatum: ")
        lbl.setFixedWidth(150)
        self._buchungsdatumLayout.addWidget(lbl)
        self._sdBuchungsdatum.setFixedWidth(85)
        self._sdBuchungsdatum.setToolTip(
            "Buchungsdatum. Kann leer bleiben, wenn Buchung noch nicht erfolgt ist"
        )
        self._buchungsdatumLayout.addWidget(self._sdBuchungsdatum)
        size = QSize(25, 25)
        self._btnAddDay.setIcon(QIcon("../images/plus.png"))
        self._btnAddDay.setFixedSize(size)
        self._btnAddDay.setToolTip("Buchungsdatum um 1 Tag erhöhen")
        self._btnAddDay.clicked.connect(self.onAddDayToBuchungsdatum)
        self._buchungsdatumLayout.addWidget(self._btnAddDay)
        self._btnClearBuchungsdatum.setIcon(QIcon("../images/cancel.png"))
        self._btnClearBuchungsdatum.setFixedSize(size)
        self._btnClearBuchungsdatum.setToolTip("Buchungsdatum löschen")
        self._btnClearBuchungsdatum.clicked.connect(self.onClearBuchungsdatum)
        self._buchungsdatumLayout.addWidget(self._btnClearBuchungsdatum)

        self._sdRechnungsdatum.setPlaceholderText("Datum Rg.")
        self._sdRechnungsdatum.setMaximumWidth(85)
        self._sdRechnungsdatum.setToolTip("optional: Datum der Rechnung")
        self._buchungsdatumLayout.addSpacing(10)
        lbl = QLabel(text="Rechnungsdatum (optional): ")
        lbl.setFixedWidth(200)
        self._buchungsdatumLayout.addWidget(lbl)
        self._buchungsdatumLayout.addWidget(self._sdRechnungsdatum)

    def _assembleObjektReference(self):
        lbl = QLabel(self, text="Betroffenes Objekt: ")
        lbl.setFixedWidth(150)
        self._objektRefLayout.addWidget(lbl)
        self._cboMasterobjekt.setFixedWidth(155)
        self._cboMasterobjekt.setPlaceholderText("Haus")
        self._cboMasterobjekt.setToolTip(
            "Haus, auf das sich die Zahlung bezieht")
        self._cboMasterobjekt.currentIndexChanged.connect(
            self.onMasterobjektChanged)
        self._objektRefLayout.addWidget(self._cboMasterobjekt)
        self._cboMietobjekt.setPlaceholderText("Wohnung")
        self._cboMietobjekt.setToolTip(
            "optional: Wohnung, auf die sich die Zahlung bezieht")
        self._cboMietobjekt.currentIndexChanged.connect(
            self.onMietobjektChanged)
        self._objektRefLayout.addWidget(self._cboMietobjekt)

    def _assembleRechnungsdaten(self):
        self._cboKreditor.setToolTip("Kreditor")
        self._cboKreditor.setFixedWidth(200)
        self._cboKreditor.currentIndexChanged.connect(self.onKreditorChanged)
        self._editRechnungLineLayout.addWidget(self._cboKreditor)
        self._cboBuchungstext.setToolTip(
            "Identifikation der Zahlung durch Rechnungsnummer oder Buchungstext"
        )
        self._cboBuchungstext.setMinimumWidth(100)
        self._editRechnungLineLayout.addWidget(self._cboBuchungstext,
                                               stretch=2)

        #Button for DB-Search
        btn = self._btnDbSearch
        btn.clicked.connect(self._onDbSearch)
        size = QSize(30, 30)
        btn.setFixedSize(size)
        btn.setToolTip("Suche Buchungstext in der DB")
        icon = QIcon("../images/search_30.png")
        btn.setIcon(icon)
        btn.setEnabled(True)
        self._editRechnungLineLayout.addWidget(btn)

        # self._sdRechnungsdatum.setPlaceholderText( "Datum Rg." )
        # self._sdRechnungsdatum.setMaximumWidth( 85 )
        # self._sdRechnungsdatum.setToolTip( "optional: Datum der Rechnung" )
        # self._editRechnungLineLayout.addWidget( self._sdRechnungsdatum, stretch=0, alignment=Qt.AlignLeft )
        self._feBetrag.setPlaceholderText("Betrag")
        self._feBetrag.setMaximumWidth(70)
        self._feBetrag.setToolTip(
            "Positive Beträge sind Aus-, negative Einzahlungen (Gutschriften)")
        self._editRechnungLineLayout.addWidget(self._feBetrag,
                                               stretch=0,
                                               alignment=Qt.AlignLeft)

        # Combobox Kostenart
        self._cboKostenart.setPlaceholderText("Kostenart")
        self._cboKostenart.setFixedWidth(70)
        self._cboKostenart.setToolTip("Kostenart einstellen")
        self._editRechnungLineLayout.addWidget(self._cboKostenart,
                                               stretch=0,
                                               alignment=Qt.AlignLeft)

        vbox = QVBoxLayout()
        vbox.setSpacing(0)
        self._cbUmlegbar.setText("uml")
        self._cbUmlegbar.setToolTip(
            "Ob die Auszahlung auf den/die Mieter umlegbar sind")
        vbox.addWidget(self._cbUmlegbar)
        self._cbWerterhaltend.setText("wert")
        self._cbWerterhaltend.setToolTip(
            "Ob die Auszahlung der Werterhaltung der Wohnung dient")
        vbox.addWidget(self._cbWerterhaltend)
        self._editRechnungLineLayout.addLayout(vbox)

        self._teBemerkung.setPlaceholderText("Bemerkung zur Auszahlung")
        self._teBemerkung.setMaximumSize(QtCore.QSize(16777215, 50))
        self._editRechnungLineLayout.addWidget(self._teBemerkung, stretch=1)

        vbox = QVBoxLayout()
        self._btnOk.setIcon(QIcon("../images/checked.png"))
        self._btnOk.setDefault(True)
        self._btnOk.setToolTip(
            "Neue oder geänderte Daten in Tabelle übernehmen (kein Speichern)")
        self._btnOk.clicked.connect(self.onOkEditFields)
        vbox.addWidget(self._btnOk)
        self._btnClear.setIcon(QIcon("../images/cancel.png"))
        self._btnClear.setToolTip("Änderungen verwerfen und Felder leeren")
        self._btnClear.clicked.connect(self.onClearEditFields)
        vbox.addWidget(self._btnClear)
        self._editRechnungLineLayout.addLayout(vbox)

    # def setContextMenuActions( self, actions:List[QAction] ) -> None:
    #     self._contextMenuActions = actions

    def getSummen(self) -> XSonstAusSummen:
        summen = XSonstAusSummen()
        summen.summe_aus = self._idSummeAus.getIntValue()
        summen.summe_werterhaltend = self._idSummeW.getIntValue()
        summen.summe_umlegbar = self._idSummeU.getIntValue()
        return summen

    def onAddDayToBuchungsdatum(self):
        val = self._sdBuchungsdatum.getDate()
        if val:
            dt = getQDateFromIsoString(val)
            dt = dt.addDays(1)
            self._sdBuchungsdatum.setDate(dt.year(), dt.month(), dt.day())

    def onClearBuchungsdatum(self):
        self._sdBuchungsdatum.clear()

    def setSaveButtonEnabled(self, enable: bool = True):
        self._btnSave.setEnabled(enable)

    def onSave(self):
        if self._saveActionCallback:
            self._saveActionCallback()

    def _onSearch(self):
        if self._searchActionCallback:
            self._searchActionCallback(self._editSearch.text())

    def _onDbSearch(self):
        if self._dbSearchActionCallback:
            #self._dbSearchActionCallback( self._editDbSearch.text() )
            searchstring = self._cboBuchungstext.currentText()
            if searchstring:
                self._dbSearchActionCallback(searchstring)

    def onBuchungsjahrChanged(self, newindex):
        """
        Slot für die Änderung des Buchungsjahrs.
        :param newindex:
        :return:
        """
        if self._buchungsjahrChangedCallback:
            jahr = int(self._cboBuchungsjahr.currentText())
            self._buchungsjahrChangedCallback(jahr)

    def onMasterobjektChanged(self, newindex: int):
        if self._masterobjektChangedCallback and not self._suspendCallbacks:
            self._masterobjektChangedCallback(
                self._cboMasterobjekt.currentText())

    def onMietobjektChanged(self, newindex: int):
        pass

    def onKreditorChanged(self, newindex: int):
        if self._kreditorChangedCallback and not self._suspendCallbacks:
            self._kreditorChangedCallback(self._cboMasterobjekt.currentText(),
                                          self._cboMietobjekt.currentText(),
                                          self._cboKreditor.currentText())

    def onOkEditFields(self, arg):
        """
        OK gedrückt. Änderungen an Callback-Funktion melden.
        :param arg:
        :return:
        """
        if self._submitChangesCallback:
            x: XSonstAus = self._getEditedXSonstAus()
            ok: bool = self._submitChangesCallback(x)
            if ok:
                self._tvAuszahlungen.clearSelection()
                if x.saus_id <= 0:  # neuer Eintrag in Tabelle, nach unten scrollen
                    self._tvAuszahlungen.scrollToBottom()

    def _getEditedXSonstAus(self) -> XSonstAus:
        x: XSonstAus = self._justEditing if self._justEditing else XSonstAus()
        x.buchungsjahr = int(self._cboBuchungsjahr.currentText())
        x.buchungsdatum = self._sdBuchungsdatum.getDate()
        idx = self._cboMasterobjekt.currentIndex()
        x.master_name = "" if idx < 0 else self._cboMasterobjekt.currentText()
        idx = self._cboMietobjekt.currentIndex()
        x.mobj_id = "" if idx < 0 else self._cboMietobjekt.currentText()
        x.kreditor = self._cboKreditor.currentText()
        x.buchungstext = self._cboBuchungstext.currentText()
        x.rgdatum = self._sdRechnungsdatum.getDate()
        x.betrag = self._feBetrag.getFloatValue() * (-1)
        x.umlegbar = self._cbUmlegbar.isChecked()
        x.werterhaltend = self._cbWerterhaltend.isChecked()
        x.rgtext = self._teBemerkung.toPlainText()
        return x

    def onClearEditFields(self, arg):
        self.clearEditFields()
        self._tvAuszahlungen.clearSelection()

    def getAuszahlungenTableView(self) -> QTableView:
        return self._tvAuszahlungen

    def setAuszahlungenTableModel(self, tm: SonstAusTableModel):
        self._tvAuszahlungen.setModel(tm)
        self._tvAuszahlungen.resizeColumnsToContents()
        #self._tvAuszahlungen.setColumnWidth( 0, 10 )
        #self._tvAuszahlungen.setColumnWidth( 1, 10 )

    def setBuchungsjahre(self, jahre: List[int]):
        """
        setzt die Liste der auswählbaren Jahre für die Buchungsjahr-Combobox
        :param jahre:
        :return:
        """
        for jahr in jahre:
            self._cboBuchungsjahr.addItem(str(jahr))

    def setBuchungsjahr(self, jahr: int) -> None:
        """
        setzt das Jahr, das in der Buchungsjahr-Combobox anzuzeigen ist
        :param jahr:
        :return:
        """
        self._cboBuchungsjahr.setCurrentText(str(jahr))

    def setBuchungsdatum(self, tag: int, monat: str):
        """
        setzt Buchungstag und -monat.
        Das Jahr ergibt sich aus dem eingestellten Buchungsjahr
        :param tag:
        :param monat:
        :return:
        """
        # self._sbTag.setValue( tag )
        # self._cboMonat.setCurrentText( monat )
        self._sdBuchungsdatum.\
            setDate( int(self._cboBuchungsjahr.currentText()), getMonthIndex( monat ), tag )

    def setMasterobjekte(self, masterobjekte: List[str]):
        for obj in masterobjekte:
            self._cboMasterobjekt.addItem(obj)

    def setMietobjekte(self, mietobjekte: List[str]):
        self._cboMietobjekt.clear()
        for obj in mietobjekte:
            self._cboMietobjekt.addItem(obj)
        self._cboMietobjekt.setCurrentIndex(0)

    def selectMietobjekt(self, mobj_id: str):
        self._cboMietobjekt.setCurrentText(mobj_id)

    def clearMietobjekte(self):
        self._cboMietobjekt.clear()

    def setKreditoren(self, kreditoren: List[str]):
        self._cboKreditor.clear()
        for k in kreditoren:
            self._cboKreditor.addItem(k)
        self._cboKreditor.setCurrentIndex(-1)

    def selectKreditor(self, kreditor: str):
        self._cboKreditor.setCurrentText(kreditor)

    def setLeistungsidentifikationen(self, idents: List[str]):
        self._cboBuchungstext.clear()
        for i in idents:
            self._cboBuchungstext.addItem(i)
        #self._cboRechnungsIdent.showPopup()

    def setCurrentLeistungsidentifikation(self, leistident: str) -> None:
        self._cboBuchungstext.setCurrentText(leistident)

    def getCurrentMasterobjekt(self) -> str:
        return self._cboMasterobjekt.currentText()

    def getCurrentMietobjekt(self) -> str:
        return self._cboMietobjekt.currentText()

    def getCurrentKreditor(self) -> str:
        return self._cboKreditor.currentText()

    def setCurrentKreditor(self, kreditor: str) -> None:
        self._cboKreditor.setCurrentText(kreditor)

    def getCurrentLeistungsidentifikation(self) -> str:
        return self._cboBuchungstext.currentText()

    def resetKreditoren(self):
        self._cboKreditor.setCurrentIndex(-1)

    def clearKreditoren(self):
        self._cboKreditor.clear()

    def setKostenarten(self, kostenarten: List[str]):
        self._cboKostenart.clear()
        for k in kostenarten:
            self._cboKostenart.addItem(k)
        self._cboKostenart.setCurrentIndex(-1)

    def getCurrentKostenart(self) -> str:
        return self._cboKostenart.currentText()

    def selectKostenart(self, kostenart: str):
        self._cboKostenart.setCurrentText(kostenart)

    def resetKostenart(self):
        self._cboKostenart.setCurrentIndex(-1)

    def clearEditFields(self):
        self._suspendCallbacks = True
        #self._sdBuchungsdatum.clear()
        self._cboMasterobjekt.setCurrentIndex(-1)
        self._cboMietobjekt.setCurrentIndex(-1)
        self._cboKreditor.setCurrentIndex(-1)
        self._cboBuchungstext.setCurrentIndex(-1)
        self._sdRechnungsdatum.clear()
        self._feBetrag.clear()
        self._cboKostenart.setCurrentIndex(-1)
        self._cbUmlegbar.setChecked(False)
        self._cbWerterhaltend.setChecked(False)
        self._teBemerkung.clear()
        self._justEditing = None
        self._suspendCallbacks = False

    # def provideEditFieldsPartly( self, umlegbar:bool, master_id:int, master_name:str,
    #                              mobj_id:str, kreditor:str, buchungstext:str ):
    #     self._cbUmlegbar.setChecked( umlegbar )
    #     self._cboMasterobjekt.setCurrentText( master_name )
    #     self._cboMietobjekt.setCurrentText( mobj_id )
    #     self._cboKreditor.setCurrentText( kreditor )
    #     self._cboBuchungstext.setCurrentText( buchungstext )
    #     #todo: weitermachen

    def provideEditFields(self, x: XSonstAus):
        self.clearEditFields()
        #self._suspendCallbacks = True
        self._justEditing = x
        if x.buchungsdatum:
            y, m, d = getDateParts(x.buchungsdatum)
            self._sdBuchungsdatum.setDate(y, m, d)
        else:
            self._sdBuchungsdatum.clear()
        if x.master_id is not None and x.master_id >= 0:  #master_id kann auch 0 sein! (**alle**)
            self._cboMasterobjekt.setCurrentText(x.master_name)
        if x.mobj_id:
            self._cboMietobjekt.setCurrentText(x.mobj_id)
        if x.kreditor:
            self._cboKreditor.setCurrentText(x.kreditor)
        if x.buchungstext:
            self._cboBuchungstext.setCurrentText(x.buchungstext)
        if x.rgdatum:
            y, m, d = getDateParts(x.rgdatum)
            self._sdRechnungsdatum.setDate(y, m, d)
        self._feBetrag.setText(str(x.betrag * (-1)))
        self._cbUmlegbar.setChecked(x.umlegbar)
        self._cbWerterhaltend.setChecked(x.werterhaltend)
        self._teBemerkung.setText(x.rgtext)
        self._suspendCallbacks = False

    def getModel(self) -> IccTableModel:
        return self._tvAuszahlungen.model()

    def showException(self, title: str, exception: str, moretext: str = None):
        # todo: show Qt-Errordialog
        msgbox = QtWidgets.QMessageBox()
        msgbox.setWindowTitle(title)
        msgbox.setIcon(QMessageBox.Critical)
        msgbox.setText(exception)
        if moretext:
            msgbox.setInformativeText(moretext)
        msgbox.exec_()

    ################# SET CALLBACKS  ############################

    def setBuchungsjahrChangedCallback(self, cbfnc) -> None:
        """
        Die callback-Funktion muss als Argument das neu eingestellte Jahr als integer akzeptieren
        :param cbfnc:
        :return:
        """
        self._buchungsjahrChangedCallback = cbfnc

    def setSaveActionCallback(self, cbfnc) -> None:
        """
        Die callback-FUnktion braucht keine Parameter empfangen.
        :param cbfnc:
        :return:
        """
        self._saveActionCallback = cbfnc

    def setSearchActionCallback(self, cbfnc) -> None:
        """
        Die callback-Funktion muss den Searchstring als Parameter empfangen.
        :param cbfnc:
        :return:
        """
        self._searchActionCallback = cbfnc

    def setDbSearchActionCallback(self, cbfnc) -> None:
        """
       Die callback-Funktion muss den Searchstring als Parameter empfangen.
       :param cbfnc:
       :return:
       """
        self._dbSearchActionCallback = cbfnc

    def setMasterobjektChangedCallback(self, cbfnc):
        """
        Die callback-Funktion muss einen String als Argument akzeptieren (Name des MAsterobjekts)
        :param cbfnc:
        :return:
        """
        self._masterobjektChangedCallback = cbfnc

    def setMietobjektChangedCallback(self, cbfnc):
        """
        Die callback-Funktion muss einen String als Argument akzeptieren (mobj_id)
        :param cbfnc:
        :return:
        """
        self._mietobjektChangedCallback = cbfnc

    def setKreditorChangedCallback(self, cbfnc):
        """
        Die callback Funktion muss 3 Argumente entgegennehmen können:
        master_name, mobj_id, neuer kreditor
        :param cbfnc:
        :return:
        """
        self._kreditorChangedCallback = cbfnc

    def setSubmitChangesCallback(self, cbfnc):
        """
        sets the one and only callback when the user hits the OK button in the
        edit fields area.
        The given callback function has to accept the edited XSonstAus object,
        :param cbfnc:
        :return:
        """
        self._submitChangesCallback = cbfnc
 def _on_gate_combo_box_changed(self, combo: QComboBox, new_index: int):
     with self._options as options:
         options.set_layout_configuration_field(
             "translator_configuration",
             options.layout_configuration.translator_configuration.
             replace_requirement_for_gate(combo.gate, combo.currentData()))
예제 #45
0
파일: export.py 프로젝트: strohne/Facepager
class ExportFileDialog(QFileDialog):
    """
    Create a custom Export-File Dialog with options like BOM etc.
    """

    def __init__(self,*args,**kwargs):
        super(ExportFileDialog,self).__init__(*args,**kwargs)

        self.mainWindow = self.parent()
        self.setWindowTitle("Export nodes to CSV")
        self.setAcceptMode(QFileDialog.AcceptSave)
        self.setOption(QFileDialog.DontUseNativeDialog)
        #self.setFilter("CSV Files (*.csv)")
        self.setDefaultSuffix("csv")

        self.optionBOM = QCheckBox("Use a BOM",self)
        self.optionBOM.setCheckState(Qt.CheckState.Checked)

        self.optionLinebreaks = QCheckBox("Remove line breaks",self)
        self.optionLinebreaks.setCheckState(Qt.CheckState.Checked)

        self.optionSeparator = QComboBox(self)
        self.optionSeparator.insertItems(0, [";","\\t",","])
        self.optionSeparator.setEditable(True)

        #self.optionLinebreaks.setCheckState(Qt.CheckState.Checked)

        self.optionWide = QCheckBox("Convert to wide format (experimental feature)",self)
        self.optionWide.setCheckState(Qt.CheckState.Unchecked)

        # if none or all are selected, export all
        # if one or more are selected, export selective
        self.optionAll = QComboBox(self)
        self.optionAll.insertItems(0, ['All nodes (faster for large datasets, ordered by internal ID)','Selected nodes (ordered like shown in nodes view)'])
        if self.mainWindow.tree.noneOrAllSelected():
            self.optionAll.setCurrentIndex(0)
        else:
            self.optionAll.setCurrentIndex(1)

        layout = self.layout()
        row = layout.rowCount()
        layout.addWidget(QLabel('Options'),row,0)

        options = QHBoxLayout()
        options.addWidget(self.optionBOM)
        options.addWidget(self.optionLinebreaks)
        options.addWidget(QLabel('Separator'))
        options.addWidget(self.optionSeparator)
        options.addStretch(1)

        layout.addLayout(options,row,1,1,2)

        layout.addWidget(QLabel('Post processing'),row+1,0)
        layout.addWidget(self.optionWide,row+1,1,1,2)

        layout.addWidget(QLabel('Export mode'),row+2,0)
        layout.addWidget(self.optionAll,row+2,1,1,2)
        self.setLayout(layout)

        if self.exec_():

            if os.path.isfile(self.selectedFiles()[0]):
                os.remove(self.selectedFiles()[0])
            output = open(self.selectedFiles()[0], 'w', newline='', encoding='utf8')
            if self.optionBOM.isChecked() and not self.optionWide.isChecked():
                output.write('\ufeff')

            try:
                if self.optionAll.currentIndex() == 0:
                    self.exportAllNodes(output)
                else:
                    self.exportSelectedNodes(output)
            finally:
                output.close()

            if self.optionWide.isChecked():
                self.convertToWideFormat(self.selectedFiles()[0])


    def exportSelectedNodes(self,output):
        progress = ProgressBar("Exporting data...", self.mainWindow)

        #indexes = self.mainWindow.tree.selectionModel().selectedRows()
        #if child nodes should be exported as well, uncomment this line an comment the previous one
        indexes = self.mainWindow.tree.selectedIndexesAndChildren()
        progress.setMaximum(len(indexes))

        try:
            delimiter = self.optionSeparator.currentText()
            delimiter = delimiter.encode('utf-8').decode('unicode_escape')
            writer = csv.writer(output, delimiter=delimiter, quotechar='"', quoting=csv.QUOTE_ALL, doublequote=True,
                                lineterminator='\r\n')


            #headers
            row = [str(val) for val in self.mainWindow.tree.treemodel.getRowHeader()]
            if self.optionLinebreaks.isChecked():
                row = [val.replace('\n', ' ').replace('\r',' ') for val in row]

            writer.writerow(row)

            #rows
            for no in range(len(indexes)):
                if progress.wasCanceled:
                    break

                row = [str(val) for val in self.mainWindow.tree.treemodel.getRowData(indexes[no])]
                if self.optionLinebreaks.isChecked():
                    row = [val.replace('\n', ' ').replace('\r',' ') for val in row]

                writer.writerow(row)

                progress.step()

        finally:
            progress.close()


    def exportAllNodes(self,output):
        progress = ProgressBar("Exporting data...", self.mainWindow)
        progress.setMaximum(Node.query.count())


        try:
            delimiter = self.optionSeparator.currentText()
            delimiter = delimiter.encode('utf-8').decode('unicode_escape')
            writer = csv.writer(output, delimiter=delimiter, quotechar='"', quoting=csv.QUOTE_ALL, doublequote=True,
                                lineterminator='\r\n')

            #headers
            row = ["level", "id", "parent_id", "object_id", "object_type", "query_status", "query_time",
                   "query_type"]
            for key in self.mainWindow.tree.treemodel.customcolumns:
                row.append(key)
            if self.optionLinebreaks.isChecked():
                row = [val.replace('\n', ' ').replace('\r',' ') for val in row]

            writer.writerow(row)

            #rows
            page = 0

            while True:
                allnodes = Node.query.offset(page * 5000).limit(5000)
                if allnodes.count() == 0:
                    break
                for node in allnodes:
                    if progress.wasCanceled:
                        break
                    row = [node.level, node.id, node.parent_id, node.objectid, node.objecttype,
                           node.querystatus, node.querytime, node.querytype]
                    for key in self.mainWindow.tree.treemodel.customcolumns:
                        row.append(node.getResponseValue(key))

                    if self.optionLinebreaks.isChecked():
                        row = [str(val).replace('\n', ' ').replace('\r',' ') for val in row]

                    writer.writerow(row)
                    # step the Bar
                    progress.step()
                if progress.wasCanceled:
                    break
                else:
                    page += 1

        finally:
            progress.close()

    def convertToWideFormat(self,filename):
        progress = ProgressBar("Converting data...", self.mainWindow)
        try:
            #Separate levels
            def flattenTable(fulltable,levelcol,idcol,parentidcol,countchildren,removeempty):
                fulltable[[levelcol]] = fulltable[[levelcol]].astype(int)

                levels = dict(list(fulltable.groupby(levelcol)))
                minlevel = fulltable.level.min()
                for level, data in sorted(levels.items()):
                    #First level is the starting point for the following merges
                    if level == minlevel:
                        #data = data[[idcol,'object_id','object_type']]
                        data = data.add_prefix('level_{}-'.format(level))
                        flattable = data
                    else:
                        #Aggregate object types and join them
                        for col_countchildren in countchildren:
                            children = data[parentidcol].groupby([data[parentidcol],data[col_countchildren]]).count()
                            children = children.unstack(col_countchildren)
                            children['total'] = children.sum(axis=1)
                            children = children.add_prefix('level_{}-children-{}-'.format(level-1,col_countchildren))

                            leftkey = 'level_{}-id'.format(level-1)
                            flattable = merge(flattable,children,how='left',left_on=leftkey,right_index=True)
                            flattable[children.columns.values.tolist()] = flattable[children.columns.values.tolist()].fillna(0).astype(int)

                        #Join data
                        data['childnumber'] = data.groupby(parentidcol).cumcount()
                        leftkey = 'level_{}-{}'.format(level-1,idcol)
                        rightkey = 'level_{}-{}'.format(level,parentidcol)
                        data = data.drop([levelcol],axis=1)
                        data = data.add_prefix('level_{}-'.format(level))
                        flattable = merge(flattable,data,how="outer",left_on=leftkey,right_on=rightkey)

                if removeempty:
                    flattable = flattable.dropna(axis=1,how='all')
                return flattable

            try:
                #delimiter
                delimiter = self.optionSeparator.currentText()
                delimiter = delimiter.encode('utf-8').decode('unicode_escape')

                #open
                data = read_csv(filename, sep=delimiter,encoding='utf-8',dtype=str)

                #convert
                newdata = flattenTable(data,'level','id','parent_id',['object_type','query_status','query_type'],False)


                #save
                outfile = open(filename, 'w',newline='',encoding='utf8')
                try:
                    if self.optionBOM.isChecked():
                        outfile.write('\ufeff') #UTF8 BOM
                    newdata.to_csv(outfile,sep=delimiter,index=False,encoding="utf-8")
                finally:
                    outfile.close()
            except Exception as e:
                self.mainWindow.logmessage(e)
        finally:
            progress.close()