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
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 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)
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
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
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
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])
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()
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()
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
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 __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")
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()))
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)
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()
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)
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()
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)
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()
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
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
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
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
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()
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()
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
def setUp(self): super(QGraphicsSceneOnQVariantTest, self).setUp() self.s = MyDiagram() self.i = MyItem() self.combo = QComboBox()
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
def __init__(self, parent=None): QComboBox.__init__(self, parent) self.setEditable(True)
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)
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])
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"))
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)
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))
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())
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()))
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()