class MetalGUI(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) self.parent = parent self.supported_setups = ['TOP-DOWN'] self.stacked_layout = QStackedLayout() self.__setup_widget = None self.__metal_main_widget = None self.__init_main_widget__() self.stacked_layout.setCurrentIndex(0) self.setLayout(self.stacked_layout) def minimumSizeHint(self): return self.stacked_layout.currentWidget().minimumSizeHint() def sizeHint(self): return self.stacked_layout.currentWidget().sizeHint() def __load_settings__(self): base_path = Path(__file__).parent settings_path = str( (base_path / '../resources/PRINTER_SETTINGS.json').resolve()) settings_file = QFile(settings_path) if settings_file.open(QIODevice.ReadOnly | QIODevice.Text): file_data = QJsonDocument.fromJson( settings_file.readAll()).object() if "metal_printer_settings" in file_data: printer_setup = str( file_data["metal_printer_settings"]["printer_setup"]) if printer_setup == self.supported_setups[0]: self.__select_setup__(0) else: return False return True settings_file.close() return False def __init_configuration_selection_widget__(self): self.__setup_widget = QWidget(self) setup_layout = QHBoxLayout() for idx in range(len(self.supported_setups)): button = QPushButton(self.supported_setups[idx], self.__setup_widget) button.setFixedSize(200, 200) button.clicked.connect(self.__select_setup__) setup_layout.addWidget(button) self.__setup_widget.setLayout(setup_layout) self.stacked_layout.addWidget(self.__setup_widget) def __select_setup__(self, idx): self.selected_setup = self.supported_setups[idx] self.__init_main_widget__() self.stacked_layout.setCurrentIndex(1) self.parent.move( self.desktops.screen(0).rect().center() - self.__metal_main_widget.rect().center()) def __init_main_widget__(self): self.__metal_main_widget = QTabWidget(self) self.__metal_main_widget.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum) self.__gcode_sender_widget = GCodeSenderGUI( parent=self.__metal_main_widget) self.__slicer_widget = MetalSlicerGUI(parent=self.__metal_main_widget) self.__slicer_widget.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum) self.__metal_main_widget.addTab(self.__gcode_sender_widget, 'GCode Sender') self.__metal_main_widget.addTab(self.__slicer_widget, 'Slicer') self.stacked_layout.addWidget(self.__metal_main_widget) self.desktops = QDesktopWidget() @Slot() def closeEvent(self, event: QCloseEvent): if self.__setup_widget: self.__setup_widget.close() if self.__metal_main_widget: self.__slicer_widget.close() self.__metal_main_widget.close() event.accept() def get_settings_window(self, parent=None): printer_settings = QGroupBox("Metal Printer Settings:", parent) gcodesender_settings = self.__gcode_sender_widget.get_settings_window( printer_settings) settings_layout = QVBoxLayout(printer_settings) settings_layout.addWidget(gcodesender_settings) return printer_settings
def testObjectDestructorOrder(self): w = QWidget() filt = MyFilter() filt.app = self.app w.installEventFilter(filt) w.show() w.close() w = None self.assert_(True)
class PersonaUI(QWidget): """ Widget for Persona creation view. :param MainFrame mainframe: application mainframe :param QWidget op: parent widget """ def __init__(self, mainframe, op): QWidget.__init__(self) self.mainframe = mainframe self.op = op self.grid = QGridLayout() self.setLayout(self.grid) self.listP = None self.listLS = None self.listEL1 = None self.listEL2 = None self.nameT = None self.levelT = None self.textT = None self.strT = None self.magT = None self.endT = None self.agiT = None self.luckT = None self.createFrame = None self.buttonFrame = None self.bfgrid = None # Actual create frame variables. self.cfgrid = None self.lsdic = None self.slashO = None self.strikeO = None self.pierceO = None self.fireO = None self.iceO = None self.windO = None self.elecO = None self.darkO = None self.lightO = None self.arcO = None self.iSpellOs = None self.lsSpellO = None self.lslevel = None self.initUI(True) def initUI(self, infoDump): """ Initializes the basic UI showing the list of Personas. Does a lot of stuff. :param dict infoDump: not sure lol """ self.mainframe.setWindowTitle("Persona Creator") if not infoDump: self.createFrameDraw() self.initButtonFrame(infoDump) self.listP = QListWidget(self) self.grid.addWidget(self.listP, 0, 3, 2, 1) temp = json_reader.readPerNames() self.listP.addItems(temp) def initButtonFrame(self, infoDump): """ Initializes the buttonframes that are present in all Persona creator views. :param dict infoDump: not sure lol """ self.buttonFrame = QWidget(self) self.bfgrid = QGridLayout() self.buttonFrame.setLayout(self.bfgrid) self.grid.addWidget(self.buttonFrame, 3, 0, 1, 4) new = QPushButton(self.buttonFrame, text="New") new.clicked.connect(self.new) self.bfgrid.addWidget(new, 4, 0) back = QPushButton(self.buttonFrame, text="Back") back.clicked.connect(self.back) self.bfgrid.addWidget(back, 4, 4) remove = QPushButton(self.buttonFrame, text="Remove") remove.clicked.connect(self.remove) self.bfgrid.addWidget(remove, 4, 3) edit = QPushButton(self.buttonFrame, text="Edit") edit.clicked.connect(self.edit) self.bfgrid.addWidget(edit, 4, 2) if not infoDump: save = QPushButton(self.buttonFrame, text="Save") save.clicked.connect(self.save) self.bfgrid.addWidget(save, 4, 1) def createFrameDraw(self): """ Initializes the GUI of the actual creation frame view. Does a LOT of stuff. """ self.createFrame = QWidget(self) self.cfgrid = QGridLayout() self.createFrame.setLayout(self.cfgrid) self.grid.addWidget(self.createFrame, 0, 0, 2, 2) self.lsdic = {} nameL = QLabel(self.createFrame, text="Name:") self.cfgrid.addWidget(nameL, 0, 0) self.nameT = QLineEdit(self.createFrame) self.nameT.setFixedSize(100, 20) self.cfgrid.addWidget(self.nameT, 0, 1) strL = QLabel(self.createFrame, text="Str") self.cfgrid.addWidget(strL, 0, 2) self.strT = QLineEdit(self.createFrame) self.strT.setFixedSize(20, 20) self.cfgrid.addWidget(self.strT, 0, 3) magL = QLabel(self.createFrame, text="Mag") self.cfgrid.addWidget(magL, 1, 2) self.magT = QLineEdit(self.createFrame) self.magT.setFixedSize(20, 20) self.cfgrid.addWidget(self.magT, 1, 3) endL = QLabel(self.createFrame, text="End") self.cfgrid.addWidget(endL, 2, 2) self.endT = QLineEdit(self.createFrame) self.endT.setFixedSize(20, 20) self.cfgrid.addWidget(self.endT, 2, 3) agiL = QLabel(self.createFrame, text="Agi") self.cfgrid.addWidget(agiL, 3, 2) self.agiT = QLineEdit(self.createFrame) self.agiT.setFixedSize(20, 20) self.cfgrid.addWidget(self.agiT, 3, 3) luckL = QLabel(self.createFrame, text="Luck") self.cfgrid.addWidget(luckL, 4, 2) self.luckT = QLineEdit(self.createFrame) self.luckT.setFixedSize(20, 20) self.cfgrid.addWidget(self.luckT, 4, 3) resList = json_reader.data_list("resistances") resL = QLabel(self.createFrame, text="Resistance:") self.cfgrid.addWidget(resL, 0, 5) slashL = QLabel(self.createFrame, text="Slash") self.cfgrid.addWidget(slashL, 1, 5) self.slashO = QComboBox(self.createFrame) self.slashO.addItems(resList) self.slashO.setCurrentIndex(1) self.cfgrid.addWidget(self.slashO, 1, 6) strikeL = QLabel(self.createFrame, text="Strike") self.cfgrid.addWidget(strikeL, 2, 5) self.strikeO = QComboBox(self.createFrame) self.strikeO.addItems(resList) self.strikeO.setCurrentIndex(1) self.cfgrid.addWidget(self.strikeO, 2, 6) pierceL = QLabel(self.createFrame, text="Pierce") self.cfgrid.addWidget(pierceL, 3, 5) self.pierceO = QComboBox(self.createFrame) self.pierceO.addItems(resList) self.pierceO.setCurrentIndex(1) self.cfgrid.addWidget(self.pierceO, 3, 6) fireL = QLabel(self.createFrame, text="Fire") self.cfgrid.addWidget(fireL, 4, 5) self.fireO = QComboBox(self.createFrame) self.fireO.addItems(resList) self.fireO.setCurrentIndex(1) self.cfgrid.addWidget(self.fireO, 4, 6) iceL = QLabel(self.createFrame, text="Ice") self.cfgrid.addWidget(iceL, 5, 5) self.iceO = QComboBox(self.createFrame) self.iceO.addItems(resList) self.iceO.setCurrentIndex(1) self.cfgrid.addWidget(self.iceO, 5, 6) elecL = QLabel(self.createFrame, text="Elec") self.cfgrid.addWidget(elecL, 6, 5) self.elecO = QComboBox(self.createFrame) self.elecO.addItems(resList) self.elecO.setCurrentIndex(1) self.cfgrid.addWidget(self.elecO, 6, 6) windL = QLabel(self.createFrame, text="Wind") self.cfgrid.addWidget(windL, 7, 5) self.windO = QComboBox(self.createFrame) self.windO.addItems(resList) self.windO.setCurrentIndex(1) self.cfgrid.addWidget(self.windO, 7, 6) lightL = QLabel(self.createFrame, text="Light") self.cfgrid.addWidget(lightL, 8, 5) self.lightO = QComboBox(self.createFrame) self.lightO.addItems(resList) self.lightO.setCurrentIndex(1) self.cfgrid.addWidget(self.lightO, 8, 6) darkL = QLabel(self.createFrame, text="Dark") self.cfgrid.addWidget(darkL, 9, 5) self.darkO = QComboBox(self.createFrame) self.darkO.addItems(resList) self.darkO.setCurrentIndex(1) self.cfgrid.addWidget(self.darkO, 9, 6) spellList = json_reader.data_list("spells") self.listLS = QListWidget(self.createFrame) self.listLS.setFixedSize(200, 300) self.cfgrid.addWidget(self.listLS, 3, 7, 8, 2) newLS = QPushButton(self.createFrame, text="+") newLS.clicked.connect(self.addLS) self.cfgrid.addWidget(newLS, 2, 7) delLS = QPushButton(self.createFrame, text="DEL") delLS.clicked.connect(self.delLS) self.cfgrid.addWidget(delLS, 2, 8) lsl = QLabel(self.createFrame, text="Learned Spells:") self.cfgrid.addWidget(lsl, 0, 7, 1, 2) arcanaL = QLabel(self.createFrame, text="Arcana:") self.cfgrid.addWidget(arcanaL, 1, 0) arc_list = json_reader.data_list("arcanas") self.arcO = QComboBox(self.createFrame) self.arcO.addItems(arc_list) self.arcO.setCurrentIndex(0) self.cfgrid.addWidget(self.arcO, 1, 1) levelL = QLabel(self.createFrame, text="Level:") self.cfgrid.addWidget(levelL, 2, 0) self.levelT = QLineEdit(self.createFrame) self.levelT.setFixedSize(20, 20) self.cfgrid.addWidget(self.levelT, 2, 1) heritageL = QLabel(self.createFrame, text="Inherits:") self.cfgrid.addWidget(heritageL, 3, 0, 1, 2) elements = json_reader.data_list("elements") elements.append("Support") self.listEL1 = QComboBox(self.createFrame) self.listEL1.addItems(elements) self.cfgrid.addWidget(self.listEL1, 4, 0) self.listEL2 = QComboBox(self.createFrame) self.listEL2.addItems(elements) self.cfgrid.addWidget(self.listEL2, 4, 1) iSpellL = QLabel(self.createFrame, text="Initial Spells:") self.cfgrid.addWidget(iSpellL, 5, 0, 1, 2) self.iSpellOs = [] for i in range(6, 9): temp = QComboBox(self.createFrame) temp.addItems(spellList) temp2 = QComboBox(self.createFrame) temp2.addItems(spellList) self.cfgrid.addWidget(temp, i, 0, 1, 2) self.cfgrid.addWidget(temp2, i, 2, 1, 2) self.iSpellOs.extend([temp, temp2]) textL = QLabel(self.createFrame, text="Info:") self.cfgrid.addWidget(textL, 10, 0) self.textT = QTextEdit(self.createFrame) self.textT.setFixedSize(300, 100) self.cfgrid.addWidget(self.textT, 10, 1, 1, 5) self.lslevel = QLineEdit(self.createFrame) self.lslevel.setFixedSize(40, 20) self.lsSpellO = QComboBox(self.createFrame) self.lsSpellO.addItems(spellList) self.cfgrid.addWidget(self.lsSpellO, 1, 7) self.cfgrid.addWidget(self.lslevel, 1, 8) def addLS(self): """ Add a learned spell to the list, based on what was entered. """ print("Adding learned spell") chosenSpell = self.lsSpellO.currentText() if (int)(self.lslevel.text()) <= (int)(self.levelT.text()): popup("You cannot add a spell at an earlier level than the Persona's base level", "Critical") return if chosenSpell != "": print("Ok") self.lsdic[chosenSpell] = self.lslevel.text() self.listLS.addItem(chosenSpell + " at level " + self.lslevel.text()) self.lslevel.setText("") self.lsSpellO.setCurrentIndex(0) return popup("You must choose a spell", "Critical") def delLS(self): """ Remove the selected learned spell from the list """ print("Deleting learned spell") key = "" i = 0 while len(self.listLS.currentItem().text()) > i: if self.listLS.currentItem().text()[i] == " " and \ self.listLS.currentItem().text()[i+1] == "a" and \ self.listLS.currentItem().text()[i+2] == "t": # TODO EWWWWWW break key += self.listLS.currentItem().text()[i] i = i + 1 print(key) print(self.lsdic.pop(key)) self.listLS.takeItem(self.listLS.currentRow()) def loadPer(self, name): """ Load a certain Persona from file. :param str name: name of Persona to load """ data = json_reader.readOne(name, 'pers') self.nameT.setText(data["name"]) self.textT.setText(data["desc"]) self.strT.setText(data["stats"][0]) self.magT.setText(data["stats"][1]) self.endT.setText(data["stats"][2]) self.agiT.setText(data["stats"][3]) self.luckT.setText(data["stats"][4]) self.levelT.setText(data["level"]) self.arcO.setCurrentIndex( [self.arcO.itemText(i) for i in range(self.arcO.count())].index(data["arcana"]) ) self.listEL1.setCurrentIndex( [self.listEL1.itemText(i) for i in range(self.listEL1.count())].index(data["heritage"][0]) ) self.listEL2.setCurrentIndex( [self.listEL2.itemText(i) for i in range(self.listEL2.count())].index(data["heritage"][1]) ) self.slashO.setCurrentIndex( [self.slashO.itemText(i) for i in range(self.slashO.count())].index(data["resistance"][0]) ) self.strikeO.setCurrentIndex( [self.strikeO.itemText(i) for i in range(self.strikeO.count())].index(data["resistance"][1]) ) self.pierceO.setCurrentIndex( [self.pierceO.itemText(i) for i in range(self.pierceO.count())].index(data["resistance"][2]) ) self.fireO.setCurrentIndex( [self.fireO.itemText(i) for i in range(self.fireO.count())].index(data["resistance"][3]) ) self.iceO.setCurrentIndex( [self.iceO.itemText(i) for i in range(self.iceO.count())].index(data["resistance"][4]) ) self.elecO.setCurrentIndex( [self.elecO.itemText(i) for i in range(self.elecO.count())].index(data["resistance"][5]) ) self.windO.setCurrentIndex( [self.windO.itemText(i) for i in range(self.windO.count())].index(data["resistance"][6]) ) self.lightO.setCurrentIndex( [self.lightO.itemText(i) for i in range(self.lightO.count())].index(data["resistance"][7]) ) self.darkO.setCurrentIndex( [self.darkO.itemText(i) for i in range(self.darkO.count())].index(data["resistance"][8]) ) i = 0 for combobox in self.iSpellOs: combobox.setCurrentIndex( [combobox.itemText(j) for j in range(combobox.count()-1)].index(data["spellDeck"][i]) ) i += 1 self.lsdic = data["spellLearn"] self.listLS.clear() for spell, level in self.lsdic.items(): self.listLS.addItem(spell + " at level " + level) print("Loaded " + data["name"]) def edit(self): """ Switch to edit view, also loads the selected Persona. """ try: if self.listP.currentItem().text() != "": if self.createFrame and not popup("Override any unsaved changes?", "Warning"): return self.loadPer(self.listP.currentItem().text()) except AttributeError: # To initialize createFrame UI before load if self.listP.currentItem().text() != "": temp = self.listP.currentItem().text() self.buttonFrame.close() self.initUI(False) self.loadPer(temp) else: return self.createFrame.show() self.mainframe.center() print("Changed to edit frame") def save(self): """ Validate all info and save to file on disk. """ if os.path.exists(json_reader.buildPath("data/pers/"+self.nameT.text()+".json")): if not popup("Override existing Persona "+self.nameT.text()+"?", "Question"): return print("Saving") spellDeck = [] for combobox in self.iSpellOs: spellDeck.append(combobox.currentText()) stats = [self.strT.text(), self.magT.text(), self.endT.text(), self.agiT.text(), self.luckT.text()] res = [self.slashO.currentText(), self.strikeO.currentText(), self.pierceO.currentText(), self.fireO.currentText(), self.iceO.currentText(), self.elecO.currentText(), self.windO.currentText(), self.lightO.currentText(), self.darkO.currentText()] try: (int)(self.levelT.text()) (int)(self.strT.text()) (int)(self.magT.text()) (int)(self.endT.text()) (int)(self.agiT.text()) (int)(self.luckT.text()) except ValueError: popup("There is a number entry that isn't valid.\nEntries requiring numbers are:\nLEVEL\nSTR" "\nMAG\nEND\nAGI\nLUCK", "Critical") print("Not Saved") return if not (self.nameT.text() and not self.nameT.text().isspace()): popup("No name entered for your Persona. Name is a required field.", "Critical") print("No Name, not saved") return toWrite = Persona( self.nameT.text(), self.arcO.currentText(), self.levelT.text(), self.textT.toPlainText(), spellDeck, self.lsdic, stats, res, [self.listEL1.currentText(), self.listEL2.currentText()] ) json_reader.writeOne(toWrite, 'pers') temp = self.nameT.text() if (temp not in [self.listP.item(i).text() for i in range(self.listP.count())]): self.listP.addItem(temp) self.loadPer(temp) print("Saved Persona") def remove(self): """ Remove a created Persona from the list and delete the file on disk. """ if self.listP.currentItem().text() == "": return if not popup( "Are you certain you want to completely remove this Persona?\n(Cannot be undone)", "Warning" ): return print("Removing Persona " + self.listP.currentItem().text()) json_reader.deletePer(self.listP.currentItem().text()) self.listP.takeItem( [self.listP.item(i).text() for i in range(self.listP.count())].index( self.listP.currentItem().text()) ) def new(self): """ Open an empty Persona edit view. """ if self.createFrame and not popup("Override any unsaved changes?", "Warning"): return if self.createFrame: self.createFrame.close() self.buttonFrame.close() self.initUI(False) self.createFrame.show() self.mainframe.center() print("Created") def back(self): """ Return to the parent widget. """ print("Returned to main screen") self.mainframe.changeState(self.op)
class SpectralViewer(QWidget): def __init__(self, path, start_frame=0, gui_size=900, pixel_size_um=0.16, parent=None): self.path = path self.start_frame = start_frame self.gui_size = gui_size self.pixel_size_um = pixel_size_um self.initData() self.initUI() def initData(self): self.reader = ImageReader(self.path) # Mean projection if self.reader.n_frames > 0: self.mean_proj = self.reader.sum_proj(start_frame=self.start_frame) / (self.reader.n_frames - self.start_frame) else: self.mean_proj = self.reader.get_frame(0).astype(np.float64) # Kill the DC component self.mean_proj -= self.mean_proj.mean() Ny, Nx = self.mean_proj.shape self.Ny = Ny self.Nx = Nx # Frequencies self.yfreq = np.fft.fftfreq(Ny, d=self.pixel_size_um) self.xfreq = np.fft.fftfreq(Nx, d=self.pixel_size_um) self.freq_interval = np.abs((self.yfreq[1:] - self.yfreq[:-1])).min() Xfreq, Yfreq = np.meshgrid(self.xfreq, self.yfreq) self.rfreq = np.sqrt(Xfreq**2 + Yfreq**2) self.xfreq = Xfreq self.yfreq = Yfreq self.max_freq = int(np.ceil(self.rfreq.max())) # Filter self.take_freqs = np.ones(self.rfreq.shape, dtype=np.bool) # The actual substrate for showing / filtering self.I = self.mean_proj.copy() self.I_ft = np.fft.fft2(self.I) self.I_ft_filt = self.I_ft.copy() def initUI(self): # Master layout self.win = QWidget() L_master = QGridLayout(self.win) # Increase the Qt column stretch for the first column, which # encodes the actual images L_master.setColumnStretch(0, 1) # Assign the close event self.win.closeEvent = self.closeEvent # Left subwindow, for widgets self.win_left = QWidget(self.win) L_left = QGridLayout(self.win_left) L_master.addWidget(self.win_left, 0, 0, 1, 1) # Right subwindow, for images self.win_right = QWidget(self.win) L_right = QGridLayout(self.win_right) L_master.addWidget(self.win_right, 0, 1, 1, 1) # Two ImageView objects to contain the original and # displayed images titles = [ "Original image", "Selected band" ] self.labeledImageViews = [ LabeledImageView( parent=self.win_left, label=titles[j] ) for j in range(2) ] self.imageViews = [self.labeledImageViews[j].ImageView for j in range(2)] # Assign to the left window for j in range(2): L_left.addWidget(self.labeledImageViews[j], j%2, j//2) # Link every movement in X and Y between the different ImageView # objects for j in range(1, 2): self.imageViews[j].view.setXLink(self.imageViews[0].view) self.imageViews[j].view.setYLink(self.imageViews[0].view) # Widgets widget_align = Qt.AlignAbsolute slider_min_width = 125 # Frequency band definition self.band_0_lower_slider = FloatSlider( parent=self.win_right, name="Lower", minimum=0.0, maximum=self.max_freq, interval=self.freq_interval, init_value=0.0, min_width=slider_min_width, ) self.band_0_upper_slider = FloatSlider( parent=self.win_right, name="Upper", minimum=0.0, maximum=self.max_freq, interval=self.freq_interval, init_value=self.max_freq, min_width=slider_min_width, ) self.band_0_lower_slider.assign_callback(self.adjust_band) self.band_0_upper_slider.assign_callback(self.adjust_band) L_right.addWidget(self.band_0_lower_slider, 2, 0) L_right.addWidget(self.band_0_upper_slider, 3, 0) # Button to select either mean projection / individual frames self.combo_box_mode = LabeledQComboBox( ["Mean projection", "Individual frames"], "Mode", init_value="Mean projection", parent=self.win_right, ) self.combo_box_mode.assign_callback(self.combo_box_mode_callback) L_right.addWidget(self.combo_box_mode, 0, 0) # Button to auto-range the LUTs self.B_auto_range = QPushButton("LUT auto range", parent=self.win_right) self.B_auto_range.clicked.connect(self.auto_range_callback) L_right.addWidget(self.B_auto_range, 1, 0) # Frame slider self.frame_slider = IntSlider( minimum=0, maximum=self.reader.n_frames-1, interval=1, name="Frame", init_value=self.start_frame, min_width=slider_min_width, parent=self.win_right ) self.frame_slider.assign_callback(self.frame_slider_callback) L_right.addWidget(self.frame_slider, 4, 0) self.frame_slider.hide() self.imageViews[0].setImage(self.I) self.adjust_band(autoThresh=True) self.win.show() def adjust_band(self, autoThresh=False): """ Change the frequency band being displayed. """ t0 = self.band_0_lower_slider.value() t1 = self.band_0_upper_slider.value() # Ensure that t0 < t1 if t1 < t0: t2 = t1 t1 = t0 t0 = t2 elif t1 == t0: t0 = t0 - self.freq_interval * 0.5 t1 = t1 + self.freq_interval * 0.5 self.filter_image(t0, t1) self.imageViews[1].setImage( self.I_conv, autoRange=autoThresh, autoLevels=autoThresh, autoHistogramRange=autoThresh ) def filter_image(self, t0, t1): """ Take the band between frequencies *t0* and *t1*. """ self.take_freqs = np.logical_and( self.rfreq >= t0, self.rfreq < t1 ) self.I_ft_filt[:,:] = 0 self.I_ft_filt[self.take_freqs] = self.I_ft[self.take_freqs] self.I_conv = np.real(np.fft.ifft2(self.I_ft_filt, s=self.I.shape)) def update_primary_image(self, autoThresh=True): self.imageViews[0].setImage( self.I, autoRange=autoThresh, autoLevels=autoThresh, autoHistogramRange=autoThresh ) def combo_box_mode_callback(self): mode = self.combo_box_mode.currentText() if mode == "Mean projection": self.I = self.reader.sum_proj(start_frame=self.start_frame) / (self.reader.n_frames - self.start_frame) self.frame_slider.hide() elif mode == "Individual frames": self.I = self.reader.get_frame(int(self.frame_slider.value())) self.frame_slider.show() self.I -= self.I.mean() self.I_ft = np.fft.fft2(self.I) self.update_primary_image() self.adjust_band() def frame_slider_callback(self): if self.combo_box_mode.currentText() == "Individual frames": frame_index = int(self.frame_slider.value()) self.I = self.reader.get_frame(frame_index) self.I -= self.I.mean() self.I_ft = np.fft.fft2(self.I) self.update_primary_image() self.adjust_band() def auto_range_callback(self): self.imageViews[0].setImage( self.I, autoRange=True, autoLevels=True, autoHistogramRange=True ) self.imageViews[1].setImage( self.I_conv, autoRange=True, autoLevels=True, autoHistogramRange=True ) def closeEvent(self, event): """ Close this window and the file reader. """ self.reader.close() self.win.close() # self.close() event.accept()
class AddIngredientWidget(QWidget): def __init__(self, database, parent, ingredient_name): QWidget.__init__(self) self.add_ingredient_win = QWidget() self.add_ingredient_win.setFixedWidth(250) self.add_ingredient_win.setWindowTitle("Add Ingredient") self.add_ingredient_main_layout = QHBoxLayout() self.meal_planner_db = database self.setParent(parent) self.ingredient_name_input = QLineEdit() self.ingredient_name_input.setText(ingredient_name) self.calories_spinbox = QDoubleSpinBox() self.calories_spinbox.setMaximum(9999) self.carbs_spinbox = QDoubleSpinBox() self.carbs_spinbox.setMaximum(9999) self.sugar_spinbox = QDoubleSpinBox() self.sugar_spinbox.setMaximum(9999) self.fats_spinbox = QDoubleSpinBox() self.fats_spinbox.setMaximum(9999) self.protein_spinbox = QDoubleSpinBox() self.protein_spinbox.setMaximum(9999) self.add_ingredient_btn = QPushButton("Create Ingredient") self.add_ingredient_btn.clicked.connect(self.add_ingredient_to_recipe) self.cancel_win_btn = QPushButton("Cancel") self.cancel_win_btn.clicked.connect(self.add_ingredient_win.close) self.left_layout = QVBoxLayout() self.left_layout.addWidget(QLabel("Ingredient name")) self.left_layout.addWidget(self.ingredient_name_input) self.left_layout.addWidget(QLabel("Ingredient nutrition values")) self.left_layout.addWidget(QLabel("kCal/100g")) self.left_layout.addWidget(self.calories_spinbox) self.left_layout.addWidget(QLabel("carb/100g")) self.left_layout.addWidget(self.carbs_spinbox) self.left_layout.addWidget(QLabel("sugar/100g")) self.left_layout.addWidget(self.sugar_spinbox) self.left_layout.addWidget(QLabel("fat/100g")) self.left_layout.addWidget(self.fats_spinbox) self.left_layout.addWidget(QLabel("protein/100g")) self.left_layout.addWidget(self.protein_spinbox) self.left_layout.addWidget(self.add_ingredient_btn) self.left_layout.addWidget(self.cancel_win_btn) self.add_ingredient_main_layout.addLayout(self.left_layout) self.add_ingredient_win.setLayout(self.add_ingredient_main_layout) self.add_ingredient_win.show() @Slot() def add_ingredient_to_recipe(self): self.parent().ingredient_name_input.setText( self.ingredient_name_input.text()) ing_id = self.meal_planner_db.get_table_len("ingredients") self.meal_planner_db.add_ingredient(ing_id, self.ingredient_name_input.text(), self.calories_spinbox.value(), self.carbs_spinbox.value(), self.sugar_spinbox.value(), self.fats_spinbox.value(), self.protein_spinbox.value(), False) self.add_ingredient_win.close()
class DLPGUI(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) self.parent = parent self.supported_setups = ['BOTTOM-UP', 'TOP-DOWN'] self.supported_projectors = ['VisitechLRSWQ', 'VisitechLRS4KA'] self.supported_motors = ['ClearpathSDSK', 'ClearpathSCSK', 'Nanostage'] self.selected_setup = self.supported_setups[0] self.selected_projector = self.supported_projectors[0] self.selected_motor = self.supported_motors[0] self.stacked_layout = QStackedLayout() self.__setup_widget = None self.__dlp_main_widget = None if not self.__load_settings__(): self.__init_configuration_selection_widget__() self.__init_projector_selection_widget__() self.__init_motor_selection_widget__() self.stacked_layout.setCurrentIndex(0) self.setLayout(self.stacked_layout) def minimumSizeHint(self): return self.stacked_layout.currentWidget().minimumSizeHint() def sizeHint(self): return self.stacked_layout.currentWidget().sizeHint() def __load_settings__(self): base_path = Path(__file__).parent settings_path = str( (base_path / '../resources/PRINTER_SETTINGS.json').resolve()) settings_file = QFile(settings_path) if settings_file.open(QIODevice.ReadOnly | QIODevice.Text): file_data = QJsonDocument.fromJson( settings_file.readAll()).object() if "dlp_settings" in file_data: printer_setup = str(file_data["dlp_settings"]["printer_setup"]) if printer_setup == self.supported_setups[0]: self.__select_setup__(0) elif printer_setup == self.supported_setups[1]: self.__select_setup__(1) else: return False projector_setup = str( file_data["dlp_settings"]["projector_setup"]) if projector_setup == self.supported_projectors[0]: self.__select_projector__(None, 0) elif projector_setup == self.supported_projectors[1]: self.__select_projector__(None, 1) else: return False motor_setup = str(file_data["dlp_settings"]["motor_setup"]) if motor_setup == self.supported_motors[0]: self.__select_motor__(None, 0) elif motor_setup == self.supported_motors[1]: self.__select_motor__(None, 1) elif motor_setup == self.supported_motors[2]: self.__select_motor__(None, 2) else: return False return True settings_file.close() return False def __init_configuration_selection_widget__(self): self.__setup_widget = QWidget(self) setup_layout = QHBoxLayout() for idx in range(len(self.supported_setups)): button = QPushButton(self.supported_setups[idx], self.__setup_widget) button.setFixedSize(200, 200) button.clicked.connect(self.__select_setup__) setup_layout.addWidget(button) self.__setup_widget.setLayout(setup_layout) self.stacked_layout.addWidget(self.__setup_widget) # self.stacked_layout.setCurrentIndex(0) def __init_projector_selection_widget__(self): self.__projector_setup_widget = QWidget(self) projector_setup_layout = QHBoxLayout() for idx in range(len(self.supported_projectors)): button = QPushButton(self.supported_projectors[idx], self.__setup_widget) button.setFixedSize(200, 200) button.clicked.connect( lambda state=None, x=idx: self.__select_projector__(state, x)) projector_setup_layout.addWidget(button) self.__projector_setup_widget.setLayout(projector_setup_layout) self.stacked_layout.addWidget(self.__projector_setup_widget) def __init_motor_selection_widget__(self): self.__motor_setup_widget = QWidget(self) motor_setup_layout = QHBoxLayout() for idx in range(len(self.supported_motors)): button = QPushButton(self.supported_motors[idx], self.__setup_widget) button.setFixedSize(200, 200) button.clicked.connect( lambda state=None, x=idx: self.__select_motor__(state, x)) motor_setup_layout.addWidget(button) self.__motor_setup_widget.setLayout(motor_setup_layout) self.stacked_layout.addWidget(self.__motor_setup_widget) def __select_setup__(self, idx): self.selected_setup = self.supported_setups[idx] self.stacked_layout.setCurrentIndex(1) def __select_projector__(self, button_state, projector_id): self.selected_projector = self.supported_projectors[projector_id] self.stacked_layout.setCurrentIndex(2) def __select_motor__(self, button_state, motor_id): self.selected_motor = self.supported_motors[motor_id] self.__init_main_widget__() self.stacked_layout.setCurrentIndex(3) # self.parent.move(self.desktops.screen(0).rect().center() - self.__dlp_main_widget.rect().center()) def __init_main_widget__(self): self.__dlp_main_widget = QTabWidget(self) self.__dlp_main_widget.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum) self.dlp_controller = DLPMainController(self.selected_setup, self.selected_projector, self.selected_motor) self.__printer_widget = DLPPrinterGUI( dlp_controller=self.dlp_controller, parent=self.__dlp_main_widget) self.__slicer_widget = DLPSlicerGUI(dlp_controller=self.dlp_controller, parent=self.__dlp_main_widget) self.__settings_widget = DLPSettingsGUI( dlp_controller=self.dlp_controller, parent=self.__dlp_main_widget) self.__printer_widget.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum) self.__slicer_widget.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum) self.__settings_widget.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum) self.__dlp_main_widget.addTab(self.__printer_widget, 'DLP') self.__dlp_main_widget.addTab(self.__slicer_widget, 'Slicer') self.__dlp_main_widget.addTab(self.__settings_widget, 'Advanced Settings') self.stacked_layout.addWidget(self.__dlp_main_widget) self.dlp_controller.save_default_parameters() # self.__dlp_main_widget.move() # self.desktops = QDesktopWidget() # self.parent.move(self.desktops.screen(0).rect().center() - self.__dlp_main_widget.rect().center()) # self.__dlp_main_widget.move(QGuiApplication.desktop().screen().rect().center() - self.rect().center()) def reset_main_widget(self): self.dlp_controller.close_projector() self.__init_main_widget__() self.stacked_layout.setCurrentIndex(3) # self.parent.move(self.desktops.screen(0).rect().center() - self.__dlp_main_widget.rect().center()) @Slot() def closeEvent(self, event: QCloseEvent): if self.__setup_widget: self.__setup_widget.close() if self.__dlp_main_widget: self.__printer_widget.close() self.__slicer_widget.close() self.__settings_widget.close() self.__dlp_main_widget.close() event.accept() def get_settings_window(self, parent=None): printer_settings = QGroupBox("DLP Printer Settings:", parent) dlp_setup_label = QLabel("DLP Setup:", printer_settings) self.dlp_setup_combo = QComboBox(printer_settings) self.dlp_setup_combo.addItems(self.supported_setups) self.dlp_setup_combo.setCurrentIndex( self.supported_setups.index(self.selected_setup)) dlp_projector_label = QLabel("DLP Projector:", printer_settings) self.dlp_projector_combo = QComboBox(printer_settings) self.dlp_projector_combo.addItems(self.supported_projectors) self.dlp_projector_combo.setCurrentIndex( self.supported_projectors.index(self.selected_projector)) dlp_motor_label = QLabel("DLP Motor:", printer_settings) self.dlp_motor_combo = QComboBox(printer_settings) self.dlp_motor_combo.addItems(self.supported_motors) self.dlp_motor_combo.setCurrentIndex( self.supported_motors.index(self.selected_motor)) apply_button = QPushButton("Apply Changes", printer_settings) apply_button.clicked.connect(self.__apply_settings) printer_settings_layout = QGridLayout(printer_settings) printer_settings_layout.addWidget(dlp_setup_label, 1, 0) printer_settings_layout.addWidget(self.dlp_setup_combo, 1, 1) printer_settings_layout.addWidget(dlp_projector_label, 2, 0) printer_settings_layout.addWidget(self.dlp_projector_combo, 2, 1) printer_settings_layout.addWidget(dlp_motor_label, 3, 0) printer_settings_layout.addWidget(self.dlp_motor_combo, 3, 1) printer_settings_layout.addWidget(apply_button, 4, 1) return printer_settings @Slot() def __apply_settings(self): self.selected_setup = self.supported_setups[ self.dlp_setup_combo.currentIndex()] if self.supported_motors[self.dlp_motor_combo.currentIndex( )] is not self.selected_motor: self.selected_motor = self.supported_motors[ self.dlp_motor_combo.currentIndex()] self.dlp_controller.change_motor(self.selected_setup, self.selected_motor) if self.supported_projectors[self.dlp_projector_combo.currentIndex( )] is not self.selected_projector: self.selected_projector = self.supported_projectors[ self.dlp_projector_combo.currentIndex()] self.dlp_controller.change_projector(self.selected_projector) self.dlp_controller.save_default_parameters()
class SigProcToolbox(QWidget): """Class to handle all processing related to digital signal processing""" def __init__(self, main_frame): self.main_frame = main_frame # Initialize tab screen self.window = QWidget() self.layout = QVBoxLayout(self.window) self.tabs = QTabWidget() self.tabs.layout = QVBoxLayout() self.tab1 = QWidget() self.tab2 = QWidget() self.checkbox_states = {} self.wavelet_parameters = {} self.coeffs = dict() self.coeffs_zero = dict() self.coeffs_waverec = dict() self.checkbox_keep_wavelet = dict() self.attenauation_wavelet = dict() self.args = dict() self.fig_wavelet = dict() self.wavelet_combo_box = dict() self.sig_corrected = None self.order_decomp = None # Add tabs self.tabs.addTab(self.tab1, "Fourier Transform") self.tabs.addTab(self.tab2, "Wavelet Denoising") # Create first tab self._set_ui_tab1() # Create second tab self._set_ui_tab2() # Add tabs to widget self.layout.addWidget(self.tabs) self.window.setLayout(self.layout) self.window.show() """ FUNCTION TO SET USER INTERFACE OF DIFFERENT TABS """ def _set_ui_tab1(self): self.tab1.layout = QVBoxLayout(self.tabs) self.pushButton1 = QPushButton("THIS PART WILL COME LATER") QObject.connect(self.pushButton1, SIGNAL('clicked()'), self.on_click) self.tab1.layout.addWidget(self.pushButton1) self.tab1.setLayout(self.tab1.layout) def _set_ui_tab2(self): """" _set_ui_tab2 @:brief Set user interface of the second tab : wavelet processing tab see pywt documentation @:parameter self @:return None """ lay = QGridLayout(self.tab2) label = QLabel("Wavelet family :") lay.addWidget(label, 0, 1) # all possible method for wevelet processing for i, (key, text) in enumerate(( ("haar", "Haar"), ("db", "daubechies"), ("sym", "Symlets"), ("coif", "Coiflets"), ("bior", "biorthogonal"), ("rbio", "reverse-biorthogonal"), ("dmey", "Discret FIR Meyer"), ("gaus", "gaussian"), ("mexh", "Mexican hat"), ("morl", "morlet"), ("cgau", "Complex Gaussian"), ("shan", "Shanon"), ("fbsp", "Frequency B-Spline"), ("cmor", "Complex Morlet"), )): checkbox = QCheckBox(text) checkbox.setChecked(False) lay.addWidget(checkbox, i + 1, 1) self.checkbox_states[key] = checkbox # set combo box with method self.wavelet_combo_box[key] = QComboBox() l = pywt.wavelist(key) self.wavelet_combo_box[key].addItems(l) lay.addWidget(self.wavelet_combo_box[key], i + 1, 2) # choose order of decomposition label_order_decomp = QLabel("choose order of decomposition : \t") lay.addWidget(label_order_decomp, 0, 0) self.order_decomp = QLineEdit() lay.addWidget(self.order_decomp, 1, 0) self.process_wavelet = QPushButton("Process") QObject.connect(self.process_wavelet, SIGNAL('clicked()'), self._on_process_wavelet) lay.addWidget(self.process_wavelet, i + 2, 3) self.tab2.setLayout(lay) """ PROCESSING AND COMPUTATION FUNCTION TAB 1 """ def on_click(self): print("TBD") """ PROCESSING AND COMPUTATION FUNCTION TAB 2 """ def _on_process_wavelet(self): """" _on_process_wavelet(self) @:brief This function is used to process all choices made by the user when it click on the process button on the second tab. We will check that user only checked one wavelet method box and that he entered all number need. Then we will store that information for further use We process the wavelet decomposition in this function Call wavelet_to_keep() @:parameter self @:return None """ my_import = self.main_frame.dict_tabs["Tab_{}".format( self.main_frame.tabs.currentIndex())]["import"] x_lower = self.main_frame.dict_tabs["Tab_{}".format( self.main_frame.tabs.currentIndex())]["lim"][0] x_upper = self.main_frame.dict_tabs["Tab_{}".format( self.main_frame.tabs.currentIndex())]["lim"][1] s = 0 for key, value in self.checkbox_states.items(): if value.isChecked(): self.wavelet_parameters[ "wavelet_family"] = self.wavelet_combo_box[ key].currentText() s += 1 if s != 1: self.main_frame.error( "Error on check boxes : you have to check only one box") else: print("you have choose : {}".format( self.wavelet_parameters["wavelet_family"])) try: self.wavelet_parameters["order_decomp"] = int( self.order_decomp.text()) except ValueError: self.main_frame.error( "enter an integer as decomposition order") if my_import.type == "s" or my_import.type == "csv": sig = my_import.data["yspectre"][x_lower:x_upper] elif my_import.type == "fits": idx2 = my_import.fits_data["Wav"].columns.get_loc("Intensity") sig = my_import.fits_data["Wav"].iloc[x_lower:x_upper, idx2].to_numpy() else: raise ValueError( "No x and y data for graph : unknown format of file") self.coeffs = pywt.wavedec( sig, self.wavelet_parameters["wavelet_family"], self.wavelet_parameters["order_decomp"]) for j in range(len(self.coeffs)): self.coeffs_zero["{}".format(j)] = [] for i in range(len(self.coeffs)): if i != j: self.coeffs_zero["{}".format(j)].append( np.asarray([0 for _ in range(len(self.coeffs[i]))])) else: self.coeffs_zero["{}".format(j)].append( np.asarray(self.coeffs[i])) for key, value in self.coeffs_zero.items(): self.coeffs_waverec[key] = pywt.waverec( self.coeffs_zero[key], self.wavelet_parameters["wavelet_family"]) self.args["lower"] = x_lower self.args["upper"] = x_upper self.args["import"] = my_import self.args["lim"] = self.main_frame.dict_tabs["Tab_{}".format( self.main_frame.tabs.currentIndex())]["lim"] if my_import.type == "s" or my_import.type == "csv": self.args["x"] = my_import.data["lambda"][x_lower:x_upper] elif my_import.type == "fits": idx1 = my_import.fits_data["Wav"].columns.get_loc( "Wavelength1") self.args["x"] = my_import.fits_data["Wav"].iloc[ x_lower:x_upper, idx1].to_numpy() else: raise ValueError( "No x and y data for graph : unknown format of file") self.wavelet_to_keep() def wavelet_to_keep(self): """ wavelet_to_keep(self) @:brief Propose to the user all the results from the wavelet decomposition User have to choose what he wants to continue (which signals to keep with attenuation or not) If you select a graph and don't put a number in the attenuation column the default value is 1 When button is click call : _on_wavelet_return @:parameter self @:return None """ self.window = QWidget() lay = QGridLayout(self.window) i = 0 label = QLabel("attenuation coeff (1 by default)") lay.addWidget(label, i, 2) for key, value in self.coeffs_waverec.items(): checkbox = QCheckBox("Keep that part ?") checkbox.setChecked(False) self.checkbox_keep_wavelet[key] = checkbox lay.addWidget(checkbox, i + 1, 1) attenuation = QLineEdit() lay.addWidget(attenuation, i + 1, 2) self.attenauation_wavelet[key] = attenuation plt.close('all') figure = plt.gcf() figure.set_size_inches(20, 8) plt.plot(self.args["x"], self.coeffs_waverec[key][:len(self.args["x"])]) self.fig_wavelet[key] = SigProcToolboxFig(figure) lay.addWidget(self.fig_wavelet[key], i + 1, 0) plt.close(figure) i += 1 button = QPushButton("Process") QObject.connect(button, SIGNAL('clicked()'), self._on_wavelet_return) lay.addWidget(button, i + 1, 3) self.window.setLayout(lay) self.window.show() self.window.showMaximized() def _on_wavelet_return(self): """ _on_wavelet_return @:brief Compute choices of the user for the wavelet processing Call MainFrame method : add_tab_from_wavelet(self.args) to add a tab with the processed signal @:parameter self @:return None """ to_keep = dict() for key, value in self.checkbox_keep_wavelet.items(): if value.isChecked(): to_keep[key] = self.coeffs_waverec[key][:len(self.args["x"])] self.sig_corrected = 0 for key, value in to_keep.items(): try: print(self.attenauation_wavelet[key].text()) q = float(self.attenauation_wavelet[key].text()) if q < 0: q = 0 elif q > 1: q = 1 except ValueError: q = 1 self.sig_corrected += to_keep[key] * q self.args["y"] = self.sig_corrected self.window.close() self.main_frame.add_tab_from_wavelet(self.args)
class EnglCourseDBApp: def __init__(self): self.db = EnglCourseDB() self.app = QApplication(sys.argv) self.ui1 = ui1.Ui_Form() self.Form1 = QWidget() self.ui1.setupUi(self.Form1) self.ui2 = ui2.Ui_Form() self.Form2 = QWidget() self.ui2.setupUi(self.Form2) self.current_found_person = "fullname" self.add_or_change_person_info = { "fullname": None, "course": None, "date": None, "date_when_": "", "lvl": None, "lvl_when_": "", "current_lvl": "", "on_studying": False, } self.ui1.add_or_change_btn.clicked.connect(self.open_second_window) self.ui1.search_btn.clicked.connect(self.find) self.ui1.delete_btn.clicked.connect(self.delete) self.ui2.date_came_btn.clicked.connect(lambda: exec( 'self.add_or_change_person_info["date_when_"] = "came"', {'self': self})) self.ui2.date_left_btn.clicked.connect(lambda: exec( 'self.add_or_change_person_info["date_when_"] = "left"', {'self': self})) self.ui2.lvl_came_btn.clicked.connect(lambda: exec( 'self.add_or_change_person_info["lvl_when_"] = "came"', {'self': self})) self.ui2.lvl_left_btn.clicked.connect(lambda: exec( 'self.add_or_change_person_info["lvl_when_"] = "left"', {'self': self})) self.ui2.on_studying_true_btn.clicked.connect(lambda: exec( 'self.add_or_change_person_info["on_studying"] = True', {'self': self})) self.ui2.on_studying_false_btn.clicked.connect(lambda: exec( 'self.add_or_change_person_info["on_studying"] = False', {'self': self})) self.ui2.add_or_change_btn.clicked.connect(self.add_or_change) def run(self): self.Form1.show() sys.exit(self.app.exec_()) def find(self): information = self.db.find(self.ui1.search_line_edit.text()) result = "" if not information: QMessageBox.about(QWidget(), "Error", "There is no such person in the database") else: for info in information: course = info[0] width = int((56 - len(course)) / 2) course = course.rjust(width, "-") course += "-" * width arr = [] [arr.append(info[1][i + 2]) for i in range(len(info[1]) - 2)] result += f"{course}\nDate:\n\tcame:{arr[0]}\n\tleft:{arr[1]}\nLevel:\n\tcame:{arr[2]}\n\tleft:{arr[3]}\n\tcurrent:{arr[4]}\n\nOn studying: {arr[5]}\n\n" self.ui1.info_text_edit.setText(result) def open_second_window(self): self.Form2.show() def delete(self): self.db.delete(self.ui1.search_line_edit.text()) self.ui1.info_text_edit.setText("") self.ui1.search_line_edit.setText("") def add_or_change(self): self.Form2.close() self.ui1.info_text_edit.setText("") self.ui1.search_line_edit.setText("") try: available_in_db = self.db.find(self.ui2.fullname_line_edit.text(), self.ui2.course_line_edit.text()) if not available_in_db: self.db.add(self.ui2.course_line_edit.text(), self.ui2.fullname_line_edit.text()) except: QMessageBox.about(QWidget(), "Error", "There is no such course in the database") else: columns_with_data = [ [ 'level_when_' + self.add_or_change_person_info['lvl_when_'], self.ui2.lvl_line_edit.text() ], ['current_level', self.ui2.current_lvl_line_edit.text()], ['on_studying', self.add_or_change_person_info['on_studying']], [ 'date_when_' + self.add_or_change_person_info['date_when_'], self.ui2.date_line_edit.text() ], ["fullname", self.ui2.fullname_line_edit.text()] ] for column in columns_with_data: self.db.update(self.ui2.course_line_edit.text(), self.ui2.fullname_line_edit.text(), column[0], column[1]) finally: for i in self.add_or_change_person_info.keys(): self.add_or_change_person_info[i] = None self.ui2.fullname_line_edit.setText("") self.ui2.course_line_edit.setText("") self.ui2.date_line_edit.setText("") self.ui2.lvl_line_edit.setText("") self.ui2.current_lvl_line_edit.setText("")