class ReverseWidget(ToolWidget): def __init__(self, parent=None): super(ReverseWidget, self).__init__(parent) self.tineye_radio = QRadioButton(self.tr("TinEye")) self.tineye_radio.setIcon(QIcon("icons/tineye.png")) self.google_radio = QRadioButton(self.tr("Google")) self.google_radio.setIcon(QIcon("icons/google.svg")) self.bing_radio = QRadioButton(self.tr("Bing")) self.bing_radio.setIcon(QIcon("icons/bing.svg")) self.root_radio = QRadioButton(self.tr("RootAbout")) self.root_radio.setIcon(QIcon("icons/rootabout.png")) self.karma_radio = QRadioButton(self.tr("KarmaDecay")) self.karma_radio.setIcon(QIcon("icons/karmadecay.jpg")) self.tineye_radio.setChecked(True) self.last_radio = self.tineye_radio self.web_view = QWebEngineView() self.choose() self.tineye_radio.clicked.connect(self.choose) self.google_radio.clicked.connect(self.choose) self.bing_radio.clicked.connect(self.choose) self.root_radio.clicked.connect(self.choose) self.karma_radio.clicked.connect(self.choose) top_layout = QHBoxLayout() top_layout.addWidget(QLabel(self.tr("Search engine:"))) top_layout.addWidget(self.tineye_radio) top_layout.addWidget(self.google_radio) top_layout.addWidget(self.bing_radio) top_layout.addWidget(self.root_radio) top_layout.addWidget(self.karma_radio) top_layout.addStretch() main_layout = QVBoxLayout() main_layout.addLayout(top_layout) main_layout.addWidget(self.web_view) self.setLayout(main_layout) def choose(self): if self.tineye_radio.isChecked(): self.web_view.load(QUrl("https://tineye.com/")) self.last_radio = self.tineye_radio elif self.google_radio.isChecked(): self.web_view.load(QUrl("https://www.google.com/imghp")) self.last_radio = self.google_radio elif self.bing_radio.isChecked(): self.web_view.load( QUrl("https://www.bing.com/?scope=images&nr=1&FORM=NOFORM")) self.last_radio = self.bing_radio elif self.root_radio.isChecked(): self.web_view.load(QUrl("http://rootabout.com/")) self.last_radio = self.root_radio elif self.karma_radio.isChecked(): self.web_view.load(QUrl("http://karmadecay.com/")) self.last_radio = self.karma_radio else: self.last_radio.setChecked(True)
class Window(QWidget): def __init__(self): super().__init__() self.init_ui() def init_ui(self): self.lbl = QLabel('Which do you like best?') self.dog = QRadioButton('Dogs') self.cat = QRadioButton('Cats') self.btn = QPushButton('Select') layout = QVBoxLayout() layout.addWidget(self.lbl) layout.addWidget(self.dog) layout.addWidget(self.cat) layout.addWidget(self.btn) self.setLayout(layout) self.btn.clicked.connect( lambda: self.btn_click(self.dog.isChecked(), self.lbl)) self.show() def btn_click(self, chk, lbl): if chk: lbl.setText('I guess you like dogs') else: lbl.setText("So its cats for you")
class PrimaryMonitorSelect(QWidget): def __init__(self, parent): super(PrimaryMonitorSelect, self).__init__() self.parent = parent self.layout = QHBoxLayout() self.layout.setAlignment(Qt.AlignCenter) self.setLayout(self.layout) self.label = QLabel("Primary Monitor:") self.layout.addWidget(self.label) self.radio_buttons_setup() def radio_buttons_setup(self): self.leftRadioButton = QRadioButton("Left") self.leftRadioButton.toggled.connect(self.handle_toggled) self.rightRadioButton = QRadioButton("Right") self.rightRadioButton.toggled.connect(self.handle_toggled) if defaultSettings.list[2][1] == "True": self.leftRadioButton.setChecked(True) else: self.rightRadioButton.setChecked(True) self.layout.addWidget(self.leftRadioButton) self.layout.addWidget(self.rightRadioButton) def handle_toggled(self): defaultSettings.list[2][1] = str(self.leftRadioButton.isChecked()) defaultSettings.write()
class IntroductionPage(QtWidgets.QWizardPage): def __init__(self, *args, **kwargs): super(IntroductionPage, self).__init__(*args, **kwargs) # ____COMBO BOX____ self.radioButtonsContent = QGroupBox('new auction OR load auction') self.radioButtonNew = QRadioButton('new') self.radioButtonLoad = QRadioButton('load') self.radioHBox = QHBoxLayout() self.radioHBox.addWidget(self.radioButtonNew, 0) self.radioHBox.addWidget(self.radioButtonLoad, 1) self.radioButtonsContent.setLayout(self.radioHBox) self.radioButtonNew.toggled self.radioButtonNew.toggled.connect(self.changeViewFromRadio) # ___________________SELECT NUMBER OF CONTENDER_________________________ self.newViewContent = QGroupBox('new auction:') self.newViewContent.setVisible(False) self.titleNumberOfContenders = QLabel('Select number of contenders') self.numberOfContenders = QComboBox() self.numberOfContenders.addItems([ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12' ]) self.newViewBoxLayout = QHBoxLayout() self.newViewBoxLayout.addWidget(self.titleNumberOfContenders, 0) self.newViewBoxLayout.addWidget(self.numberOfContenders, 1) self.newViewContent.setLayout(self.newViewBoxLayout) self.registerField("contenderCount*", self.numberOfContenders) # ___________________LOAD DATA_________________________ self.loadViewContent = QGroupBox('Load data:') self.loadViewContent.setVisible(False) self.titleLoadData = QLabel("Select folder with save") self.loadButton = QPushButton() self.loadButton.setText("search saved file") self.loadViewBoxLayout = QVBoxLayout() self.loadViewBoxLayout.addWidget(self.titleLoadData) self.loadViewBoxLayout.addWidget(self.loadButton) self.loadViewContent.setLayout(self.loadViewBoxLayout) # ___Add Elements to layout___ self.layout = QVBoxLayout() self.layout.addWidget(self.radioButtonsContent) self.layout.addWidget(self.newViewContent) self.layout.addWidget(self.loadViewContent) self.setLayout(self.layout) def checkableNew(self): self.newViewContent.setVisible(True) self.loadViewContent.setVisible(False) def checkableLoad(self): self.newViewContent.setVisible(False) self.loadViewContent.setVisible(True) @Slot() def loadDataClicked(self): print("newAuctionSetted to False") @Slot() def changeViewFromRadio(self, IsRadioButtonNew): if IsRadioButtonNew: print("new RadioButton clicked") self.checkableNew() else: print("load RadioButton clicked") self.checkableLoad() def nextId(self): # return the id of the next page, retrun 1 because Wizard.class1 has problems if self.radioButtonNew.isChecked(): return 1 else: return 2
class SubsTextureManagerUI(QtWidgets.QDialog): def __init__(self): super(SubsTextureManagerUI, self).__init__() self.setWindowTitle('PxrSurface from Substance Textures') self.name_input = None self.pxr_surface_name = None self.directory = "none" #keys are the texture types, values are [file name, selected?, node_name] self.texture_data = { "diffColor": ["none", False, "none"], "specFaceColor": ["none", False, "none"], "specEdgeColor": ["none", False, "none"], "specRough": ["none", False, "none"], "normal": ["none", False, "none"], "bump": ["none", False, "none"], "glowColor": ["none", False, "none"], "presence": ["none", False, "none"] } self.reverse_normals = False self.spec_mode_artistic = False self.color_mode_subsurface = False self.loaded_existing = False self.buildUI() # UI AND FILE MANAGEMENT def buildUI(self): print "building" self.layout = QtWidgets.QVBoxLayout(self) self.loadPxrWidget = QtWidgets.QWidget() self.loadPxrLayout = QtWidgets.QHBoxLayout(self.loadPxrWidget) self.loadPxrBtn = QtWidgets.QPushButton("Load PxrSurface of Selected") self.loadPxrLayout.addWidget(self.loadPxrBtn) self.loadPxrBtn.clicked.connect(self.find_existing_pxr) self.layout.addWidget(self.loadPxrWidget) #Fields to enter PxrSurface name and locate the texture directory self.nameWidget = QtWidgets.QWidget() self.nameLayout = QtWidgets.QHBoxLayout(self.nameWidget) self.pxrNameLabel = QtWidgets.QLabel("PxrSurface Name:") self.nameLayout.addWidget(self.pxrNameLabel) self.pxrNameField = QtWidgets.QLineEdit() self.nameLayout.addWidget(self.pxrNameField) self.layout.addWidget(self.nameWidget) self.directoryWidget = QtWidgets.QWidget() self.directoryLayout = QtWidgets.QHBoxLayout(self.directoryWidget) self.directoryLabel = QtWidgets.QLabel("Texture Directory:") self.directoryLayout.addWidget(self.directoryLabel) self.directoryField = QtWidgets.QLineEdit() self.directoryLayout.addWidget(self.directoryField) self.directoryBtn = QtWidgets.QPushButton("Locate") self.directoryLayout.addWidget(self.directoryBtn) self.directoryBtn.clicked.connect(self.locate_directory) self.layout.addWidget(self.directoryWidget) #All Textures checkbox, checkbox for each texture file found self.plugWidget = QtWidgets.QWidget() self.plugLayout = QtWidgets.QVBoxLayout(self.plugWidget) self.plugCheckbox = QtWidgets.QCheckBox() self.plugCheckbox.toggle() self.plugCheckbox.setText("Plug in all available textures") self.plugLayout.addWidget(self.plugCheckbox) self.plugCheckbox.stateChanged.connect(self.plug_checkbox_handler) self.filesWidget = QtWidgets.QListWidget() self.plugLayout.addWidget(self.filesWidget) self.filesWidget.setEnabled(False) self.layout.addWidget(self.plugWidget) #checkboxes to reverse normals, set diffuse texture destination, specular color options self.optionsWidget = QtWidgets.QWidget() self.optionsLayout = QtWidgets.QVBoxLayout(self.optionsWidget) self.diffDestLabel = QtWidgets.QLabel("Color texture destination:") self.optionsLayout.addWidget(self.diffDestLabel) self.diffDestWidget = QtWidgets.QWidget() self.diffDestLayout = QtWidgets.QHBoxLayout(self.diffDestWidget) self.diffDiffuseRadio = QRadioButton("Diffuse") self.diffDiffuseRadio.setChecked(True) self.diffDestLayout.addWidget(self.diffDiffuseRadio) self.diffSubsurfaceRadio = QRadioButton("Subsurface") self.diffDestLayout.addWidget(self.diffSubsurfaceRadio) self.optionsLayout.addWidget(self.diffDestWidget) self.specDestLabel = QtWidgets.QLabel("Primary specular mode:") self.optionsLayout.addWidget(self.specDestLabel) self.specDestWidget = QtWidgets.QWidget() self.specDestLayout = QtWidgets.QHBoxLayout(self.specDestWidget) self.specArtisticRadio = QRadioButton("Artistic") self.specArtisticRadio.setChecked(True) self.specDestLayout.addWidget(self.specArtisticRadio) self.specPhysicalRadio = QRadioButton("Physical") self.specDestLayout.addWidget(self.specPhysicalRadio) self.optionsLayout.addWidget(self.specDestWidget) self.reverseCheckbox = QtWidgets.QCheckBox() self.reverseCheckbox.toggle() self.reverseCheckbox.setText("Invert bump") self.optionsLayout.addWidget(self.reverseCheckbox) self.layout.addWidget(self.optionsWidget) #Apply and Close buttons self.btnWidget = QtWidgets.QWidget() self.btnLayout = QtWidgets.QHBoxLayout(self.btnWidget) self.applyBtn = QtWidgets.QPushButton("Create New") self.btnLayout.addWidget(self.applyBtn) self.applyBtn.clicked.connect(self.createPxr) self.updateButton = QtWidgets.QPushButton("Update Existing") self.btnLayout.addWidget(self.updateButton) self.updateButton.clicked.connect(self.updatePxr) self.closeBtn = QtWidgets.QPushButton("Close") self.btnLayout.addWidget(self.closeBtn) self.closeBtn.clicked.connect(self.close) self.layout.addWidget(self.btnWidget) def find_existing_pxr(self): objSel = cmds.ls(sl=True, s=1, dag=1) if len(objSel) == 0: cmds.warning("Please select a mesh") return True for object in objSel: pxr = nodes.get_bxdf(nodes.get_shape_shading_engine(object)) if pxr: self.pxr_surface_name = pxr break self.pxrNameField.setText(self.pxr_surface_name) if not self.pxr_surface_name: cmds.warning("No existing PxrSurface found. Use 'Create and Assign' option.") return connections = cmds.listConnections(self.pxr_surface_name, connections=True) print connections for i in range(0, len(connections), 2): plug = connections[i] input = connections[i+1] if "diffuseColor" in plug: self.texture_data["diffColor"][2] = input if "specularFaceColor" in plug: self.texture_data["specFaceColor"][2] = input if "specularEdgeColor" in plug: self.texture_data["specEdgeColor"][2] = input if "specularRoughness" in plug: self.texture_data["specRough"][2] = input if "bumpNormal" in plug: if "normal" in input: self.texture_data["normal"][2] = input else: self.texture_data["bump"][2] = input if "glowColor" in plug: self.texture_data["glowColor"][2] = input if "presence" in plug: self.texture_data["presence"][2] = input self.loaded_existing = True def plug_checkbox_handler(self): if self.plugCheckbox.isChecked(): for i in range(self.filesWidget.count()): self.filesWidget.item(i).setCheckState(QtCore.Qt.Checked) self.filesWidget.setEnabled(False) else: self.filesWidget.setEnabled(True) def locate_directory(self): self.directory = QtWidgets.QFileDialog.getExistingDirectory(self, 'Select directory', os.path.join(cmds.workspace(q=True, rd=True), 'sourceimages')) self.directoryField.setText(self.directory) self.update_file_list() def update_file_list(self): print "listing" if self.directory == "none": return onlyFiles = [f for f in listdir(self.directory) if self.check_file_type(join(self.directory, f))] for file in onlyFiles: if "_DiffuseColor" in file: self.texture_data["diffColor"][0] = file if "_SpecularFaceColor" in file: self.texture_data["specFaceColor"][0] = file if "_SpecularEdgeColor" in file: self.texture_data["specEdgeColor"][0] = file if "_SpecularRoughness" in file: self.texture_data["specRough"][0] = file if "_Normal" in file: self.texture_data["normal"][0] = file if "_Displacement" in file: self.texture_data["bump"][0] = file if "_GlowColor" in file: self.texture_data["glowColor"][0] = file if "_Presence" in file: self.texture_data["presence"][0] = file self.filesWidget.clear() for key in self.texture_data: if self.texture_data[key][0] != "none": print "adding" listText = self.texture_data[key][0] temp = QtWidgets.QListWidgetItem(listText) temp.setCheckState(QtCore.Qt.Checked) self.filesWidget.addItem(temp) def check_file_type(self, path): return (isfile(path) and ".png" in path and ".tex" not in path) def collect_user_input(self): self.name_input = self.pxrNameField.text() self.directory = self.directoryField.text() for i in range(self.filesWidget.count()): if self.filesWidget.item(i).checkState() == QtCore.Qt.Checked: for key in self.texture_data.keys(): if (self.texture_data[key][0] == self.filesWidget.item(i).text()): self.texture_data[key][1] = True self.spec_mode_artistic = self.specArtisticRadio.isChecked() self.color_mode_subsurface = self.diffSubsurfaceRadio.isChecked() self.reverse_normals = self.reverseCheckbox.isChecked() def bad_use(self): selected = cmds.ls(sl=True, fl=True) if len(selected) == 0: cmds.warning("Please select a mesh") return True print selected if not self.name_input: cmds.warning("Please enter a PxrSurface name") return True if not self.directory: cmds.warning("Please locate a texture directory") return True return False #PXRSURFACE MANIPULATION def createPxr(self): print "creating" self.collect_user_input() if self.bad_use(): return nodes.create_and_assign_bxdf('PxrSurface') sel = cmds.ls(sl=True)[0] self.pxr_surface_name = cmds.rename(sel, self.name_input) for key in self.texture_data.keys(): if self.texture_data[key][1]: self.add_tex_node(key) self.update_tex(key) if !self.texture_data["diffColor"][1]: cmds.setAttr('%s.diffuseGain' % self.pxr_surface_name, 0.0) cmds.select(self.pxr_surface_name) def updatePxr(self): print "updating" self.collect_user_input() if self.bad_use(): return if not self.loaded_existing or not self.pxr_surface_name: cmds.warning("No existing PxrSurface found. Use 'Create and Assign' option.") return for key in self.texture_data.keys(): if self.texture_data[key][1]: if self.texture_data[key][2] == "none": self.add_tex_node(key) self.update_tex(key) if self.texture_data["diffColor"][2] == "none": cmds.setAttr('%s.diffuseGain' % self.pxr_surface_name, 0.0) cmds.select(self.pxr_surface_name) def add_tex_node(self, key): if key == "normal": nodes.create_and_select('PxrNormalMap') elif key == "bump": nodes.create_and_select('PxrBump') else: nodes.create_and_select('PxrTexture') nodeName = cmds.ls(sl=True)[0] if key == "diffColor": if self.color_mode_subsurface: print "adding subsurface color texture" nodeName = cmds.rename(nodeName, '%s_subsurface_tex' % self.pxr_surface_name) cmds.connectAttr('%s.resultRGB' % nodeName, '%s.subsurfaceColor' % self.pxr_surface_name, f=True) cmds.setAttr('%s.subsurfaceGain' % self.pxr_surface_name, 1.0) cmds.setAttr('%s.diffuseGain' % self.pxr_surface_name, 0.0) else: print "adding diffuse color texture" nodeName = cmds.rename(nodeName, '%s_diffuse_tex' % self.pxr_surface_name) cmds.connectAttr('%s.resultRGB' % nodeName, '%s.diffuseColor' % self.pxr_surface_name, f=True) cmds.setAttr('%s.subsurfaceGain' % self.pxr_surface_name, 0.0) cmds.setAttr('%s.diffuseGain' % self.pxr_surface_name, 1.0) elif key == "specFaceColor": if self.spec_mode_artistic: print "adding specular face color texture, ARTISTIC" cmds.setAttr('%s.specularFresnelMode' % self.pxr_surface_name, 0) nodeName = cmds.rename(nodeName, '%s_spec_face_color_tex' % self.pxr_surface_name) cmds.connectAttr('%s.resultRGB' % nodeName, '%s.specularFaceColor' % self.pxr_surface_name, f=True) else: print "adding specular face color texture, PHYSICAL" #ADD CHANGES TO EXTINCTION COEFF cmds.setAttr('%s.specularFresnelMode' % self.pxr_surface_name, 1) nodeName = cmds.rename(nodeName, '%s_spec_edge_physical_color_tex' % self.pxr_surface_name) cmds.connectAttr('%s.resultRGB' % nodeName, '%s.specularEdgeColor' % self.pxr_surface_name, f=True) elif key == "specEdgeColor": if self.spec_mode_artistic: print "adding specular edge color texture" nodeName = cmds.rename(nodeName, '%s_spec_edge_color_tex' % self.pxr_surface_name) cmds.connectAttr('%s.resultRGB' % nodeName, '%s.specularEdgeColor' % self.pxr_surface_name, f=True) elif key == "specRough": print "adding specular roughness texture" nodeName = cmds.rename(nodeName, '%s_spec_rough_tex' % self.pxr_surface_name) cmds.connectAttr('%s.resultR' % nodeName, '%s.specularRoughness' % self.pxr_surface_name, f=True) elif key == "normal": print "adding global normal texture" nodeName = cmds.rename(nodeName, '%s_global_normal' % self.pxr_surface_name) cmds.connectAttr('%s.resultN' % nodeName, '%s.bumpNormal' % self.pxr_surface_name, f=True) cmds.setAttr('%s.invertBump' % nodeName, self.reverse_normals) elif key == "bump" and self.texture_data["normal"][2] == "none": print "adding global bump texture" nodeName = cmds.rename(nodeName, '%s_global_bump' % self.pxr_surface_name) cmds.connectAttr('%s.resultN' % nodeName, '%s.bumpNormal' % self.pxr_surface_name, f=True) elif key == "glowColor": print "adding glow color texture" nodeName = cmds.rename(nodeName, '%s_glow_tex' % self.pxr_surface_name) cmds.connectAttr('%s.resultRGB' % nodeName, '%s.glowColor' % self.pxr_surface_name, f=True) cmds.setAttr('%s.glowGain' % self.pxr_surface_name, 1.0) elif key == "presence": print "adding presence texture" nodeName = cmds.rename(nodeName, '%s_presence_tex' % self.pxr_surface_name) cmds.connectAttr('%s.resultR' % nodeName, '%s.presence' % self.pxr_surface_name, f=True) self.texture_data[key][2] = nodeName def update_tex(self, key): if self.texture_data[key][2] == "none": return cmds.setAttr('%s.filename' % self.texture_data[key][2], os.path.join(self.directory, self.texture_data[key][0]), type='string')
class PeopleTab(QWidget): def __init__(self, parent): QWidget.__init__(self) self.Parent = parent self.PeoplTitle = 'PEOPLE' self.UI() @property def Title(self): return self.PeoplTitle def UI(self): self.widgets() self.layouts() self.funcDisplayPeople() def widgets(self): # People widgets ########################################################### # Top layout (search people) widgets self.searchPeopleText = QLabel("Search: ") self.searchPeopleEntry = QLineEdit() self.searchPeopleEntry.setPlaceholderText("Search people..") self.searchPeopleBtn = QPushButton("Search") self.searchPeopleBtn.clicked.connect(self.searchPeople) self.refreshPeopleBtn = QPushButton("Refresh") self.refreshPeopleBtn.clicked.connect(self.funcDisplayPeople) # Middle layout (list people) widgets with radio buttons self.allPeopleRadioBtn = QRadioButton("All people") self.employeesPeopleRadioBtn = QRadioButton("Employees") self.contractorsPeopleRadioBtn = QRadioButton("Contractors") self.subcontractorsPeopleRadioBtn = QRadioButton("Subcontractors") self.listPeopleBtn = QPushButton("List") self.listPeopleBtn.clicked.connect(self.funcListPeople) # Bottom layout widget, a table showing people self.peopleTable = QTableWidget() self.peopleTable.verticalHeader().hide() self.peopleTable.setSortingEnabled(True) self.peopleTable.setShowGrid(False) self.peopleTable.verticalHeader().setDefaultSectionSize(90) self.peopleTable.setColumnCount(10) # self.peopleTable.setColumnHidden(0, True) self.peopleTable.setHorizontalHeaderItem(0, QTableWidgetItem("")) self.peopleTable.horizontalHeader().setSectionResizeMode( 0, QHeaderView.ResizeToContents) self.peopleTable.setHorizontalHeaderItem(1, QTableWidgetItem("Photo")) self.peopleTable.horizontalHeader().setSectionResizeMode( 1, QHeaderView.ResizeToContents) self.peopleTable.setHorizontalHeaderItem(2, QTableWidgetItem("ID")) self.peopleTable.setHorizontalHeaderItem( 3, QTableWidgetItem("First name")) self.peopleTable.horizontalHeader().setSectionResizeMode( 3, QHeaderView.Stretch) self.peopleTable.setHorizontalHeaderItem(4, QTableWidgetItem("Last name")) self.peopleTable.horizontalHeader().setSectionResizeMode( 4, QHeaderView.Stretch) self.peopleTable.setHorizontalHeaderItem(5, QTableWidgetItem("Title")) self.peopleTable.setHorizontalHeaderItem(6, QTableWidgetItem("Phone")) self.peopleTable.horizontalHeader().setSectionResizeMode( 6, QHeaderView.Stretch) self.peopleTable.setHorizontalHeaderItem(7, QTableWidgetItem("Email")) self.peopleTable.horizontalHeader().setSectionResizeMode( 7, QHeaderView.Stretch) self.peopleTable.setHorizontalHeaderItem(8, QTableWidgetItem("Location")) self.peopleTable.setHorizontalHeaderItem( 9, QTableWidgetItem("Employment type")) self.peopleTable.horizontalHeader().setSectionResizeMode( 9, QHeaderView.ResizeToContents) # Double clicking a row opens a window with person details self.peopleTable.doubleClicked.connect(self.selectedPerson) # Buttons for actions on selected people self.addPerson = QPushButton("Add") self.addPerson.clicked.connect(self.funcAddPerson) self.viewPerson = QPushButton("View/Edit") self.viewPerson.clicked.connect(self.selectedPerson) self.deletePerson = QPushButton("Delete") self.deletePerson.clicked.connect(self.funcDeletePerson) self.exportPeopleCSVBtn = QPushButton("Export CSV") self.exportPeopleCSVBtn.setEnabled(False) self.exportPeopleCSVBtn.clicked.connect(self.funcPeopleToCSV) self.exportPeopleXLSXBtn = QPushButton("Export XLSX") self.exportPeopleXLSXBtn.setEnabled(False) self.exportPeopleXLSXBtn.clicked.connect(self.funcPeopleToXLSX) self.exportPeoplePDFBtn = QPushButton("Export PDF") self.exportPeoplePDFBtn.setEnabled(False) self.exportPeoplePDFBtn.clicked.connect(self.funcPeopleToPdf) def layouts(self): # People layouts ########################################################### self.peopleMainLayout = QVBoxLayout() self.peopleMainTopLayout = QHBoxLayout() self.peopleTopLeftLayout = QHBoxLayout() self.peopleTopRightLayout = QHBoxLayout() # self.peopleMainMiddleLayout = QHBoxLayout() self.peopleMainBottomLayout = QHBoxLayout() self.peopleBottomRightLayout = QVBoxLayout() self.peopleBottomLeftLayout = QHBoxLayout() # Groupboxes allows customization using CSS-like syntax # self.peopleTopGroupBox = QGroupBox() # self.peopleTopGroupBoxRightFiller = QGroupBox() # self.peopleMiddleGroupBox = QGroupBox() # self.peopleMiddleGroupBoxRightFiller = QGroupBox() self.peopleTopLeftGroupBox = QGroupBox() self.peopleTopRightGroupBox = QGroupBox() self.peopleTopGroupBox = QGroupBox() self.peopleBottomGroupBox = QGroupBox() self.peopleBottomLeftGroupBox = QGroupBox() self.peopleBottomRightGroupBox = QGroupBox() self.peopleBottomRightGroupBox.setStyleSheet( 'QGroupBox {margin-top: 0px;}') self.peopleBottomRightGroupBoxFiller = QGroupBox() self.peopleBottomRightGroupBoxFiller.setStyleSheet( styles.groupBoxFillerStyle()) # Top layout (search box) widgets self.peopleTopLeftLayout.addWidget(self.searchPeopleText, 10) self.peopleTopLeftLayout.addWidget(self.searchPeopleEntry, 30) self.peopleTopLeftLayout.addWidget(self.searchPeopleBtn, 10) self.peopleTopLeftLayout.addItem( QSpacerItem(70, 40, QSizePolicy.Minimum, QSizePolicy.Expanding)) self.peopleTopLeftLayout.addWidget(self.refreshPeopleBtn, 10) self.peopleTopLeftGroupBox.setLayout(self.peopleTopLeftLayout) # Middle layout (list box) widgets self.peopleTopRightLayout.addWidget(self.allPeopleRadioBtn) self.peopleTopRightLayout.addWidget(self.employeesPeopleRadioBtn) self.peopleTopRightLayout.addWidget(self.contractorsPeopleRadioBtn) self.peopleTopRightLayout.addWidget(self.subcontractorsPeopleRadioBtn) self.peopleTopRightLayout.addWidget(self.listPeopleBtn) self.peopleTopRightGroupBox.setLayout(self.peopleTopRightLayout) self.peopleMainTopLayout.addWidget(self.peopleTopLeftGroupBox, 60) self.peopleMainTopLayout.addWidget(self.peopleTopRightGroupBox, 40) # Bottom layout (table with issues) widgets # Bottom left layout with table self.peopleBottomLeftLayout.addWidget(self.peopleTable) self.peopleBottomLeftGroupBox.setLayout(self.peopleBottomLeftLayout) # Bottom right layout with buttons self.peopleBottomRightLayout.addWidget(self.addPerson, 5) self.peopleBottomRightLayout.addWidget(self.viewPerson, 5) self.peopleBottomRightLayout.addWidget(self.deletePerson, 5) self.peopleBottomRightLayout.addWidget( self.peopleBottomRightGroupBoxFiller, 70) self.peopleBottomRightLayout.addWidget(self.exportPeopleCSVBtn, 5) self.peopleBottomRightLayout.addWidget(self.exportPeopleXLSXBtn, 5) self.peopleBottomRightLayout.addWidget(self.exportPeoplePDFBtn, 5) self.peopleBottomRightGroupBox.setLayout(self.peopleBottomRightLayout) self.peopleMainBottomLayout.addWidget(self.peopleTable, 90) self.peopleMainBottomLayout.addWidget(self.peopleBottomRightGroupBox, 10) # self.peopleMainLayout.addWidget(self.peopleTopGroupBox, 10) # self.peopleMainLayout.addWidget(self.peopleMiddleGroupBox, 10) # self.peopleMainLayout.addLayout(self.peopleMainBottomLayout, 80) self.peopleMainLayout.addLayout(self.peopleMainTopLayout, 10) self.peopleMainLayout.addLayout(self.peopleMainBottomLayout, 90) self.setLayout(self.peopleMainLayout) @Slot() def funcDisplayPeople(self): for i in reversed(range(self.peopleTable.rowCount())): self.peopleTable.removeRow(i) cur = db.cur people = cur.execute("SELECT * FROM people") for row_data in people: row_number = self.peopleTable.rowCount() self.peopleTable.insertRow(row_number) # Add checkboxes to the table widget = QWidget() checkBox = QCheckBox() checkBox.setCheckState(Qt.Unchecked) checkBox.stateChanged.connect(self.funcActivateBtnsWithCheckbox) hBoxLayout = QHBoxLayout(widget) hBoxLayout.addWidget(checkBox) hBoxLayout.setAlignment(Qt.AlignCenter) self.peopleTable.setCellWidget(row_number, 0, widget) self.peopleTable.setItem(row_number, 0, QTableWidgetItem(row_number)) # Add photo photos_thumbnails to the table thumbWidget = QWidget() pic = QPixmap(str(row_data[10])) thumbLabel = QLabel() thumbLabel.setPixmap(pic) thumbLayout = QHBoxLayout(thumbWidget) thumbLayout.addWidget(thumbLabel) self.peopleTable.setCellWidget(row_number, 1, thumbWidget) self.peopleTable.setItem(row_number, 0, QTableWidgetItem(row_number)) # Fill the rest of the data for column_number, data in enumerate(row_data, start=2): if column_number == 2: self.peopleTable.setItem( row_number, column_number, QTableWidgetItem("PRN#" + str(data))) else: self.peopleTable.setItem(row_number, column_number, QTableWidgetItem(str(data))) self.peopleTable.setEditTriggers(QAbstractItemView.NoEditTriggers) self.peopleTable.setSelectionBehavior(QTableView.SelectRows) @Slot() def funcActivateBtnsWithCheckbox(self): indices = self.funcPeopleCheckBox() if self.sender().isChecked() or indices: self.exportPeopleCSVBtn.setEnabled(True) self.exportPeopleXLSXBtn.setEnabled(True) self.exportPeoplePDFBtn.setEnabled(True) else: self.exportPeopleCSVBtn.setEnabled(False) self.exportPeopleXLSXBtn.setEnabled(False) self.exportPeoplePDFBtn.setEnabled(False) @Slot() def funcAddPerson(self): self.newPerson = AddPerson(self) self.newPerson.setObjectName("add_person_popup") self.newPerson.setStyleSheet(styles.addPopups()) @Slot() def funcPeopleCheckBox(self): checked_list = [] for i in range(self.peopleTable.rowCount()): if self.peopleTable.cellWidget(i, 0).findChild(type( QCheckBox())).isChecked(): item = self.peopleTable.item(i, 2).text() checked_list.append(item.lstrip("PRN#")) return checked_list @Slot() def selectedPerson(self): self.displayPerson = DisplayPerson(self) self.displayPerson.show() @Slot() def funcDeletePerson(self): indices = self.funcPeopleCheckBox() mbox = QMessageBox.question( self, "Warning", "Are you sure you want to delete this person?", QMessageBox.Yes | QMessageBox.Cancel, QMessageBox.Cancel) if (mbox == QMessageBox.Yes): if indices: try: for index in range(len(indices)): query = "DELETE FROM people WHERE person_id = ?" db.cur.execute(query, (indices[index], )) db.conn.commit() QMessageBox.information(self, "Info", "Selected people were deleted") self.funcDisplayPeople() except: QMessageBox.information(self, "Info", "No changes made") else: row = self.peopleTable.currentRow() personId = self.peopleTable.item(row, 0).text() personId = personId.lstrip("PRN#") try: query = "DELETE FROM people WHERE person_id = ?" db.cur.execute(query, (personId, )) db.conn.commit() QMessageBox.information(self, "Info", "Person was deleted") self.funcDisplayPeople() except: QMessageBox.information(self, "Info", "No changes made") self.displayPerson.close() @Slot() def funcListPeople(self): if self.allPeopleRadioBtn.isChecked(): self.funcDisplayPeople() elif self.employeesPeopleRadioBtn.isChecked(): try: query = "SELECT * FROM people WHERE person_empl_type = 'Employee'" people = db.cur.execute(query).fetchall() for i in reversed(range(self.peopleTable.rowCount())): self.peopleTable.removeRow(i) for row_data in people: row_number = self.peopleTable.rowCount() self.peopleTable.insertRow(row_number) # Add checkboxes to the table widget = QWidget() checkBox = QCheckBox() checkBox.setCheckState(Qt.Unchecked) hBoxLayout = QHBoxLayout(widget) hBoxLayout.addWidget(checkBox) hBoxLayout.setAlignment(Qt.AlignCenter) self.peopleTable.setCellWidget(row_number, 0, widget) self.peopleTable.setItem(row_number, 0, QTableWidgetItem(row_number)) # Add photo photos_thumbnails to the table thumbWidget = QWidget() pic = QPixmap( "assets/media/people-media/photos_thumbnails/01Aug2020_18h01mtrtgzteuzuspxrp_thumbnail.png" ) thumbLabel = QLabel() thumbLabel.setPixmap(pic) thumbLayout = QHBoxLayout(thumbWidget) thumbLayout.addWidget(thumbLabel) self.peopleTable.setCellWidget(row_number, 1, thumbWidget) self.peopleTable.setItem(row_number, 0, QTableWidgetItem(row_number)) # Fill the rest of the data for column_number, data in enumerate(row_data, start=2): if column_number == 2: self.peopleTable.setItem( row_number, column_number, QTableWidgetItem("PRN#" + str(data))) else: self.peopleTable.setItem( row_number, column_number, QTableWidgetItem(str(data))) except: QMessageBox.information(self, "Info", "Cannot access database") elif self.contractorsPeopleRadioBtn.isChecked(): try: query = "SELECT * FROM people WHERE person_empl_type = 'Contractor'" people = db.cur.execute(query).fetchall() for i in reversed(range(self.peopleTable.rowCount())): self.peopleTable.removeRow(i) for row_data in people: row_number = self.peopleTable.rowCount() self.peopleTable.insertRow(row_number) # Add checkboxes to the table widget = QWidget() checkBox = QCheckBox() checkBox.setCheckState(Qt.Unchecked) hBoxLayout = QHBoxLayout(widget) hBoxLayout.addWidget(checkBox) hBoxLayout.setAlignment(Qt.AlignCenter) self.peopleTable.setCellWidget(row_number, 0, widget) self.peopleTable.setItem(row_number, 0, QTableWidgetItem(row_number)) # Add photo photos_thumbnails to the table thumbWidget = QWidget() pic = QPixmap( "assets/media/people-media/photos_thumbnails/01Aug2020_18h01mtrtgzteuzuspxrp_thumbnail.png" ) thumbLabel = QLabel() thumbLabel.setPixmap(pic) thumbLayout = QHBoxLayout(thumbWidget) thumbLayout.addWidget(thumbLabel) self.peopleTable.setCellWidget(row_number, 1, thumbWidget) self.peopleTable.setItem(row_number, 0, QTableWidgetItem(row_number)) # Fill the rest of the data for column_number, data in enumerate(row_data, start=2): if column_number == 2: self.peopleTable.setItem( row_number, column_number, QTableWidgetItem("PRN#" + str(data))) else: self.peopleTable.setItem( row_number, column_number, QTableWidgetItem(str(data))) except: QMessageBox.information(self, "Info", "Cannot access database") elif self.subcontractorsPeopleRadioBtn.isChecked(): try: query = "SELECT * FROM people WHERE person_empl_type = 'Subcontractor'" people = db.cur.execute(query).fetchall() for i in reversed(range(self.peopleTable.rowCount())): self.peopleTable.removeRow(i) for row_data in people: row_number = self.peopleTable.rowCount() self.peopleTable.insertRow(row_number) # Add checkboxes to the table widget = QWidget() checkBox = QCheckBox() checkBox.setCheckState(Qt.Unchecked) hBoxLayout = QHBoxLayout(widget) hBoxLayout.addWidget(checkBox) hBoxLayout.setAlignment(Qt.AlignCenter) self.peopleTable.setCellWidget(row_number, 0, widget) self.peopleTable.setItem(row_number, 0, QTableWidgetItem(row_number)) # Add photo photos_thumbnails to the table thumbWidget = QWidget() pic = QPixmap( "assets/media/people-media/photos_thumbnails/01Aug2020_18h01mtrtgzteuzuspxrp_thumbnail.png" ) thumbLabel = QLabel() thumbLabel.setPixmap(pic) thumbLayout = QHBoxLayout(thumbWidget) thumbLayout.addWidget(thumbLabel) self.peopleTable.setCellWidget(row_number, 1, thumbWidget) self.peopleTable.setItem(row_number, 0, QTableWidgetItem(row_number)) # Fill the rest of the data for column_number, data in enumerate(row_data, start=2): if column_number == 2: self.peopleTable.setItem( row_number, column_number, QTableWidgetItem("PRN#" + str(data))) else: self.peopleTable.setItem( row_number, column_number, QTableWidgetItem(str(data))) except: QMessageBox.information(self, "Info", "Cannot access database") @Slot() def searchPeople(self): value = self.searchPeopleEntry.text() if value == "": QMessageBox.information(self, "Warning", "Search string cannot be empty") self.funcDisplayPeople() else: # Erase search entry self.searchPeopleEntry.setText("") try: query = "SELECT * FROM people WHERE " \ "person_id LIKE ? " \ "OR person_first_name LIKE ?" \ "OR person_last_name LIKE ?" \ "OR person_title LIKE ?" \ "OR person_phone LIKE ?" \ "OR person_email LIKE ?" \ "OR person_location LIKE ?" \ "OR person_empl_type LIKE ?" results = db.cur.execute(query, ( '%' + value + '%', '%' + value + '%', '%' + value + '%', '%' + value + '%', '%' + value + '%', '%' + value + '%', '%' + value + '%', '%' + value + '%', )).fetchall() if results == []: QMessageBox.information(self, "Info", "Nothing was found") self.displayPeople() else: for i in reversed(range(self.peopleTable.rowCount())): self.peopleTable.removeRow(i) for row_data in results: row_number = self.peopleTable.rowCount() self.peopleTable.insertRow(row_number) # Add checkboxes to the table qwidget = QWidget() checkbox = QCheckBox() checkbox.setCheckState(Qt.Unchecked) qhboxlayout = QHBoxLayout(qwidget) qhboxlayout.addWidget(checkbox) qhboxlayout.setAlignment(Qt.AlignCenter) self.peopleTable.setCellWidget(row_number, 0, qwidget) self.peopleTable.setItem(row_number, 0, QTableWidgetItem(row_number)) # Add photo photos_thumbnails to the table thumbWidget = QWidget() pic = QPixmap( "assets/media/people-media/photos_thumbnails/01Aug2020_18h01mtrtgzteuzuspxrp_thumbnail.png" ) thumbLabel = QLabel() thumbLabel.setPixmap(pic) thumbLayout = QHBoxLayout(thumbWidget) thumbLayout.addWidget(thumbLabel) self.peopleTable.setCellWidget(row_number, 1, thumbWidget) self.peopleTable.setItem(row_number, 0, QTableWidgetItem(row_number)) for column_number, data in enumerate(row_data, start=2): if column_number == 2: self.peopleTable.setItem( row_number, column_number, QTableWidgetItem("PRN#" + str(data))) else: self.peopleTable.setItem( row_number, column_number, QTableWidgetItem(str(data))) except: QMessageBox.information(self, "Info", "Cannot access database") @Slot() def funcPeopleToCSV(self): indices = self.funcPeopleCheckBox() if indices: CSV(self, "people", indices) else: QMessageBox.information( self, "Info", "Nothing selected for export\nUse checkboxes to select issues to export" ) @Slot() def funcPeopleToXLSX(self): indices = self.funcPeopleCheckBox() if indices: try: date = datetime.datetime.now() # Get file location and add timestamp to when it was created to the filename fileName, _ = QFileDialog.getSaveFileName( self, "Save as...", "~/PeopleXLSX" + "{:%d%b%Y_%Hh%Mm}".format(date) + ".xlsx", "Excel files (*.xlsx)") if fileName: db.cur.execute("SELECT * FROM people") workbook = xlsxwriter.Workbook(fileName) worksheet = workbook.add_worksheet("People") worksheet.set_column('A:C', 12) worksheet.set_row(0, 30) merge_format = workbook.add_format({ 'bold': 1, 'align': 'center', 'valign': 'vcenter' }) worksheet.merge_range('A1:B1', '', merge_format) worksheet.insert_image( 'A1', './assets/logo/logo-full-main.png', { 'x_scale': 0.4, 'y_scale': 0.4, 'x_offset': 15, 'y_offset': 10 }) # Create header row stop = 8 col = 0 for i, value in enumerate(db.cur.description[:stop]): worksheet.write(1, col, value[0]) col += 1 # Write date to xlsx file row_number = 2 for index in range(len(indices)): query = "SELECT * FROM people WHERE person_id=?" person_record = db.cur.execute( query, (indices[index], )).fetchone() for i, value in enumerate(person_record[:stop]): if person_record[9]: worksheet.set_row(row_number, 185) worksheet.set_column(8, 8, 35) worksheet.insert_image(row_number, 8, person_record[9], { 'x_scale': 0.3, 'y_scale': 0.3 }) worksheet.write(row_number, i, value) row_number += 1 workbook.close() QMessageBox.information( self, "Info", "Data exported successfully into {}".format(fileName)) except: QMessageBox.information(self, "Info", "Export failed") else: QMessageBox.information( self, "Info", "Nothing selected for export\nUse checkboxes to select issues to export" ) @Slot() def funcPeopleToPdf(self): indices = self.funcPeopleCheckBox() if indices: try: date = datetime.datetime.now() # Get file location and add timestamp to when it was created to the filename fileName, _ = QFileDialog.getSaveFileName( self, "Save as...", "~/PeoplePDF" + "{:%d%b%Y_%Hh%Mm}".format(date) + ".pdf", "PDF files (*.pdf)") if fileName: pdf = PDF() pdf.add_page() pdf.set_font('Arial', 'B', 13) for index in range(len(indices)): query = "SELECT * FROM people WHERE person_id=?" person_record = db.cur.execute( query, (indices[index], )).fetchone() # This string allows for text formatting in the pdf, easy to implement and test stringPerson = "\nPerson id: " + str(person_record[0]) + \ "\nFirst name: " + str(person_record[1]) + \ "\nLast name: " + str(person_record[2]) + \ "\nTitle: " + str(person_record[3]) + \ "\nPhone: " + str(person_record[4]) + \ "\nEmail: " + str(person_record[5]) + \ "\nLocation: " + str(person_record[6]) + \ "\nEmployment type: " + str(person_record[7]) effectivePageWidth = pdf.w - 2 * pdf.l_margin ybefore = pdf.get_y() pdf.multi_cell(effectivePageWidth / 2, 10, stringPerson) if person_record[9]: pdf.set_xy(effectivePageWidth / 2 + pdf.l_margin, ybefore) pdf.image(person_record[9], effectivePageWidth / 2 + 20, 40, w=70) pdf.ln(0.5) if index != (len(indices) - 1): pdf.add_page() # pdf.multi_cell(200, 10, stringPerson) pdf.output(fileName, 'F') QMessageBox.information( self, "Info", "Data exported successfully into {}".format(fileName)) except: QMessageBox.information(self, "Info", "Export failed") else: QMessageBox.information( self, "Info", "Nothing selected for export\nUse checkboxes to select issues to export" )
class HistWidget(ToolWidget): def __init__(self, image, parent=None): super(ToolWidget, self).__init__(parent) self.rgb_radio = QRadioButton(self.tr('RGB')) self.rgb_radio.setChecked(True) self.last_radio = self.rgb_radio self.red_radio = QRadioButton(self.tr('Red')) self.green_radio = QRadioButton(self.tr('Green')) self.blue_radio = QRadioButton(self.tr('Blue')) self.value_radio = QRadioButton(self.tr('Value')) self.log_check = QCheckBox(self.tr('Log scale')) self.grid_check = QCheckBox(self.tr('Show grid')) self.marker_check = QCheckBox(self.tr('Show markers')) self.marker_check.setToolTip( self.tr('Show plot markers for min(--), avg(-), max(-.)')) self.start_slider = ParamSlider([0, 255], 8, 0, label='Start:', bold=True) self.end_slider = ParamSlider([0, 255], 8, 255, label='End:', bold=True) channels = cv.split(cv.cvtColor(image, cv.COLOR_BGR2RGB)) channels.append(cv.cvtColor(image, cv.COLOR_BGR2GRAY)) self.hist = [compute_hist(c) for c in channels] rows, cols, chans = image.shape pixels = rows * cols unique = np.unique(np.reshape(image, (pixels, chans)), axis=0).shape[0] unique_ratio = unique / pixels * 100 unique_label = QLabel( self.tr('total pixels = {}, unique colors = {} ({:.2f}%) '.format( pixels, unique, unique_ratio))) modify_font(unique_label, italic=True) self.rgb_radio.clicked.connect(self.redraw) self.red_radio.clicked.connect(self.redraw) self.green_radio.clicked.connect(self.redraw) self.blue_radio.clicked.connect(self.redraw) self.value_radio.clicked.connect(self.redraw) self.log_check.stateChanged.connect(self.redraw) self.grid_check.stateChanged.connect(self.redraw) self.marker_check.stateChanged.connect(self.redraw) self.start_slider.valueChanged.connect(self.redraw) self.end_slider.valueChanged.connect(self.redraw) self.table_widget = QTableWidget(8, 2) self.table_widget.setHorizontalHeaderLabels( [self.tr('Property'), self.tr('Value')]) self.table_widget.setItem(0, 0, QTableWidgetItem(self.tr('Least frequent'))) self.table_widget.setItem(1, 0, QTableWidgetItem(self.tr('Most frequent'))) self.table_widget.setItem(2, 0, QTableWidgetItem(self.tr('Average level'))) self.table_widget.setItem(3, 0, QTableWidgetItem(self.tr('Median level'))) self.table_widget.setItem(4, 0, QTableWidgetItem(self.tr('Deviation'))) self.table_widget.setItem(5, 0, QTableWidgetItem(self.tr('Pixel count'))) self.table_widget.setItem(6, 0, QTableWidgetItem(self.tr('Percentile'))) self.table_widget.setItem(7, 0, QTableWidgetItem(self.tr('Smoothness'))) for i in range(self.table_widget.rowCount()): modify_font(self.table_widget.item(i, 0), bold=True) self.table_widget.setSelectionMode(QAbstractItemView.SingleSelection) self.table_widget.setEditTriggers(QAbstractItemView.NoEditTriggers) self.table_widget.resizeColumnsToContents() self.table_widget.setAlternatingRowColors(True) self.table_widget.setMaximumWidth(200) figure = Figure() plot_canvas = FigureCanvas(figure) # plot_canvas.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) self.axes = plot_canvas.figure.subplots() self.redraw() figure.set_tight_layout(True) right_layout = QVBoxLayout() table_label = QLabel(self.tr('Range properties')) modify_font(table_label, bold=True) table_label.setAlignment(Qt.AlignCenter) right_layout.addWidget(table_label) right_layout.addWidget(self.table_widget) right_layout.addWidget(self.marker_check) right_layout.addWidget(self.start_slider) right_layout.addWidget(self.end_slider) center_layout = QHBoxLayout() center_layout.addWidget(plot_canvas) center_layout.addLayout(right_layout) bottom_layout = QHBoxLayout() bottom_layout.addWidget(self.rgb_radio) bottom_layout.addWidget(self.red_radio) bottom_layout.addWidget(self.green_radio) bottom_layout.addWidget(self.blue_radio) bottom_layout.addWidget(self.value_radio) bottom_layout.addWidget(self.log_check) bottom_layout.addWidget(self.grid_check) bottom_layout.addStretch() bottom_layout.addWidget(unique_label) main_layout = QVBoxLayout() main_layout.addLayout(center_layout) main_layout.addLayout(bottom_layout) self.setLayout(main_layout) def redraw(self): x = np.arange(256) alpha = 0.25 rgb = self.rgb_radio.isChecked() red = self.red_radio.isChecked() green = self.green_radio.isChecked() blue = self.blue_radio.isChecked() value = self.value_radio.isChecked() grid = self.grid_check.isChecked() log = self.log_check.isChecked() try: self.axes.clear() except RecursionError: return y = None if value: y = self.hist[3] self.axes.step(x, y, 'k') self.axes.fill_between(x, y, alpha=alpha, facecolor='k', step='pre') else: # TODO: Ottimizzare facendo un ciclo senza ripetere le istruzioni if red or rgb: y = self.hist[0] self.axes.step(x, y, 'r') self.axes.fill_between(x, y, alpha=alpha, facecolor='r', step='pre') if green or rgb: y = self.hist[1] self.axes.step(x, y, 'g') self.axes.fill_between(x, y, alpha=alpha, facecolor='g', step='pre') if blue or rgb: y = self.hist[2] self.axes.step(x, y, 'b') self.axes.fill_between(x, y, alpha=alpha, facecolor='b', step='pre') if log: self.axes.set_yscale('log') self.axes.set_ylim(bottom=1) else: self.axes.set_yscale('linear') self.axes.set_ylim(bottom=0) self.axes.set_xlim([-1, 256]) self.axes.set_xlabel(self.tr('intensity value')) self.axes.set_ylabel(self.tr('pixel count')) self.axes.set_xticks([0, 64, 128, 192, 255]) self.axes.grid(grid, which='both') if rgb: self.table_widget.setEnabled(False) self.marker_check.setEnabled(False) self.start_slider.setEnabled(False) self.end_slider.setEnabled(False) for i in range(self.table_widget.rowCount()): if self.table_widget.item(i, 1) is not None: self.table_widget.item(i, 1).setText('') self.table_widget.item(i, 1).setBackgroundColor( QColor('white')) else: self.table_widget.setEnabled(True) self.marker_check.setEnabled(True) self.start_slider.setEnabled(True) self.end_slider.setEnabled(True) start = self.start_slider.value() end = self.end_slider.value() if end <= start: end = start + 1 elif start >= end: start = end - 1 total = np.sum(y) x = x[start:end + 1] y = y[start:end + 1] count = np.sum(y) if count != 0: argmin = np.argmin(y) + start argmax = np.argmax(y) + start mean = np.round(np.sum(x * y) / count, 2) stddev = np.round(np.sqrt(np.sum(((x - mean)**2) * y) / count), 2) median = np.argmax(np.cumsum(y) > count / 2) + start percent = np.round(count / total * 100, 2) y = y / np.max(y) sweep = len(y) smooth = 0 if sweep > 2: for i in range(1, sweep - 1): h0 = y[i - 1] h1 = y[i] h2 = y[i + 1] smooth += abs((h0 + h2) / 2 - h1) smooth = np.round((1 - (smooth / (sweep - 2))) * 100, 2) if self.marker_check.isChecked(): self.axes.axvline(argmin, linestyle='--', color='m') self.axes.axvline(mean, linestyle='-', color='m') self.axes.axvline(argmax, linestyle='-.', color='m') else: argmin = argmax = mean = stddev = median = percent = smooth = 0 self.table_widget.setItem(0, 1, QTableWidgetItem(str(argmin))) self.table_widget.setItem(1, 1, QTableWidgetItem(str(argmax))) self.table_widget.setItem(2, 1, QTableWidgetItem(str(mean))) self.table_widget.setItem(3, 1, QTableWidgetItem(str(median))) self.table_widget.setItem(4, 1, QTableWidgetItem(str(stddev))) self.table_widget.setItem(5, 1, QTableWidgetItem(str(count))) self.table_widget.setItem(6, 1, QTableWidgetItem(str(percent) + '%')) self.table_widget.setItem(7, 1, QTableWidgetItem(str(smooth) + '%')) if smooth <= 80: self.table_widget.item(7, 1).setBackgroundColor( QColor.fromHsv(0, 96, 255)) elif smooth <= 90: self.table_widget.item(7, 1).setBackgroundColor( QColor.fromHsv(30, 96, 255)) elif smooth <= 95: self.table_widget.item(7, 1).setBackgroundColor( QColor.fromHsv(60, 96, 255)) else: self.table_widget.item(7, 1).setBackgroundColor( QColor.fromHsv(90, 96, 255)) self.table_widget.resizeColumnsToContents() if start != 0 or end != 255: self.axes.axvline(start, linestyle=':', color='k') self.axes.axvline(end, linestyle=':', color='k') _, top = self.axes.get_ylim() self.axes.fill_between(np.arange(start, end + 1), top, facecolor='y', alpha=alpha * 2) self.axes.figure.canvas.draw()
class MagnifierWidget(ToolWidget): def __init__(self, image, parent=None): super(MagnifierWidget, self).__init__(parent) self.equalize_radio = QRadioButton(self.tr("Equalization")) self.equalize_radio.setToolTip(self.tr("RGB histogram equalization")) self.contrast_radio = QRadioButton(self.tr("Auto Contrast")) self.contrast_radio.setToolTip(self.tr("Compress luminance tonality")) self.centile_spin = QSpinBox() self.centile_spin.setRange(0, 100) self.centile_spin.setValue(20) self.centile_spin.setSuffix(self.tr(" %")) self.centile_spin.setToolTip(self.tr("Histogram percentile amount")) self.channel_check = QCheckBox(self.tr("By channel")) self.channel_check.setToolTip(self.tr("Independent RGB compression")) self.equalize_radio.setChecked(True) self.last_radio = self.equalize_radio self.image = image self.viewer = ImageViewer(self.image, self.image) self.change() self.viewer.viewChanged.connect(self.process) self.equalize_radio.clicked.connect(self.change) self.contrast_radio.clicked.connect(self.change) self.centile_spin.valueChanged.connect(self.change) self.channel_check.stateChanged.connect(self.change) top_layout = QHBoxLayout() top_layout.addWidget(QLabel(self.tr("Mode:"))) top_layout.addWidget(self.equalize_radio) top_layout.addWidget(self.contrast_radio) top_layout.addWidget(self.centile_spin) top_layout.addWidget(self.channel_check) top_layout.addStretch() main_layout = QVBoxLayout() main_layout.addLayout(top_layout) main_layout.addWidget(self.viewer) self.setLayout(main_layout) def process(self, rect): y1 = rect.top() y2 = rect.bottom() x1 = rect.left() x2 = rect.right() roi = self.image[y1:y2, x1:x2] if self.equalize_radio.isChecked(): self.centile_spin.setEnabled(False) self.channel_check.setEnabled(False) roi = equalize_img(roi) self.last_radio = self.equalize_radio elif self.contrast_radio.isChecked(): self.centile_spin.setEnabled(True) self.channel_check.setEnabled(True) centile = self.centile_spin.value() / 200 if self.channel_check.isChecked(): roi = cv.merge( [cv.LUT(c, auto_lut(c, centile)) for c in cv.split(roi)]) else: roi = cv.LUT( roi, auto_lut(cv.cvtColor(roi, cv.COLOR_BGR2GRAY), centile)) self.last_radio = self.contrast_radio else: self.last_radio.setChecked(True) return processed = np.copy(self.image) processed[y1:y2, x1:x2] = roi self.viewer.update_processed(processed) def change(self): self.process(self.viewer.get_rect())
class Widget(QWidget): movie_url_label_text = "粘贴有 dailymotion 版的連續劇网址 (例子: https://dramaq.de/cn191023b/): " def __init__(self): QWidget.__init__(self) self.q = None self.pool = None self.top = QHBoxLayout() self.top.setMargin(10) self.middle = QVBoxLayout() self.middle.setMargin(10) self.radioButtonDailyMotionDrama = QRadioButton( "有 Dailymotion Drama 的網站") self.radioButtonAny = QRadioButton("其它類型網站 (例如 YouTube)") self.top.addWidget(self.radioButtonDailyMotionDrama) self.top.addWidget(self.radioButtonAny) self.url_label = QLabel() self.url = QLineEdit() self.url_label.setBuddy(self.url) self.middle.addWidget(self.url_label) self.middle.addWidget(self.url) self.browse_folder_label = QLabel("下載到:") self.browseFolder = QPushButton("選擇目錄") self.browse_folder_label.setBuddy(self.browseFolder) self.middle.addWidget(self.browse_folder_label) self.middle.addWidget(self.browseFolder) self.browse_folder_value = "" self.bk_cinemae_spin_from = 1 self.bk_cinemae_spin_to = 1 self.fromEpSpinBox = QSpinBox() self.fromEpSpinBox.setMinimum(1) self.fromEpSpinBox.setMaximum(2147483647) self.fromEpLabel = QLabel("&從第幾集開始下載:") self.fromEpLabel.setBuddy(self.fromEpSpinBox) self.toEpSpinBox = QSpinBox() self.toEpSpinBox.setMinimum(1) self.toEpSpinBox.setMaximum(2147483647) self.toEpLabel = QLabel("&到第幾集停止下載:") self.toEpLabel.setBuddy(self.toEpSpinBox) self.cinema_ly = QHBoxLayout() #self.cinema_ly.setMargin(10) self.cinema_ly.addWidget(self.fromEpLabel) self.cinema_ly.addWidget(self.fromEpSpinBox) self.cinema_ly.addWidget(self.toEpLabel) self.cinema_ly.addWidget(self.toEpSpinBox) self.middle.addLayout(self.cinema_ly) self.add = QPushButton("開始下載") self.add.setEnabled(False) self.middle.addWidget(self.add) self.stop_me = QPushButton("停止下載") self.stop_me.setEnabled(False) self.middle.addWidget(self.stop_me) self.log_area = QPlainTextEdit() self.log_area.setReadOnly(True) self.log_area.setMaximumBlockCount(1000) self.middle.addWidget(self.log_area) #self.table_view.setSizePolicy(size) #self.layout.addWidget(self.table) self.layout = QVBoxLayout() self.layout.addLayout(self.top) self.layout.addLayout(self.middle) self.setLayout(self.layout) self.radioButtonDailyMotionDrama.toggled.connect( self.choose_DailyMotionDrama_widgets) self.radioButtonAny.toggled.connect(self.choose_Any_widgets) self.url.textChanged[str].connect(self.check_disable_download) self.browseFolder.clicked.connect(self.add_folder) self.add.clicked.connect(self.start_download) self.stop_me.clicked.connect(self.stop_download) self.radioButtonDailyMotionDrama.setChecked( True) #set default only after .connect above # TESTING PURPOSE ''' self.url.setText('https://journalflash.com/cn191023b/') self.browse_folder_value = 'C:/Users/Administrator/Documents/duboku' ''' #set current process (not queue that one) log handler: logger = logging.getLogger(__name__) handler2 = LoggerWriter() logger.addHandler(handler2) logger.setLevel(logging.INFO) #DEBUG handler2.emitter.sigLog.connect(self.log_area.appendPlainText) sys.stdout = handler2 #LoggerWriter() #sys.stderr = handler2 #Seems no difference #handler2.emitter.sigLog.emit('hihi') @Slot() def choose_DailyMotionDrama_widgets(self): if self.radioButtonDailyMotionDrama.isChecked(): self.fromEpLabel.setEnabled(True) self.toEpLabel.setEnabled(True) self.fromEpSpinBox.setEnabled(True) self.toEpSpinBox.setEnabled(True) self.fromEpSpinBox.setValue(self.bk_cinemae_spin_from) self.toEpSpinBox.setValue(self.bk_cinemae_spin_to) self.fromEpLabel.setDisabled(True) self.toEpLabel.setDisabled(True) @Slot() def choose_Any_widgets(self): if self.radioButtonAny.isChecked(): self.fromEpSpinBox.setDisabled(True) self.toEpSpinBox.setDisabled(True) self.bk_cinemae_spin_from = self.fromEpSpinBox.value() self.bk_cinemae_spin_to = self.toEpSpinBox.value() self.fromEpSpinBox.setValue(1) self.toEpSpinBox.setValue(1) @Slot() def add_folder(self, s): #fname = QFileDialog.getOpenFileName(self, 'Open file', "c:\'", "Image files (*.jpg *.gif)") #fname = QFileDialog.getOpenFileName(self, 'Open file', '', QFileDialog.ShowDirsOnly) fname = QFileDialog.getExistingDirectory(self, '選擇下載至什麼目錄', '', QFileDialog.ShowDirsOnly) #print('repr: ' + repr(fname)) if fname and fname.strip(): fname = fname.strip() self.browse_folder_value = fname #if getOpenFileName, will return ('/home/xiaobai/Pictures/disco.jpg', 'Image files (*.jpg *.gif)') #, while if getExistingDirectory, will return single path string only self.browseFolder.setText(fname) self.check_disable_download(fname) #else: # print('User cancel') @Slot() def check_disable_download(self, s): if self.url.text() and self.browse_folder_value: self.add.setEnabled(True) else: self.add.setEnabled(False) def task_done(self, retVal): self.add.setEnabled(True) self.stop_me.setEnabled(False) @Slot() def stop_download(self): if self.q: self.q.close() if self.pool: self.pool.terminate() self.add.setEnabled(True) self.stop_me.setEnabled(False) print('下載停止。') @Slot() def start_download(self): if self.fromEpSpinBox.value() > self.toEpSpinBox.value(): self.log_area.setPlainText('[!] 從第幾集必須小於或等於到第幾集。') return #No need worry click twice too fast, it seems already handle by PySide2 self.add.setEnabled(False) self.stop_me.setEnabled(True) self.log_area.clear() dest_full_path = self.browse_folder_value ''' print('dest_full_path: ' + repr(dest_full_path)) print('self.url.text(): ' + repr(self.url.text())) print('self.fromEpSpinBox.value(): ' + repr(self.fromEpSpinBox.value())) print('self.toEpSpinBox.value(): ' + repr(self.toEpSpinBox.value())) ''' import drama_dailymotion_console #Windows can't set like that bcoz not update for args.url, must put explicitly #drama_dailymotion_console.redirect_stdout_to_custom_stdout(arg_url, ...etc, LoggerWriter()) #failed other process handler = LogHandlerOtherProcess() handler.emitter.sigLog.connect(self.log_area.appendPlainText) ''' #ref current process: logger = logging.getLogger(__name__) handler2 = LoggerWriter() logger.addHandler(handler2) logger.setLevel(logging.DEBUG) handler2.emitter.sigLog.connect(self.log_area.appendPlainText) sys.stdout = handler2 #LoggerWriter() #handler2.emitter.sigLog.emit('hihi') ''' #handler = LoggerWriter() #handler.emitter.sigLog.connect(self.log_area.appendPlainText) self.q = multiprocessing.Queue() self.ql = QueueListener(self.q, handler) self.ql.start() self.pool = multiprocessing.Pool(1, worker_init, [self.q]) if self.radioButtonDailyMotionDrama.isChecked(): self.pool.apply_async(drama_dailymotion_console.main, args=(dest_full_path, self.fromEpSpinBox.value(), self.toEpSpinBox.value(), self.url.text(), LoggerWriterOtherProcess(), False), callback=self.task_done) else: self.pool.apply_async(drama_dailymotion_console.main, args=(dest_full_path, self.fromEpSpinBox.value(), self.toEpSpinBox.value(), self.url.text(), LoggerWriterOtherProcess(), True), callback=self.task_done)
class StereoWidget(ToolWidget): def __init__(self, image, parent=None): super(StereoWidget, self).__init__(parent) gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY) small = cv.resize(gray, None, None, 1, 0.5) start = 10 end = small.shape[1] // 3 diff = np.fromiter([ cv.mean(cv.absdiff(small[:, i:], small[:, :-i]))[0] for i in range(start, end) ], np.float32) _, maximum, _, argmax = cv.minMaxLoc(np.ediff1d(diff)) if maximum < 2: error_label = QLabel(self.tr("Unable to detect stereogram!")) modify_font(error_label, bold=True) error_label.setStyleSheet("color: #FF0000") error_label.setAlignment(Qt.AlignCenter) main_layout = QVBoxLayout() main_layout.addWidget(error_label) self.setLayout(main_layout) return offset = argmax[1] + start a = image[:, offset:] b = image[:, :-offset] self.pattern = norm_img(cv.absdiff(a, b)) temp = cv.cvtColor(self.pattern, cv.COLOR_BGR2GRAY) thr, _ = cv.threshold(temp, 0, 255, cv.THRESH_TRIANGLE) self.silhouette = cv.medianBlur( gray_to_bgr(cv.threshold(temp, thr, 255, cv.THRESH_BINARY)[1]), 3) a = cv.cvtColor(a, cv.COLOR_BGR2GRAY) b = cv.cvtColor(b, cv.COLOR_BGR2GRAY) flow = cv.calcOpticalFlowFarneback(a, b, None, 0.5, 5, 15, 5, 5, 1.2, cv.OPTFLOW_FARNEBACK_GAUSSIAN)[:, :, 0] self.depth = gray_to_bgr(norm_mat(flow)) flow = np.repeat(cv.normalize(flow, None, 0, 1, cv.NORM_MINMAX)[:, :, np.newaxis], 3, axis=2) self.shaded = cv.normalize( self.pattern.astype(np.float32) * flow, None, 0, 255, cv.NORM_MINMAX).astype(np.uint8) self.viewer = ImageViewer(self.pattern, None, export=True) self.pattern_radio = QRadioButton(self.tr("Pattern")) self.pattern_radio.setChecked(True) self.pattern_radio.setToolTip( self.tr("Difference between raw and aligned image")) self.silhouette_radio = QRadioButton(self.tr("Silhouette")) self.silhouette_radio.setToolTip( self.tr("Apply threshold to discovered pattern")) self.depth_radio = QRadioButton(self.tr("Depth")) self.depth_radio.setToolTip( self.tr("Estimate 3D depth using optical flow")) self.shaded_radio = QRadioButton(self.tr("Shaded")) self.shaded_radio.setToolTip( self.tr("Combine pattern and depth information")) self.silhouette_radio.clicked.connect(self.process) self.pattern_radio.clicked.connect(self.process) self.depth_radio.clicked.connect(self.process) self.shaded_radio.clicked.connect(self.process) top_layout = QHBoxLayout() top_layout.addWidget(QLabel(self.tr("Mode:"))) top_layout.addWidget(self.pattern_radio) top_layout.addWidget(self.silhouette_radio) top_layout.addWidget(self.depth_radio) top_layout.addWidget(self.shaded_radio) top_layout.addStretch() main_layout = QVBoxLayout() main_layout.addLayout(top_layout) main_layout.addWidget(self.viewer) self.setLayout(main_layout) def process(self): if self.pattern_radio.isChecked(): output = self.pattern elif self.silhouette_radio.isChecked(): output = self.silhouette elif self.depth_radio.isChecked(): output = self.depth elif self.shaded_radio.isChecked(): output = self.shaded else: return self.viewer.update_original(output)
class FrequencyWidget(ToolWidget): def __init__(self, image, parent=None): super(FrequencyWidget, self).__init__(parent) self.ampl_radio = QRadioButton(self.tr('Amplitude')) self.ampl_radio.setChecked(True) self.phase_radio = QRadioButton(self.tr('Phase')) self.dct_radio = QRadioButton(self.tr('DCT Map')) self.last_radio = self.ampl_radio self.thr_spin = QSpinBox() self.thr_spin.setRange(0, 255) self.thr_spin.setSpecialValueText(self.tr('Off')) self.ratio_label = QLabel() self.filter_check = QCheckBox(self.tr('Filter')) self.ampl_radio.clicked.connect(self.process) self.phase_radio.clicked.connect(self.process) self.dct_radio.clicked.connect(self.process) self.thr_spin.valueChanged.connect(self.process) self.filter_check.stateChanged.connect(self.process) gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY) rows, cols = gray.shape height = cv.getOptimalDFTSize(rows) width = cv.getOptimalDFTSize(cols) padded = cv.copyMakeBorder(gray, 0, height - rows, 0, width - cols, cv.BORDER_CONSTANT).astype(np.float32) planes = cv.merge([padded, np.zeros_like(padded)]) dft = cv.split(np.fft.fftshift(cv.dft(planes))) mag, phase = cv.cartToPolar(dft[0], dft[1]) dct = cv.dct(padded) self.result = [ normalize_mat(img) for img in [cv.log(mag), phase, cv.log(dct)] ] self.image = image self.viewer = ImageViewer(self.image, None) self.process() top_layout = QHBoxLayout() top_layout.addWidget(QLabel(self.tr('Coefficients:'))) top_layout.addWidget(self.ampl_radio) top_layout.addWidget(self.phase_radio) top_layout.addWidget(self.dct_radio) top_layout.addWidget(self.filter_check) top_layout.addStretch() top_layout.addWidget(QLabel(self.tr('Threshold:'))) top_layout.addWidget(self.thr_spin) top_layout.addWidget(self.ratio_label) main_layout = QVBoxLayout() main_layout.addLayout(top_layout) main_layout.addWidget(self.viewer) self.setLayout(main_layout) def process(self): if self.ampl_radio.isChecked(): output = self.result[0] self.last_radio = self.ampl_radio elif self.phase_radio.isChecked(): output = self.result[1] self.last_radio = self.phase_radio elif self.dct_radio.isChecked(): output = self.result[2] self.last_radio = self.dct_radio else: self.last_radio.setChecked(True) return if self.filter_check.isChecked(): output = cv.medianBlur(output, 3) thr = self.thr_spin.value() if thr > 0: _, output = cv.threshold(output, thr, 0, cv.THRESH_TOZERO) zeros = (1.0 - cv.countNonZero(output) / output.size) * 100 else: zeros = 0 self.ratio_label.setText('(masked = {:.1f}%)'.format(zeros)) self.viewer.update_original(cv.cvtColor(output, cv.COLOR_GRAY2BGR))
class PcaWidget(ToolWidget): def __init__(self, image, parent=None): super(PcaWidget, self).__init__(parent) self.comp_combo = QComboBox() self.comp_combo.addItems([self.tr('#{}'.format(i + 1)) for i in range(3)]) self.distvect_radio = QRadioButton(self.tr('Vector Distance')) self.cross_radio = QRadioButton(self.tr('Cross Correlation')) self.distvect_radio.setChecked(True) self.last_radio = self.distvect_radio self.image = image self.components = [] rows, cols, dims = self.image.shape bgr = np.reshape(self.image, (rows * cols, dims)).astype(np.float32) m, eigen_vec, eigen_val = cv.PCACompute2(bgr, np.array([])) p = self.image.astype(np.float32) - m for v in eigen_vec: c = np.cross(p, v) d = np.linalg.norm(c, axis=2) / np.linalg.norm(v) distance = normalize_mat(d, to_bgr=True) cross = cv.merge([normalize_mat(x) for x in cv.split(c)]) self.components.extend([distance, cross]) table_data = [[m[0, 2], m[0, 1], m[0, 0]], [eigen_vec[0, 2], eigen_vec[0, 1], eigen_vec[0, 0]], [eigen_vec[1, 2], eigen_vec[1, 1], eigen_vec[1, 0]], [eigen_vec[2, 2], eigen_vec[2, 1], eigen_vec[2, 0]], [eigen_val[2, 0], eigen_val[1, 0], eigen_val[0, 0]]] table_widget = QTableWidget(5, 4) table_widget.setHorizontalHeaderLabels([ self.tr('Element'), self.tr('Red'), self.tr('Green'), self.tr('Blue')]) table_widget.setItem(0, 0, QTableWidgetItem(self.tr('Mean color'))) table_widget.setItem(1, 0, QTableWidgetItem(self.tr('Eigen vect 1'))) table_widget.setItem(2, 0, QTableWidgetItem(self.tr('Eigen vect 2'))) table_widget.setItem(3, 0, QTableWidgetItem(self.tr('Eigen vect 3'))) table_widget.setItem(4, 0, QTableWidgetItem(self.tr('Eigen values'))) for i in range(len(table_data)): modify_font(table_widget.item(i, 0), bold=True) for j in range(len(table_data[i])): table_widget.setItem(i, j + 1, QTableWidgetItem(str(table_data[i][j]))) # item = QTableWidgetItem() # item.setBackgroundColor(QColor(m[0, 2], m[0, 1], m[0, 0])) # table_widget.setItem(0, 4, item) # table_widget.resizeRowsToContents() # table_widget.resizeColumnsToContents() table_widget.setEditTriggers(QAbstractItemView.NoEditTriggers) table_widget.setSelectionMode(QAbstractItemView.SingleSelection) table_widget.setMaximumHeight(190) self.viewer = ImageViewer(self.image, self.image, None) self.process() self.comp_combo.currentIndexChanged.connect(self.process) self.distvect_radio.clicked.connect(self.process) self.cross_radio.clicked.connect(self.process) top_layout = QHBoxLayout() top_layout.addWidget(QLabel(self.tr('Component:'))) top_layout.addWidget(self.comp_combo) top_layout.addWidget(QLabel(self.tr('Projection:'))) top_layout.addWidget(self.distvect_radio) top_layout.addWidget(self.cross_radio) top_layout.addStretch() bottom_layout = QHBoxLayout() bottom_layout.addWidget(table_widget) main_layout = QVBoxLayout() main_layout.addLayout(top_layout) main_layout.addWidget(self.viewer) main_layout.addLayout(bottom_layout) self.setLayout(main_layout) def process(self): index = 2*self.comp_combo.currentIndex() if self.distvect_radio.isChecked(): self.viewer.update_processed(self.components[index]) self.last_radio = self.distvect_radio elif self.cross_radio.isChecked(): self.viewer.update_processed(self.components[index + 1]) self.last_radio = self.cross_radio else: self.last_radio.setChecked(True)
class StatsWidget(ToolWidget): def __init__(self, image, parent=None): super(StatsWidget, self).__init__(parent) self.min_radio = QRadioButton(self.tr('Minimum')) self.min_radio.setToolTip(self.tr('RGB channel with smallest value')) self.min_radio.setChecked(True) self.avg_radio = QRadioButton(self.tr('Average')) self.avg_radio.setToolTip(self.tr('RGB channel with average value')) self.max_radio = QRadioButton(self.tr('Maximum')) self.max_radio.setToolTip(self.tr('RGB channel with largest value')) self.incl_check = QCheckBox(self.tr('Inclusive')) self.incl_check.setToolTip(self.tr('Use not strict inequalities')) self.image = image b, g, r = cv.split(self.image) blue = np.array([255, 0, 0]) green = np.array([0, 255, 0]) red = np.array([0, 0, 255]) self.minimum = [[], []] self.minimum[0] = np.zeros_like(self.image) self.minimum[0][np.logical_and(b < g, b < r)] = blue self.minimum[0][np.logical_and(g < r, g < b)] = green self.minimum[0][np.logical_and(r < b, r < g)] = red self.minimum[1] = np.zeros_like(self.image) self.minimum[1][np.logical_and(b <= g, b <= r)] = blue self.minimum[1][np.logical_and(g <= r, g <= b)] = green self.minimum[1][np.logical_and(r <= b, r <= g)] = red self.maximum = [[], []] self.maximum[0] = np.zeros_like(self.image) self.maximum[0][np.logical_and(b > g, b > r)] = blue self.maximum[0][np.logical_and(g > r, g > b)] = green self.maximum[0][np.logical_and(r > b, r > g)] = red self.maximum[1] = np.zeros_like(self.image) self.maximum[1][np.logical_and(b >= g, b >= r)] = blue self.maximum[1][np.logical_and(g >= r, g >= b)] = green self.maximum[1][np.logical_and(r >= b, r >= g)] = red self.average = [[], []] self.average[0] = np.zeros_like(self.image) self.average[0][np.logical_or(np.logical_and(r < b, b < g), np.logical_and(g < b, b < r))] = blue self.average[0][np.logical_or(np.logical_and(r < g, g < b), np.logical_and(b < g, g < r))] = green self.average[0][np.logical_or(np.logical_and(b < r, r < g), np.logical_and(g < r, r < b))] = red self.average[1] = np.zeros_like(self.image) self.average[1][np.logical_or(np.logical_and(r <= b, b <= g), np.logical_and(g <= b, b <= r))] = blue self.average[1][np.logical_or(np.logical_and(r <= g, g <= b), np.logical_and(b <= g, g <= r))] = green self.average[1][np.logical_or(np.logical_and(b <= r, r <= g), np.logical_and(g <= r, r <= b))] = red self.viewer = ImageViewer(self.image, self.image) self.process() self.min_radio.clicked.connect(self.process) self.avg_radio.clicked.connect(self.process) self.max_radio.clicked.connect(self.process) self.incl_check.stateChanged.connect(self.process) params_layout = QHBoxLayout() params_layout.addWidget(QLabel(self.tr('Mode:'))) params_layout.addWidget(self.min_radio) params_layout.addWidget(self.avg_radio) params_layout.addWidget(self.max_radio) params_layout.addWidget(self.incl_check) params_layout.addStretch() main_layout = QVBoxLayout() main_layout.addLayout(params_layout) main_layout.addWidget(self.viewer) self.setLayout(main_layout) def process(self): inclusive = self.incl_check.isChecked() if self.min_radio.isChecked(): result = self.minimum[1 if inclusive else 0] elif self.max_radio.isChecked(): result = self.maximum[1 if inclusive else 0] elif self.avg_radio.isChecked(): result = self.average[1 if inclusive else 0] else: return self.viewer.update_processed(result)
class InputsLayout(QFormLayout): # this signal is connected to print_output from output_layout class. Connection is done in center_layout ga_result = Signal( str ) # a signal that is emitted so it can transfer resulting string to the output_layout class def __init__(self): super(InputsLayout, self).__init__() self.big_font = QFont() self.medium_font = QFont() self.header = QLabel() self.header_general = QLabel() self.header_fitness_remapping = QLabel() self.header_stop = QLabel() self.header_selection = QLabel() self.header_pairing = QLabel() self.header_crossover = QLabel() self.header_mutation = QLabel() self.inp_functions_combo = QComboBox() self.inp_num_variables = QSpinBox() self.inp_extrema_min = QRadioButton("Minimum") self.inp_extrema_max = QRadioButton("Maximum") self.inp_pop_size = QSpinBox() self.inp_lower_bound = QDoubleSpinBox() self.inp_upper_bound = QDoubleSpinBox() # Stopping self.inp_max_iter = QSpinBox() self.inp_similarity_cb = QCheckBox() self.inp_similarity = QSpinBox() self.inp_best_result_cb = QCheckBox() self.inp_best_result = QDoubleSpinBox() self.inp_average_result_cb = QCheckBox() self.inp_average_result = QDoubleSpinBox() # Fitness remapping self.inp_fitness_remapping = QComboBox() # Selection self.inp_selection_method = QComboBox() self.inp_elitism = QDoubleSpinBox() # Pairing self.inp_pairing_method = QComboBox() # Crossover self.inp_crossover_method = QComboBox() self.inp_crossover_fraction = QDoubleSpinBox() self.intermediate_offset = QDoubleSpinBox() # Mutation self.inp_mutation_method = QComboBox() self.inp_mutation_intensity = QDoubleSpinBox() self.inp_mutation_intensity_final = QDoubleSpinBox() self.init_fonts() self.init_header() self.init_row_functions() self.init_row_general() self.init_row_fitness_remapping() self.init_row_stop() self.init_row_selection() self.init_row_pairing() self.init_row_crossover() self.init_row_mutation() def init_fonts(self): self.big_font.setPointSizeF(14) self.medium_font.setPointSizeF(12) def init_header(self): self.header.setFont(self.big_font) self.header.setAlignment(Qt.AlignCenter) self.header.setText("Genetic Algorithm Continuous Optimization") self.addRow(self.header) self.addRow(QHLine()) def init_row_functions(self): self.inp_functions_combo.addItem("Ackley", ackley) self.inp_functions_combo.addItem("Griewank", griewank) self.inp_functions_combo.addItem("Michalewicz", michalewicz) self.inp_extrema_min.setChecked(True) radio_box = QHBoxLayout() radio_box.addWidget(self.inp_extrema_min) radio_box.addWidget(self.inp_extrema_max) self.addRow("Function:", self.inp_functions_combo) self.inp_num_variables.setMaximum(10000) self.inp_num_variables.setValue(10) self.addRow("Number of variables:", self.inp_num_variables) self.addRow("Find:", radio_box) self.addRow(QHLine()) def init_row_general(self): self.header_general.setFont(self.medium_font) self.header_general.setText("General") self.inp_pop_size.setMaximum(10000) self.inp_pop_size.setValue(300) self.inp_lower_bound.setMaximum(1000000) self.inp_lower_bound.setMinimum(-1000000.0) self.inp_lower_bound.setValue(-10) self.inp_upper_bound.setMaximum(1000000) self.inp_upper_bound.setMinimum(-1000000.0) self.inp_upper_bound.setValue(10) self.addRow(self.header_general) self.addRow("Population size", self.inp_pop_size) self.addRow("Lower Bound", self.inp_lower_bound) self.addRow("Upper Bound", self.inp_upper_bound) self.addRow(QHLine()) def init_row_fitness_remapping(self): self.header_fitness_remapping.setFont(self.medium_font) self.header_fitness_remapping.setText("Fitness Remapping") self.inp_fitness_remapping.addItem("Rank Scaling", "Rank Scaling") self.inp_fitness_remapping.addItem("Fitness Scaling", "Fitness Scaling") self.addRow(self.header_fitness_remapping) self.addRow("Fitness remapping", self.inp_fitness_remapping) self.addRow(QHLine()) def init_row_stop(self): self.header_stop.setFont(self.medium_font) self.header_stop.setText("Stopping Criteria") self.inp_max_iter.setMaximum(100000) self.inp_similarity.setMaximum(100000) self.inp_best_result.setMinimum(-100000) self.inp_best_result.setMaximum(100000) self.inp_average_result.setMinimum(-100000) self.inp_average_result.setMaximum(100000) self.inp_max_iter.setValue(500) self.inp_similarity.setValue(80) self.inp_best_result.setValue(-10) self.inp_average_result.setValue(-10000) self.inp_similarity_cb.setText("Similar Results") self.inp_best_result_cb.setText("Best Result") self.inp_average_result_cb.setText("Average Result") self.inp_similarity_cb.stateChanged.connect(self.cb_similarity_signal) self.inp_best_result_cb.stateChanged.connect( self.cb_best_result_signal) self.inp_average_result_cb.stateChanged.connect( self.cb_average_result_signal) self.inp_similarity_cb.setChecked(False) self.inp_best_result_cb.setChecked(False) self.inp_average_result_cb.setChecked(False) self.inp_similarity.setEnabled(True) self.inp_best_result.setEnabled(False) self.inp_best_result.setStyleSheet("background:#555") self.inp_average_result.setEnabled(False) self.inp_average_result.setStyleSheet("background:#555") self.addRow(self.header_stop) self.addRow("Max iter", self.inp_max_iter) self.addRow(self.inp_similarity_cb, self.inp_similarity) self.addRow(self.inp_best_result_cb, self.inp_best_result) self.addRow(self.inp_average_result_cb, self.inp_average_result) self.addRow(QHLine()) def init_row_selection(self): self.header_selection.setFont(self.medium_font) self.header_selection.setText("Selection") self.inp_selection_method.addItem("Fittest Half", "Fittest Half") self.inp_selection_method.addItem("Roulette Wheel", "Roulette Wheel") self.inp_selection_method.addItem("Random", "Random") self.inp_selection_method.addItem("Whole Population", "Whole Population") self.inp_elitism.setMaximum(1) self.inp_elitism.setValue(0.01) self.inp_elitism.setSingleStep(0.01) self.addRow(self.header_selection) self.addRow("Selection Method", self.inp_selection_method) self.addRow("Elitism Percentage", self.inp_elitism) self.addRow(QHLine()) def init_row_pairing(self): self.header_pairing.setFont(self.medium_font) self.header_pairing.setText("Pairing") self.inp_pairing_method.addItem("Random", "Random") self.inp_pairing_method.addItem("Roulette Wheel", "Roulette Wheel") self.inp_pairing_method.addItem("Fittest", "Fittest") self.addRow(self.header_pairing) self.addRow("Pairing Method", self.inp_pairing_method) self.addRow(QHLine()) def init_row_crossover(self): self.header_crossover.setFont(self.medium_font) self.header_crossover.setText("Crossover") self.inp_crossover_method.addItem("Intermediate", "Intermediate") self.inp_crossover_method.addItem("Line Intermediate", "Line Intermediate") self.inp_crossover_method.addItem("Heuristic", "Heuristic") self.inp_crossover_method.addItem("One point", "One point") self.inp_crossover_method.addItem("Two point", "Two point") self.inp_crossover_method.addItem("Random", "Random") self.inp_mutation_method.setCurrentIndex(2) self.inp_crossover_fraction.setMaximum(1) self.inp_crossover_fraction.setValue(0.7) self.inp_crossover_fraction.setSingleStep(0.05) self.intermediate_offset.setMaximum(20) self.intermediate_offset.setValue(1.55) self.intermediate_offset.setSingleStep(0.05) self.addRow(self.header_crossover) self.addRow("Crossover Method", self.inp_crossover_method) self.addRow("Crossover Fraction", self.inp_crossover_fraction) self.addRow("Intermediate Offset", self.intermediate_offset) self.addRow(QHLine()) def init_row_mutation(self): self.header_mutation.setFont(self.medium_font) self.header_mutation.setText("Mutation") self.inp_mutation_method.addItem("Gauss", "Gauss") self.inp_mutation_method.addItem("Random", "Random") self.inp_mutation_intensity.setMaximum(200) self.inp_mutation_intensity.setValue(2) self.inp_mutation_intensity.setDecimals(4) self.inp_mutation_intensity.setSingleStep(0.01) self.inp_mutation_intensity_final.setMaximum(200) self.inp_mutation_intensity_final.setDecimals(4) self.inp_mutation_intensity_final.setValue(0.001) self.inp_mutation_intensity_final.setSingleStep(0.5) self.addRow(self.header_mutation) self.addRow("Mutation Method", self.inp_mutation_method) self.addRow("Mutation Intensity", self.inp_mutation_intensity) self.addRow("Final Mutation Intensity", self.inp_mutation_intensity_final) self.addRow(QHLine()) def get_options(self): function = self.inp_functions_combo.currentData() num_var = self.inp_num_variables.text() if self.inp_extrema_min.isChecked(): extrem = 0 else: extrem = 1 pop_size = self.inp_pop_size.text() low_bound = self.inp_lower_bound.text() upp_bound = self.inp_upper_bound.text() max_iter = self.inp_max_iter.text() sim_results = self.inp_similarity.text() best_res = self.inp_best_result.text() average_res = self.inp_average_result.text() select_method = self.inp_selection_method.currentText() elite_percent = self.inp_elitism.text() pairing = self.inp_pairing_method.currentText() crossover_method = self.inp_crossover_method.currentText() crossover_fraction = self.inp_crossover_fraction.text() intermediate_offset = self.intermediate_offset.text() mutation_method = self.inp_mutation_method.currentText() mutation_intensity = self.inp_mutation_intensity.text() mutation_intensity_final = self.inp_mutation_intensity_final.text() fitness_remapping = self.inp_fitness_remapping.currentText() options = { "function": function, "num_var": num_var, "pop_size": int(pop_size), "max_iter": int(max_iter), "lower_bound": float(low_bound.replace(",", ".")), "upper_bound": float(upp_bound.replace(",", ".")), "find_max": extrem, "prints": 0, "average_result": float(average_res.replace(",", ".")), "best_result": float(best_res.replace(",", ".")), "similarity": float(sim_results.replace(",", ".")), "selection": select_method, "pairing": pairing, "crossover": crossover_method, "crossover_fraction": float(crossover_fraction.replace(",", ".")), "intermediate_offset": float(intermediate_offset.replace(",", ".")), # 0 mean child will be between parents, 1 mean offset is same as two parent distance "mutation": mutation_method, "mutation_intensity": float(mutation_intensity.replace(",", ".")), "mutation_intensity_final": float(mutation_intensity_final.replace(",", ".")), "elitism": float(elite_percent.replace(",", ".")), "fitness_remapping": fitness_remapping } if not self.inp_similarity_cb.isChecked(): options["similarity"] = None if not self.inp_best_result_cb.isChecked(): options["best_result"] = None if not self.inp_average_result_cb.isChecked(): options["average_result"] = None return options def cb_similarity_signal(self): if self.inp_similarity_cb.isChecked(): self.inp_similarity.setEnabled(True) self.inp_similarity.setStyleSheet("") else: self.inp_similarity.setEnabled(False) self.inp_similarity.setStyleSheet("background:#555") def cb_best_result_signal(self): if self.inp_best_result_cb.isChecked(): self.inp_best_result.setEnabled(True) self.inp_best_result.setStyleSheet("") else: self.inp_best_result.setEnabled(False) self.inp_best_result.setStyleSheet("background:#555") def cb_average_result_signal(self): if self.inp_average_result_cb.isChecked(): self.inp_average_result.setEnabled(True) self.inp_average_result.setStyleSheet("") else: self.inp_average_result.setEnabled(False) self.inp_average_result.setStyleSheet("background:#555")
class NumberConversion(QWidget): def __init__(self): super(NumberConversion, self).__init__() # App attributes self.bin_format_base = None self.bin_format_base_byte = None # Use language settings self.ml = ManageLng() main_layout = QGridLayout() self.setLayout(main_layout) # Input self.inputbox = QGroupBox( self.ml.get_tr_text("tab_num_conv_inputbox_gbox_name")) self.inputbox.setMaximumWidth(400) main_layout.addWidget(self.inputbox, 0, 0) inputbox_layout = QGridLayout() inputbox_layout.setHorizontalSpacing(25) inputbox_layout.setVerticalSpacing(35) inputbox_layout.setAlignment(Qt.AlignCenter) self.inputbox.setLayout(inputbox_layout) self.input_number_label = QLabel( self.ml.get_tr_text("tab_num_conv_inputbox_in_number_lab")) self.input_number_textfield = QLineEdit() self.input_number_textfield.setPlaceholderText("192") self.input_number_textfield.setAlignment(Qt.AlignCenter) self.input_number_textfield.returnPressed.connect(self.convert_action) inputbox_layout.addWidget(self.input_number_label, 0, 0, alignment=Qt.AlignCenter) inputbox_layout.addWidget(self.input_number_textfield, 0, 1) button_layout = QVBoxLayout() self.bin_button = QRadioButton( self.ml.get_tr_text("tab_num_conv_inputbox_bin_chkbox")) self.bin_button.clicked.connect( lambda: self.input_number_textfield.setPlaceholderText("11100010")) self.dec_button = QRadioButton( self.ml.get_tr_text("tab_num_conv_inputbox_dec_chkbox")) self.dec_button.clicked.connect( lambda: self.input_number_textfield.setPlaceholderText("192")) self.hex_button = QRadioButton( self.ml.get_tr_text("tab_num_conv_inputbox_hex_chkbox")) self.hex_button.clicked.connect( lambda: self.input_number_textfield.setPlaceholderText("FF")) self.dec_button.setChecked(True) button_layout.addWidget(self.bin_button) button_layout.addWidget(self.dec_button) button_layout.addWidget(self.hex_button) inputbox_layout.addLayout(button_layout, 0, 3, 1, 2) self.convert_button = QPushButton( self.ml.get_tr_text("tab_num_conv_inputbox_conv_btn")) self.convert_button.clicked.connect(self.convert_action) self.convert_button.setIcon(QIcon("static/images/exchange.png")) inputbox_layout.addWidget(self.convert_button, 1, 1, alignment=Qt.AlignCenter) # Output self.outputbox = QGroupBox( self.ml.get_tr_text("tab_num_conv_outputbox_gbox_name")) main_layout.addWidget(self.outputbox, 0, 1) outputbox_layout = QGridLayout() outputbox_layout.setHorizontalSpacing(25) self.outputbox.setLayout(outputbox_layout) self.bin_label = QLabel( self.ml.get_tr_text("tab_num_conv_outputbox_bin_lab")) self.bin_label.setAlignment(Qt.AlignCenter) self.dec_label = QLabel( self.ml.get_tr_text("tab_num_conv_outputbox_dec_lab")) self.dec_label.setAlignment(Qt.AlignCenter) self.hex_label = QLabel( self.ml.get_tr_text("tab_num_conv_outputbox_hex_lab")) self.hex_label.setAlignment(Qt.AlignCenter) self.bin_output = QLineEdit() self.bin_output.setReadOnly(True) self.bin_output.setAlignment(Qt.AlignCenter) self.dec_output = QLineEdit() self.dec_output.setReadOnly(True) self.dec_output.setAlignment(Qt.AlignCenter) self.hex_output = QLineEdit() self.hex_output.setReadOnly(True) self.hex_output.setAlignment(Qt.AlignCenter) self.bin_output_copy_button = QPushButton( self.ml.get_tr_text("tab_num_conv_outputbox_copy_btn")) self.bin_output_copy_button.setIcon( QIcon("static/images/copy_clipboard.png")) self.bin_output_copy_button.clicked.connect( lambda: copy_action(self.bin_output.text())) self.dec_output_copy_button = QPushButton( self.ml.get_tr_text("tab_num_conv_outputbox_copy_btn")) self.dec_output_copy_button.setIcon( QIcon("static/images/copy_clipboard.png")) self.dec_output_copy_button.clicked.connect( lambda: copy_action(self.dec_output.text())) self.hex_output_copy_button = QPushButton( self.ml.get_tr_text("tab_num_conv_outputbox_copy_btn")) self.hex_output_copy_button.setIcon( QIcon("static/images/copy_clipboard.png")) self.hex_output_copy_button.clicked.connect( lambda: copy_action(self.hex_output.text())) outputbox_layout.addWidget(self.bin_label, 0, 0) outputbox_layout.addWidget(self.bin_output, 0, 1) outputbox_layout.addWidget(self.bin_output_copy_button, 0, 2) outputbox_layout.addWidget(self.dec_label, 1, 0) outputbox_layout.addWidget(self.dec_output, 1, 1) outputbox_layout.addWidget(self.dec_output_copy_button, 1, 2) outputbox_layout.addWidget(self.hex_label, 2, 0) outputbox_layout.addWidget(self.hex_output, 2, 1) outputbox_layout.addWidget(self.hex_output_copy_button, 2, 2) # IP address/mask number conversion self.ip_address_number_conversion_box = QGroupBox( self.ml.get_tr_text("tab_num_conv_ip_mask_conv_gbox_name")) main_layout.addWidget(self.ip_address_number_conversion_box, 1, 0, 1, 2) ip_address_number_conversion_layout = QGridLayout() ip_address_number_conversion_layout.setAlignment(Qt.AlignCenter) ip_address_number_conversion_layout.setHorizontalSpacing(25) ip_address_number_conversion_layout.setVerticalSpacing(24) self.ip_address_number_conversion_box.setLayout( ip_address_number_conversion_layout) self.input_label = QLabel( self.ml.get_tr_text("tab_num_conv_ip_mask_conv_in_lab")) self.input_label.setAlignment(Qt.AlignCenter) self.input_label.setMaximumWidth(150) self.input_textfield = QLineEdit() self.input_textfield.setPlaceholderText("192.168.1.1") self.input_textfield.setAlignment(Qt.AlignLeft) self.input_textfield.setMaximumWidth(300) self.input_textfield.setAlignment(Qt.AlignCenter) self.input_textfield.returnPressed.connect(self.convert_action_2) ip_address_number_conversion_layout.addWidget(self.input_label, 0, 0) ip_address_number_conversion_layout.addWidget(self.input_textfield, 0, 1) button_layout_2 = QVBoxLayout() self.dec_to_bin_button = QRadioButton( self.ml.get_tr_text("tab_num_conv_ip_mask_conv_dectobin")) self.dec_to_bin_button.clicked.connect( lambda: self.input_textfield.setPlaceholderText("192.168.1.1")) self.dec_to_bin_button.setMaximumWidth(150) self.bin_to_dec_button = QRadioButton( self.ml.get_tr_text("tab_num_conv_ip_mask_conv_bintodec")) self.bin_to_dec_button.clicked.connect( lambda: self.input_textfield.setPlaceholderText( "11000000.10101000.00000001.00000001")) self.bin_to_dec_button.setMaximumWidth(150) self.dec_to_bin_button.setChecked(True) button_layout_2.addWidget(self.dec_to_bin_button) button_layout_2.addWidget(self.bin_to_dec_button) ip_address_number_conversion_layout.addLayout(button_layout_2, 0, 2) self.output_label = QLabel( self.ml.get_tr_text("tab_num_conv_ip_mask_conv_out_lab")) self.output_label.setAlignment(Qt.AlignCenter) self.output_textfield = QLineEdit() self.output_textfield.setMaximumWidth(300) self.output_textfield.setReadOnly(True) self.output_textfield.setAlignment(Qt.AlignCenter) ip_address_number_conversion_layout.addWidget(self.output_label, 1, 0) ip_address_number_conversion_layout.addWidget(self.output_textfield, 1, 1) self.output_textfield_copy_button = QPushButton( self.ml.get_tr_text("tab_num_conv_ip_mask_conv_copy_btn")) self.output_textfield_copy_button.setIcon( QIcon("static/images/copy_clipboard.png")) self.output_textfield_copy_button.clicked.connect( lambda: copy_action(self.output_textfield.text())) ip_address_number_conversion_layout.addWidget( self.output_textfield_copy_button, 1, 2, alignment=Qt.AlignLeft) self.convert_button_2 = QPushButton( self.ml.get_tr_text("tab_num_conv_ip_mask_conv_convert_btn")) self.convert_button_2.clicked.connect(self.convert_action_2) self.convert_button_2.setIcon(QIcon("static/images/exchange.png")) ip_address_number_conversion_layout.addWidget( self.convert_button_2, 2, 0, 1, 3, alignment=Qt.AlignHCenter) def convert_action(self): if is_empty(self.input_number_textfield.text()): PopupWindow("warning", self.ml.get_tr_text("tab_num_conv_warning01"), self.input_number_textfield) else: if self.bin_button.isChecked(): self.source_bin(self.input_number_textfield.text()) elif self.dec_button.isChecked(): self.source_dec(self.input_number_textfield.text()) else: self.source_hex(self.input_number_textfield.text()) def source_bin(self, bin_number): bin_number_corrected = get_corrected_number(bin_number) bin_number_corrected_byte = bin_number_corrected.rjust(8, "0") if not is_correct_binary(bin_number_corrected): PopupWindow("warning", self.ml.get_tr_text("tab_num_conv_warning02"), self.input_number_textfield) else: if 0 <= int(bin_number_corrected, 2) <= 255: if bin_number_corrected != bin_number_corrected_byte: self.bin_format_base = bin_number_corrected self.bin_format_base_byte = bin_number_corrected_byte bin_format = get_bin_format( self.bin_format_base, self.ml.get_tr_text("byte_format_str"), self.bin_format_base_byte) else: bin_format = self.bin_format_base else: bin_format = bin_number_corrected dec_format = str(int(bin_number_corrected, 2)) hex_format = hex(int(bin_number_corrected, 2)).replace("0x", "").upper() self.bin_output.setText(bin_format) self.dec_output.setText(dec_format) self.hex_output.setText(hex_format) def source_dec(self, dec_number): dec_number_corrected = get_corrected_number(dec_number) if not is_correct_decimal(dec_number_corrected): PopupWindow("warning", self.ml.get_tr_text("tab_num_conv_warning03"), self.input_number_textfield) else: if 0 <= int(dec_number_corrected) <= 255: self.bin_format_base = bin(int(dec_number_corrected)).replace( "0b", "") self.bin_format_base_byte = self.bin_format_base.rjust(8, "0") if self.bin_format_base != self.bin_format_base_byte: bin_format = get_bin_format( self.bin_format_base, self.ml.get_tr_text("byte_format_str"), self.bin_format_base_byte) else: bin_format = self.bin_format_base else: bin_format = bin(int(dec_number_corrected)).replace("0b", "") dec_format = dec_number_corrected hex_format = hex(int(dec_number_corrected)).replace("0x", "").upper() self.bin_output.setText(bin_format) self.dec_output.setText(dec_format) self.hex_output.setText(hex_format) def source_hex(self, hex_number): hex_number_corrected = get_corrected_number(hex_number).upper() if not is_correct_hexadecimal(hex_number_corrected): PopupWindow("warning", self.ml.get_tr_text("tab_num_conv_warning04"), self.input_number_textfield) else: if 0 <= int(hex_number_corrected, 16) <= 255: self.bin_format_base = bin(int(hex_number_corrected, 16)).replace("0b", "") self.bin_format_base_byte = self.bin_format_base.rjust(8, "0") if self.bin_format_base != self.bin_format_base_byte: bin_format = get_bin_format( self.bin_format_base, self.ml.get_tr_text("byte_format_str"), self.bin_format_base_byte) else: bin_format = self.bin_format_base else: bin_format = bin(int(hex_number_corrected, 16)).replace("0b", "") dec_format = str(int(hex_number_corrected, 16)) hex_format = hex_number_corrected self.bin_output.setText(bin_format) self.dec_output.setText(dec_format) self.hex_output.setText(hex_format) def convert_action_2(self): if is_empty(self.input_textfield.text()): PopupWindow("warning", self.ml.get_tr_text("tab_num_conv_warning05"), self.input_textfield) elif self.dec_to_bin_button.isChecked(): if is_correct_any_ip_dec(self.input_textfield.text()): self.output_textfield.setText( dec_to_bin(self.input_textfield.text())) else: PopupWindow("warning", self.ml.get_tr_text("tab_num_conv_warning06"), self.input_textfield) else: if is_correct_any_ip_bin(self.input_textfield.text()): self.output_textfield.setText( bin_to_dec(self.input_textfield.text())) else: PopupWindow("warning", self.ml.get_tr_text("tab_num_conv_warning07"), self.input_textfield) def re_translate_ui(self, lang): self.ml = ManageLng(lang) self.inputbox.setTitle( self.ml.get_tr_text("tab_num_conv_inputbox_gbox_name")) self.input_number_label.setText( self.ml.get_tr_text("tab_num_conv_inputbox_in_number_lab")) self.bin_button.setText( self.ml.get_tr_text("tab_num_conv_inputbox_bin_chkbox")) self.dec_button.setText( self.ml.get_tr_text("tab_num_conv_inputbox_dec_chkbox")) self.hex_button.setText( self.ml.get_tr_text("tab_num_conv_inputbox_hex_chkbox")) self.convert_button.setText( self.ml.get_tr_text("tab_num_conv_inputbox_conv_btn")) self.outputbox.setTitle( self.ml.get_tr_text("tab_num_conv_outputbox_gbox_name")) self.bin_label.setText( self.ml.get_tr_text("tab_num_conv_outputbox_bin_lab")) self.dec_label.setText( self.ml.get_tr_text("tab_num_conv_outputbox_dec_lab")) self.hex_label.setText( self.ml.get_tr_text("tab_num_conv_outputbox_hex_lab")) self.bin_output_copy_button.setText( self.ml.get_tr_text("tab_num_conv_outputbox_copy_btn")) self.dec_output_copy_button.setText( self.ml.get_tr_text("tab_num_conv_outputbox_copy_btn")) self.hex_output_copy_button.setText( self.ml.get_tr_text("tab_num_conv_outputbox_copy_btn")) self.ip_address_number_conversion_box.setTitle( self.ml.get_tr_text("tab_num_conv_ip_mask_conv_gbox_name")) self.input_label.setText( self.ml.get_tr_text("tab_num_conv_ip_mask_conv_in_lab")) self.dec_to_bin_button.setText( self.ml.get_tr_text("tab_num_conv_ip_mask_conv_dectobin")) self.bin_to_dec_button.setText( self.ml.get_tr_text("tab_num_conv_ip_mask_conv_bintodec")) self.output_label.setText( self.ml.get_tr_text("tab_num_conv_ip_mask_conv_out_lab")) self.output_textfield_copy_button.setText( self.ml.get_tr_text("tab_num_conv_ip_mask_conv_copy_btn")) self.convert_button_2.setText( self.ml.get_tr_text("tab_num_conv_ip_mask_conv_convert_btn")) if self.bin_output.text(): self.bin_output.setText( get_bin_format(self.bin_format_base, self.ml.get_tr_text("byte_format_str"), self.bin_format_base_byte))
class HistWidget(ToolWidget): def __init__(self, image, parent=None): super(ToolWidget, self).__init__(parent) self.value_radio = QRadioButton(self.tr('Value')) self.value_radio.setChecked(True) self.last_radio = self.value_radio self.red_radio = QRadioButton(self.tr('Red')) self.green_radio = QRadioButton(self.tr('Green')) self.blue_radio = QRadioButton(self.tr('Blue')) self.rgb_radio = QRadioButton(self.tr('RGB')) self.smooth_check = QCheckBox(self.tr('Smooth line')) self.smooth_check.setToolTip(self.tr('Interpolated values plot')) self.log_check = QCheckBox(self.tr('Log scale')) self.log_check.setToolTip(self.tr('Y-axes logarithmic scale')) self.grid_check = QCheckBox(self.tr('Show grid')) self.grid_check.setToolTip(self.tr('Display XY main grid lines')) self.marker_check = QCheckBox(self.tr('Show markers')) self.marker_check.setToolTip( self.tr('Show plot markers for min(--), avg(-), max(-.)')) self.start_slider = ParamSlider([0, 255], 8, 0, bold=True) self.end_slider = ParamSlider([0, 255], 8, 255, bold=True) channels = cv.split(cv.cvtColor(image, cv.COLOR_BGR2RGB)) channels.append(cv.cvtColor(image, cv.COLOR_BGR2GRAY)) self.hist = [compute_hist(c) for c in channels] rows, cols, chans = image.shape pixels = rows * cols self.unique_colors = np.unique(np.reshape(image, (pixels, chans)), axis=0).shape[0] self.unique_ratio = np.round(self.unique_colors / pixels * 100, 2) self.value_radio.clicked.connect(self.redraw) self.red_radio.clicked.connect(self.redraw) self.green_radio.clicked.connect(self.redraw) self.blue_radio.clicked.connect(self.redraw) self.rgb_radio.clicked.connect(self.redraw) self.smooth_check.stateChanged.connect(self.redraw) self.log_check.stateChanged.connect(self.redraw) self.grid_check.stateChanged.connect(self.redraw) self.marker_check.stateChanged.connect(self.redraw) self.start_slider.valueChanged.connect(self.redraw) self.end_slider.valueChanged.connect(self.redraw) self.table_widget = QTableWidget(13, 2) self.table_widget.setHorizontalHeaderLabels( [self.tr('Property'), self.tr('Value')]) self.table_widget.setItem(0, 0, QTableWidgetItem(self.tr('Least frequent'))) self.table_widget.item(0, 0).setToolTip( self.tr('Value that appears less')) self.table_widget.setItem(1, 0, QTableWidgetItem(self.tr('Most frequent'))) self.table_widget.item(1, 0).setToolTip( self.tr('Value that appears more')) self.table_widget.setItem(2, 0, QTableWidgetItem(self.tr('Average level'))) self.table_widget.item(2, 0).setToolTip(self.tr('Histogram mean value')) self.table_widget.setItem(3, 0, QTableWidgetItem(self.tr('Median level'))) self.table_widget.item(3, 0).setToolTip(self.tr('Histogram median value')) self.table_widget.setItem(4, 0, QTableWidgetItem(self.tr('Deviation'))) self.table_widget.item(4, 0).setToolTip( self.tr('Histogram standard deviation')) self.table_widget.setItem(5, 0, QTableWidgetItem(self.tr('Pixel count'))) self.table_widget.item(5, 0).setToolTip( self.tr('Total values in current range')) self.table_widget.setItem(6, 0, QTableWidgetItem(self.tr('Percentile'))) self.table_widget.item(6, 0).setToolTip( self.tr('Percentage of total pixels')) self.table_widget.setItem(7, 0, QTableWidgetItem(self.tr('Nonzero range'))) self.table_widget.item(7, 0).setToolTip( self.tr('Minimal range without empty bins')) self.table_widget.setItem(8, 0, QTableWidgetItem(self.tr('Empty bins'))) self.table_widget.item(8, 0).setToolTip( self.tr('Number of missing values')) self.table_widget.setItem(9, 0, QTableWidgetItem(self.tr('Unique colors'))) self.table_widget.item(9, 0).setToolTip(self.tr('Unique RGB color count')) self.table_widget.setItem(10, 0, QTableWidgetItem(self.tr('Unique ratio'))) self.table_widget.item(10, 0).setToolTip( self.tr('Unique colors vs total pixels')) self.table_widget.setItem(11, 0, QTableWidgetItem(self.tr('Smoothness'))) self.table_widget.item(11, 0).setToolTip( self.tr('Estimated correlation among bin values')) self.table_widget.setItem(12, 0, QTableWidgetItem(self.tr('Fullness'))) self.table_widget.item(12, 0).setToolTip( self.tr('Area covered vs total size')) for i in range(self.table_widget.rowCount()): modify_font(self.table_widget.item(i, 0), bold=True) self.table_widget.setSelectionMode(QAbstractItemView.SingleSelection) self.table_widget.setEditTriggers(QAbstractItemView.NoEditTriggers) self.table_widget.setAlternatingRowColors(True) self.table_widget.setMinimumWidth(200) self.table_widget.resizeColumnsToContents() figure = Figure() plot_canvas = FigureCanvas(figure) self.axes = plot_canvas.figure.subplots() self.redraw() figure.set_tight_layout(True) range_layout = QGridLayout() range_layout.addWidget(QLabel(self.tr('Start:')), 0, 0) range_layout.addWidget(self.start_slider, 0, 1) range_layout.addWidget(QLabel(self.tr('End:')), 1, 0) range_layout.addWidget(self.end_slider, 1, 1) right_frame = QFrame() right_layout = QVBoxLayout() right_layout.addWidget(self.table_widget) right_layout.addLayout(range_layout) right_frame.setLayout(right_layout) center_split = QSplitter() center_split.addWidget(plot_canvas) center_split.addWidget(right_frame) bottom_layout = QHBoxLayout() bottom_layout.addWidget(QLabel(self.tr('Channel:'))) bottom_layout.addWidget(self.value_radio) bottom_layout.addWidget(self.red_radio) bottom_layout.addWidget(self.green_radio) bottom_layout.addWidget(self.blue_radio) bottom_layout.addWidget(self.rgb_radio) bottom_layout.addStretch() bottom_layout.addWidget(self.smooth_check) bottom_layout.addWidget(self.log_check) bottom_layout.addWidget(self.grid_check) bottom_layout.addWidget(self.marker_check) main_layout = QVBoxLayout() main_layout.addWidget(center_split) main_layout.addLayout(bottom_layout) self.setLayout(main_layout) def redraw(self): x = np.arange(256) alpha = 0.25 rgb = self.rgb_radio.isChecked() red = self.red_radio.isChecked() green = self.green_radio.isChecked() blue = self.blue_radio.isChecked() value = self.value_radio.isChecked() smoothness = self.smooth_check.isChecked() grid = self.grid_check.isChecked() log = self.log_check.isChecked() try: self.axes.clear() except RecursionError: return y = None step = None if smoothness else 'mid' if value: y = self.hist[3] if smoothness: self.axes.plot(x, y, 'k') else: self.axes.step(x, y, 'k', where='mid') self.axes.fill_between(x, y, alpha=alpha, facecolor='k', step=step) else: if red or rgb: y = self.hist[0] if smoothness: self.axes.plot(x, y, 'r') else: self.axes.step(x, y, 'r', where='mid') self.axes.fill_between(x, y, alpha=alpha, facecolor='r', step=step) if green or rgb: y = self.hist[1] if smoothness: self.axes.plot(x, y, 'g') else: self.axes.step(x, y, 'g', where='mid') self.axes.fill_between(x, y, alpha=alpha, facecolor='g', step=step) if blue or rgb: y = self.hist[2] if smoothness: self.axes.plot(x, y, 'b') else: self.axes.step(x, y, 'b', where='mid') self.axes.fill_between(x, y, alpha=alpha, facecolor='b', step=step) if log: self.axes.set_yscale('log') self.axes.set_ylim(bottom=1) else: self.axes.set_yscale('linear') self.axes.set_ylim(bottom=0) self.axes.set_xlim([0, 255]) self.axes.set_xlabel(self.tr('intensity value')) self.axes.set_ylabel(self.tr('pixel count')) self.axes.set_xticks([0, 64, 128, 192, 255]) self.axes.grid(grid, which='both') if rgb: self.table_widget.setEnabled(False) self.marker_check.setEnabled(False) self.start_slider.setEnabled(False) self.end_slider.setEnabled(False) for i in range(self.table_widget.rowCount()): if self.table_widget.item(i, 1) is not None: self.table_widget.item(i, 1).setText('') self.table_widget.item(i, 1).setBackgroundColor( QColor('white')) else: self.table_widget.setEnabled(True) self.marker_check.setEnabled(True) self.start_slider.setEnabled(True) self.end_slider.setEnabled(True) start = self.start_slider.value() end = self.end_slider.value() if end <= start: end = start + 1 elif start >= end: start = end - 1 total = np.sum(y) x = x[start:end + 1] y = y[start:end + 1] count = np.sum(y) if count != 0: argmin = np.argmin(y) + start argmax = np.argmax(y) + start mean = np.round(np.sum(x * y) / count, 2) stddev = np.round(np.sqrt(np.sum(((x - mean)**2) * y) / count), 2) median = np.argmax(np.cumsum(y) > count / 2) + start percent = np.round(count / total * 100, 2) empty = len(x) - np.count_nonzero(y) nonzero = [ np.nonzero(y)[0][0] + start, np.nonzero(y)[0][-1] + start ] fullness = np.round(count / (255 * np.max(y)) * 100, 2) y = y / np.max(y) sweep = len(y) smoothness = 0 if sweep >= 5: for i in range(2, sweep - 2): yl = 2 * y[i - 1] - y[i - 2] yr = 2 * y[i + 1] - y[i + 2] smoothness += abs(y[i] - (yl + yr) / 2) smoothness = np.round( (1 - (smoothness / (sweep - 2))) * 100, 2) if self.marker_check.isChecked(): self.axes.axvline(argmin, linestyle='--', color='m') self.axes.axvline(mean, linestyle='-', color='m') self.axes.axvline(argmax, linestyle='-.', color='m') self.axes.axvline(median, linestyle=':', color='m') else: argmin = argmax = mean = stddev = median = percent = smoothness = empty = nonzero = fullness = 0 self.table_widget.setItem(0, 1, QTableWidgetItem(str(argmin))) self.table_widget.setItem(1, 1, QTableWidgetItem(str(argmax))) self.table_widget.setItem(2, 1, QTableWidgetItem(str(mean))) self.table_widget.setItem(3, 1, QTableWidgetItem(str(median))) self.table_widget.setItem(4, 1, QTableWidgetItem(str(stddev))) self.table_widget.setItem(5, 1, QTableWidgetItem(str(count))) self.table_widget.setItem(6, 1, QTableWidgetItem(str(percent) + '%')) self.table_widget.setItem(7, 1, QTableWidgetItem(str(nonzero))) self.table_widget.setItem(8, 1, QTableWidgetItem(str(empty))) self.table_widget.setItem( 9, 1, QTableWidgetItem(str(self.unique_colors))) self.table_widget.setItem( 10, 1, QTableWidgetItem(str(self.unique_ratio) + '%')) color_by_value(self.table_widget.item(10, 1), self.unique_ratio, [25, 50, 75]) self.table_widget.setItem(11, 1, QTableWidgetItem(str(smoothness) + '%')) color_by_value(self.table_widget.item(11, 1), smoothness, [80, 90, 95]) self.table_widget.setItem(12, 1, QTableWidgetItem(str(fullness) + '%')) color_by_value(self.table_widget.item(12, 1), fullness, [5, 10, 20]) self.table_widget.resizeColumnsToContents() if start != 0 or end != 255: self.axes.axvline(start, linestyle=':', color='k') self.axes.axvline(end, linestyle=':', color='k') _, top = self.axes.get_ylim() self.axes.fill_between(np.arange(start, end + 1), top, facecolor='y', alpha=alpha * 2) self.axes.figure.canvas.draw()
class MainApp(QMainWindow): def __init__(self): QMainWindow.__init__(self) self.setAttribute(Qt.WA_DeleteOnClose) self.setWindowTitle("MIE") self.main_widget = QWidget(self) self.setStyleSheet('QMainWindow {background-color: #8b8b8b}') #cfcfcf self.setWindowIcon(QtGui.QIcon('mie_icon.ico')) #DIAMETER self.label_d = QLabel("Radius [nm|:", self) self.slider_d = QSlider(Qt.Horizontal) self.slider_d.setMinimum(5) self.slider_d.setMaximum(200) self.slider_d.setTickInterval(5) self.slider_d.setValue(50) self.edit_d = QLineEdit(self) self.edit_d.setMaxLength(5) a = self.slider_d.value() self.edit_d.setText(str(a)) self.push_d_down = QPushButton("<", self) self.push_d_up = QPushButton(">", self) #REFRACTIVE INDEX self.label_n = QLabel("Refractiv index (medium):", self) self.slider_n = QSlider(Qt.Horizontal) self.slider_n.setMinimum(100) self.slider_n.setMaximum(300) self.slider_n.setTickInterval(10) self.slider_n.setValue(100) self.edit_n = QLineEdit(self) self.edit_n.setMaxLength(5) n_m = self.slider_n.value() / 100 self.edit_n.setText(str(n_m)) self.push_n_down = QPushButton("<", self) self.push_n_up = QPushButton(">", self) #CROSS SECTION self.label_radio = QLabel("Cross section:", self) self.radiobutton_sca = QRadioButton("Scattering") self.radiobutton_sca.setChecked(True) self.radiobutton_abs = QRadioButton("Absorption") self.radiobutton_ext = QRadioButton("Extinction") csection = "Scattering" #MATERIAL self.label_m = QLabel("Material (Nanosphere):", self) self.cb_m = QComboBox() list_m = ["Gold", "Silver", "Copper"] self.cb_m.addItems(list_m) material = "Gold" #PLOT self.plot_mie = QPushButton("PLOT", self) self.plot_mie.setStyleSheet('QPushButton {background-color: #12E316}') #CLEAR PLOT self.clear_mie = QPushButton("CLEAR", self) self.clear_mie.setStyleSheet('QPushButton {background-color: #FF0505}') #SAVE FILE self.save_mie = QPushButton("SAVE FILE", self) self.save_mie.setStyleSheet('QPushButton {background-color: #cfcfcf}') #LAYOUT CROSS SECTION self.layout_radio = QHBoxLayout() self.layout_radio.addWidget(self.radiobutton_sca) self.layout_radio.addWidget(self.radiobutton_abs) self.layout_radio.addWidget(self.radiobutton_ext) #LAYOUT DIAMETER self.layout_d1 = QHBoxLayout() self.layout_d1.addWidget(self.push_d_down) self.layout_d1.addWidget(self.slider_d) self.layout_d1.addWidget(self.push_d_up) self.layout_d = QVBoxLayout() self.layout_d.addWidget(self.label_d) self.layout_d.addSpacing(1) self.layout_d.addLayout(self.layout_d1) self.layout_d.addSpacing(1) self.layout_d.addWidget(self.edit_d) #LAYOUT REFRACTIVE INDEX self.layout_n1 = QHBoxLayout() self.layout_n1.addWidget(self.push_n_down) self.layout_n1.addWidget(self.slider_n) self.layout_n1.addWidget(self.push_n_up) self.layout_n = QVBoxLayout() self.layout_n.addWidget(self.label_n) self.layout_n.addSpacing(1) self.layout_n.addLayout(self.layout_n1) self.layout_n.addSpacing(1) self.layout_n.addWidget(self.edit_n) #LAYOUT MATERIAL self.layout_m = QVBoxLayout() self.layout_m.addWidget(self.label_m) self.layout_m.addSpacing(1) self.layout_m.addWidget(self.cb_m) #LAYOUT PARAMETER BELOW self.layout_parameter = QHBoxLayout() self.layout_parameter.addLayout(self.layout_n) self.layout_parameter.addLayout(self.layout_d) #LAYOUT PARAMETER RADIO self.layout_parameter_radio = QVBoxLayout() self.layout_parameter_radio.addWidget(self.label_radio) self.layout_parameter_radio.addSpacing(1) self.layout_parameter_radio.addLayout(self.layout_radio) #LAYOUT PARAMETER ABOVE self.layout_parameter_o = QHBoxLayout() self.layout_parameter_o.addLayout(self.layout_m) self.layout_parameter_o.addLayout(self.layout_parameter_radio) #LAYOUT PLOT self.layout_save = QHBoxLayout() self.layout_save.addWidget(self.plot_mie) self.layout_save.addWidget(self.clear_mie) self.layout_save.addWidget(self.save_mie) #CANVAS self.layout_canvas = MplCanvas(self.main_widget, width=8, height=6, a=a, n_m=n_m, material=material, csection=csection) self.main_widget.setFocus() self.setCentralWidget(self.main_widget) self.navi_toolbar = NavigationToolbar(self.layout_canvas, self) #LAYOUT CANVAS PARAMETER self.layout_cp = QVBoxLayout() self.layout_cp.addLayout(self.layout_save) self.layout_cp.addWidget(self.layout_canvas) self.layout_cp.addWidget(self.navi_toolbar) #SETTINGS LABEL self.settings = QLabel( "----------------------------------------------------------------------------------SETTINGS----------------------------------------------------------------------------------", self) self.settings.setAlignment(Qt.AlignCenter) #OVERALL LAYOUT self.layout_all = QVBoxLayout(self.main_widget) self.layout_all.addLayout(self.layout_cp) self.layout_all.addWidget(self.settings) self.layout_all.addLayout(self.layout_parameter_o) self.layout_all.addLayout(self.layout_parameter) #CONNECT self.push_d_down.clicked.connect(self.connect_d_down) self.push_d_up.clicked.connect(self.connect_d_up) self.slider_d.valueChanged.connect(self.connect_d) self.push_n_down.clicked.connect(self.connect_n_down) self.push_n_up.clicked.connect(self.connect_n_up) self.slider_n.valueChanged.connect(self.connect_n) self.plot_mie.clicked.connect(self.connect_plot) self.save_mie.clicked.connect(self.connect_save) self.cb_m.activated.connect(self.connect_cb) self.clear_mie.clicked.connect(self.clear_gui) def connect_d(self): a = self.slider_d.value() self.edit_d.setText(str(a)) return a def connect_d_down(self): return self.slider_d.setValue(self.slider_d.value() - 5) def connect_d_up(self): return self.slider_d.setValue(self.slider_d.value() + 5) def connect_n(self): n_m = self.slider_n.value() / 100 self.edit_n.setText(str(n_m)) return n_m def connect_n_down(self): return self.slider_n.setValue(self.slider_n.value() - 10) def connect_n_up(self): return self.slider_n.setValue(self.slider_n.value() + 10) def connect_cb(self): material = self.cb_m.currentText() #print(material) return material def connect_cs(self): if self.radiobutton_sca.isChecked() == True: csection = "Scattering" return csection elif self.radiobutton_abs.isChecked() == True: csection = "Absorption" return csection elif self.radiobutton_ext.isChecked() == True: csection = "Extinction" return csection def connect_plot(self): return self.layout_canvas.drawPlot(self.connect_d(), self.connect_n(), self.connect_cb(), self.connect_cs()) def saveFileDialog(self): options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog fileName, _ = QFileDialog.getSaveFileName( self, "QFileDialog.getSaveFileName()", "", "All Files (*);;Text Files (*.txt)", options=options) f = np.savetxt(fileName + '.txt', self.layout_canvas.save_File().T, fmt='%.3f', delimiter=',', header='Wavelength [nm],Cross section [nm^2]') def connect_save(self): #print(self.layout_canvas.save_File()) try: self.saveFileDialog() except: print("No data!") def clear_gui(self): return self.layout_canvas.clearPlot()
class TelegramDialog(QDialog): def __init__(self): super().__init__(GlobalAccess().get_main_window()) def exec_(self): self.init_ui() self.set_values() return super().exec_() def init_ui(self): self.setWindowTitle(_('Telegram')) self.setWindowIcon(QIcon(config.ICON)) self.setSizeGripEnabled(False) self.setModal(True) self.layout = QFormLayout(self) self.label_token = QLabel(_('Token')) self.item_token = QLineEdit() self.layout.addRow(self.label_token, self.item_token) self.label_chat_id = QLabel(_('Chat id')) self.item_chat_id = QLineEdit() self.layout.addRow(self.label_chat_id, self.item_chat_id) self.label_template = QLabel(_('Template')) self.item_template = QTextEdit() self.item_template.setMinimumHeight(150) self.layout.addRow(self.label_template, self.item_template) self.item_enabled = QCheckBox(_('Enabled')) self.layout.addRow(self.item_enabled) self.parse_mode_groupbox = QGroupBox() self.parse_mode_groupbox.setTitle(_('Parse mode')) self.parse_mode_groupbox_layout = QFormLayout() self.parse_mode_item_text = QRadioButton(_('Text')) self.parse_mode_item_markdown = QRadioButton(_('Markdown')) self.parse_mode_item_html = QRadioButton(_('HTML')) self.parse_mode_groupbox_layout.addRow(self.parse_mode_item_text) self.parse_mode_groupbox_layout.addRow(self.parse_mode_item_markdown) self.parse_mode_groupbox_layout.addRow(self.parse_mode_item_html) self.parse_mode_groupbox.setLayout(self.parse_mode_groupbox_layout) self.layout.addRow(self.parse_mode_groupbox) def cancel_changes(): self.close() def apply_changes(): try: self.apply_changes_impl() except Exception as e: logging.error(str(e)) self.close() button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.button_ok = button_box.button(QDialogButtonBox.Ok) self.button_ok.setText(_('OK')) self.button_ok.clicked.connect(apply_changes) self.button_cancel = button_box.button(QDialogButtonBox.Cancel) self.button_cancel.setText(_('Cancel')) self.button_cancel.clicked.connect(cancel_changes) self.layout.addRow(button_box) self.show() def set_values(self): obj = race() token = obj.get_setting('telegram_token', '') url = obj.get_setting('telegram_chat_id', '') parse_mode = obj.get_setting('telegram_parse_mode', '') template = obj.get_setting('telegram_template', '{group} {name} {bib} {result} {place}') telegram_enabled = obj.get_setting('telegram_enabled', False) self.item_chat_id.setText(url) self.item_token.setText(token) self.item_template.setText(template) self.item_enabled.setChecked(telegram_enabled) if parse_mode == '': self.parse_mode_item_text.setChecked(True) elif parse_mode == 'Markdown': self.parse_mode_item_markdown.setChecked(True) elif parse_mode == 'HTML': self.parse_mode_item_html.setChecked(True) def apply_changes_impl(self): parse_mode = '' if self.parse_mode_item_markdown.isChecked(): parse_mode = 'Markdown' elif self.parse_mode_item_html.isChecked(): parse_mode = 'HTML' obj = race() obj.set_setting('telegram_token', self.item_token.text()) obj.set_setting('telegram_chat_id', self.item_chat_id.text()) obj.set_setting('telegram_enabled', self.item_enabled.isChecked()) obj.set_setting('telegram_parse_mode', parse_mode) obj.set_setting('telegram_template', self.item_template.toPlainText())
class MagnifierWidget(ToolWidget): def __init__(self, image, parent=None): super(MagnifierWidget, self).__init__(parent) self.equalize_radio = QRadioButton(self.tr('Equalization')) self.contrast_radio = QRadioButton(self.tr('Auto Contrast')) self.retinex_radio = QRadioButton(self.tr('Human Retina')) self.centile_spin = QSpinBox() self.centile_spin.setRange(0, 100) self.centile_spin.setValue(20) self.centile_spin.setSuffix(self.tr(' %')) self.channel_check = QCheckBox(self.tr('By channel')) self.equalize_radio.setChecked(True) self.last_radio = self.equalize_radio self.image = image self.viewer = ImageViewer(self.image, self.image) self.change() self.viewer.view_changed.connect(self.process) self.equalize_radio.toggled.connect(self.change) self.contrast_radio.toggled.connect(self.change) self.centile_spin.valueChanged.connect(self.change) self.channel_check.stateChanged.connect(self.change) self.retinex_radio.toggled.connect(self.change) top_layout = QHBoxLayout() top_layout.addWidget(QLabel(self.tr('Enhancement:'))) top_layout.addWidget(self.equalize_radio) top_layout.addWidget(self.contrast_radio) top_layout.addWidget(self.centile_spin) top_layout.addWidget(self.channel_check) top_layout.addWidget(self.retinex_radio) top_layout.addStretch() main_layout = QVBoxLayout() main_layout.addLayout(top_layout) main_layout.addWidget(self.viewer) self.setLayout(main_layout) def process(self, rect): y1 = rect.top() y2 = rect.bottom() x1 = rect.left() x2 = rect.right() roi = self.image[y1:y2, x1:x2] if self.equalize_radio.isChecked(): roi = cv.merge([cv.equalizeHist(c) for c in cv.split(roi)]) self.last_radio = self.equalize_radio elif self.contrast_radio.isChecked(): centile = self.centile_spin.value() / 200 if self.channel_check.isChecked(): roi = cv.merge([cv.LUT(c, auto_lut(c, centile)) for c in cv.split(roi)]) else: roi = cv.LUT(roi, auto_lut(cv.cvtColor(roi, cv.COLOR_BGR2GRAY), centile)) self.last_radio = self.contrast_radio elif self.retinex_radio.isChecked(): self.last_radio = self.retinex_radio else: self.last_radio.setChecked(True) return processed = np.copy(self.image) processed[y1:y2, x1:x2] = roi self.viewer.update_processed(processed) def change(self): self.process(self.viewer.get_rect())
class SportOrgImportDialog(QDialog): def __init__(self, races, current_race=0): super().__init__(GlobalAccess().get_main_window()) self.races = races self.current_race = current_race def exec_(self): self.init_ui() self.set_values() return super().exec_() def init_ui(self): self.setWindowTitle(_('Import')) self.setWindowIcon(QIcon(config.ICON)) self.setSizeGripEnabled(False) self.setModal(True) self.layout = QFormLayout(self) self.item_races = AdvComboBox() self.layout.addRow(QLabel(_('Choose race')), self.item_races) self.unique_id_box = QGroupBox(_('Unique id')) self.unique_id_box_layout = QFormLayout() self.unique_id_item_id = QRadioButton(_('Id')) self.unique_id_item_id.setChecked(True) self.unique_id_box_layout.addRow(self.unique_id_item_id) self.unique_id_item_name = QRadioButton(_('Name')) self.unique_id_item_name.setDisabled(True) self.unique_id_box_layout.addRow(self.unique_id_item_name) self.unique_id_box.setLayout(self.unique_id_box_layout) self.layout.addRow(self.unique_id_box) self.import_action_box = QGroupBox(_('Action')) self.import_action_box_layout = QFormLayout() self.import_action_item_add = QRadioButton(_('Add')) self.import_action_box_layout.addRow(self.import_action_item_add) self.import_action_item_overwrite = QRadioButton(_('Overwrite')) self.import_action_item_overwrite.setChecked(True) self.import_action_box_layout.addRow(self.import_action_item_overwrite) self.import_action_box.setLayout(self.import_action_box_layout) self.layout.addRow(self.import_action_box) def cancel_changes(): self.close() def apply_changes(): try: self.apply_changes_impl() except Exception as e: logging.error(str(e)) self.close() button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.button_ok = button_box.button(QDialogButtonBox.Ok) self.button_ok.setText(_('OK')) self.button_ok.clicked.connect(apply_changes) self.button_cancel = button_box.button(QDialogButtonBox.Cancel) self.button_cancel.setText(_('Cancel')) self.button_cancel.clicked.connect(cancel_changes) self.layout.addRow(button_box) self.show() def set_values(self): self.fill_race_list() def apply_changes_impl(self): import_race = self.races[self.item_races.currentIndex()] unique_id = 'id' if self.unique_id_item_name.isChecked(): unique_id = 'name' action = 'add' if self.import_action_item_overwrite.isChecked(): action = 'overwrite' obj = race() if unique_id == 'id' and action == 'overwrite': import_race.id = obj.id obj.update_data(import_race.to_dict()) return if unique_id == 'id' and action == 'add': organizations = [] for org in import_race.organizations: old_org = find(obj.organizations, id=org.id) old_org_by_name = find(obj.organizations, name=org.name) if old_org is None: if old_org_by_name is not None: org.name = '_' + org.name organizations.append(org) obj.organizations.extend(organizations) courses = [] for course in import_race.courses: old_course = find(obj.courses, id=course.id) old_course_by_name = find(obj.courses, name=course.name) if old_course is None: if old_course_by_name is not None: course.name = '_' + course.name courses.append(course) obj.courses.extend(courses) groups = [] for group in import_race.groups: old_group = find(obj.groups, id=group.id) old_group_by_name = find(obj.groups, name=group.name) if old_group is None: if old_group_by_name is not None: group.name = '_' + group.name if group.course: group.course = find(obj.courses, id=group.course.id) groups.append(group) obj.groups.extend(groups) persons = [] for person in import_race.persons: if find(obj.persons, id=person.id) is None: if person.group: person.group = find(obj.groups, id=person.group.id) if person.organization: person.organization = find(obj.organizations, id=person.organization.id) persons.append(person) obj.persons.extend(persons) results = [] for result in import_race.results: if find(obj.results, id=result.id) is None: if result.person: result.person = find(obj.persons, id=result.person.id) results.append(result) obj.results.extend(results) return def fill_race_list(self): race_list = [] self.item_races.clear() for cur_race in self.races: assert isinstance(cur_race, Race) race_list.append(str(cur_race.data.get_start_datetime())) self.item_races.addItems(race_list) self.item_races.setCurrentIndex(self.current_race)
class LayoutBox(QGroupBox): def __init__(self, parent=None, size: QSize = QSize(10, 10), lang: LangEnum = LangEnum.ENG, log_handlers: [StreamHandler] = None): self.logger = getLogger(__name__) if log_handlers: for h in log_handlers: self.logger.addHandler(h) self.logger.debug("Initializing") super().__init__(parent) self.setLayout(QVBoxLayout()) self.setMaximumSize(size) self._horizontal_button = QRadioButton(self) self._horizontal_button.clicked.connect(self._horizontal_toggled) self._vertical_button = QRadioButton(self) self._vertical_button.clicked.connect(self._vertical_toggled) self._tiled_button = QRadioButton(self) self._tiled_button.clicked.connect(self._tiled_toggled) self._cascade_button = QRadioButton(self) self._cascade_button.clicked.connect(self._cascade_toggled) self.layout().addWidget(self._horizontal_button) self.layout().addWidget(self._vertical_button) self.layout().addWidget(self._tiled_button) self.layout().addWidget(self._cascade_button) self._layout_callback = None self._strings = dict() self.set_lang(lang) self.logger.debug("Initialized") def set_lang(self, lang: LangEnum) -> None: """ Set the language for this view object. :param lang: The enum for the language. :return None: """ self._strings = strings[lang] self._set_texts() def add_window_layout_handler(self, func: classmethod) -> None: """ Add handler for window layout. :param func: The handler function :return None: """ self._layout_callback = func def _horizontal_toggled(self): self.logger.debug("running") if self._horizontal_button.isChecked(): self._layout_callback("horizontal") self.logger.debug("done") def _vertical_toggled(self): self.logger.debug("running") if self._vertical_button.isChecked(): self._layout_callback("vertical") self.logger.debug("done") def _tiled_toggled(self): self.logger.debug("running") if self._tiled_button.isChecked(): self._layout_callback("tiled") self.logger.debug("done") def _cascade_toggled(self): self.logger.debug("running") if self._cascade_button.isChecked(): self._layout_callback("cascade") self.logger.debug("done") def _set_texts(self) -> None: """ Set the texts of this view item :return None: """ self.logger.debug("running") self.setTitle(self._strings[StringsEnum.LAYOUT]) self._horizontal_button.setText(self._strings[StringsEnum.HORIZONTAL]) self._vertical_button.setText(self._strings[StringsEnum.VERTICAL]) self._tiled_button.setText(self._strings[StringsEnum.TILED]) self._cascade_button.setText(self._strings[StringsEnum.CASCADE]) self.logger.debug("done")
class Music(QMainWindow): def __init__(self): super(Music, self).__init__() self.setGeometry(20, 50, 522, 175) self.setMinimumSize(522, 175) self.setMaximumSize(522, 175) self.setWindowTitle('Muse') self.setWindowIcon(QIcon('arti.PNG')) self.setFont(QFont('Roboto', 12)) palette = QPalette() palette.setColor(palette.Window, QColor('#000000')) palette.setColor(palette.WindowText, QColor('#FFFFFF')) self.setPalette(palette) self.menubar = QMenuBar(self) self.menubar.setGeometry(0, 0, 682, 21) self.menubar.setFont(QFont('Roboto', 10)) self.date_menu = QMenu(self.menubar) self.date_menu.setTitle(str(datetime.now().strftime('%d-%m-%Y'))) self.setMenuBar(self.menubar) self.menubar.addAction(self.date_menu.menuAction()) self.song = QLineEdit(self) self.song.setPlaceholderText( 'Enter the name of song you want to search for:') self.song.setGeometry(10, 30, 501, 31) self.spotify = QRadioButton(self) self.spotify.setText('Spotify') self.spotify.setGeometry(120, 80, 101, 21) self.gaana = QRadioButton(self) self.gaana.setText('Gaana') self.gaana.setGeometry(330, 80, 91, 21) self.search = QPushButton(self) self.search.setText('Search') self.search.setGeometry(380, 130, 121, 31) self.search.clicked.connect(lambda: self.on_click()) self.search.setCursor(QCursor(Qt.PointingHandCursor)) self.label = QLabel(self) self.label.setGeometry(10, 130, 341, 31) def on_click(self): self.song_search = self.song.text() if self.song.text(): if self.spotify.isChecked(): self.speak('Searching your song on Spotify.') spotify_url = 'https://open.spotify.com/search/' webbrowser.open(spotify_url + self.song_search) elif self.gaana.isChecked(): self.speak('Searching your song on Gaana.') gaana_url = 'https://gaana.com/search/' webbrowser.open(gaana_url + self.song_search) else: self.speak('Please choose either Spotify or Gaana.') else: self.speak('Please type a song name first') self.song.clear() def speak(self, audio): self.engine = pyttsx3.init('sapi5') self.voices = self.engine.getProperty('voices') self.engine.setProperty('voice', self.voices[1].id) self.engine.setProperty('rate', 165) self.engine.say(audio) self.label.setText(audio) self.engine.runAndWait()
class PcaWidget(ToolWidget): def __init__(self, image, parent=None): super(PcaWidget, self).__init__(parent) self.component_combo = QComboBox() self.component_combo.addItems([self.tr(f"#{i + 1}") for i in range(3)]) self.distance_radio = QRadioButton(self.tr("Distance")) self.distance_radio.setToolTip(self.tr("Distance from the closest point on selected component")) self.project_radio = QRadioButton(self.tr("Projection")) self.project_radio.setToolTip(self.tr("Projection onto the selected principal component")) self.crossprod_radio = QRadioButton(self.tr("Cross product")) self.crossprod_radio.setToolTip(self.tr("Cross product between input and selected component")) self.distance_radio.setChecked(True) self.last_radio = self.distance_radio self.invert_check = QCheckBox(self.tr("Invert")) self.invert_check.setToolTip(self.tr("Output bitwise complement")) self.equalize_check = QCheckBox(self.tr("Equalize")) self.equalize_check.setToolTip(self.tr("Apply histogram equalization")) rows, cols, chans = image.shape x = np.reshape(image, (rows * cols, chans)).astype(np.float32) mu, ev, ew = cv.PCACompute2(x, np.array([])) p = np.reshape(cv.PCAProject(x, mu, ev), (rows, cols, chans)) x0 = image.astype(np.float32) - mu self.output = [] for i, v in enumerate(ev): cross = np.cross(x0, v) distance = np.linalg.norm(cross, axis=2) / np.linalg.norm(v) project = p[:, :, i] self.output.extend([norm_mat(distance, to_bgr=True), norm_mat(project, to_bgr=True), norm_img(cross)]) table_data = [ [mu[0, 2], mu[0, 1], mu[0, 0]], [ev[0, 2], ev[0, 1], ev[0, 0]], [ev[1, 2], ev[1, 1], ev[1, 0]], [ev[2, 2], ev[2, 1], ev[2, 0]], [ew[2, 0], ew[1, 0], ew[0, 0]], ] table_widget = QTableWidget(5, 4) table_widget.setHorizontalHeaderLabels([self.tr("Element"), self.tr("Red"), self.tr("Green"), self.tr("Blue")]) table_widget.setItem(0, 0, QTableWidgetItem(self.tr("Mean vector"))) table_widget.setItem(1, 0, QTableWidgetItem(self.tr("Eigenvector 1"))) table_widget.setItem(2, 0, QTableWidgetItem(self.tr("Eigenvector 2"))) table_widget.setItem(3, 0, QTableWidgetItem(self.tr("Eigenvector 3"))) table_widget.setItem(4, 0, QTableWidgetItem(self.tr("Eigenvalues"))) for i in range(len(table_data)): modify_font(table_widget.item(i, 0), bold=True) for j in range(len(table_data[i])): table_widget.setItem(i, j + 1, QTableWidgetItem(str(table_data[i][j]))) # item = QTableWidgetItem() # item.setBackgroundColor(QColor(mu[0, 2], mu[0, 1], mu[0, 0])) # table_widget.setItem(0, 4, item) # table_widget.resizeRowsToContents() # table_widget.resizeColumnsToContents() table_widget.setEditTriggers(QAbstractItemView.NoEditTriggers) table_widget.setSelectionMode(QAbstractItemView.SingleSelection) table_widget.setMaximumHeight(190) self.viewer = ImageViewer(image, image, None) self.process() self.component_combo.currentIndexChanged.connect(self.process) self.distance_radio.clicked.connect(self.process) self.project_radio.clicked.connect(self.process) self.crossprod_radio.clicked.connect(self.process) self.invert_check.stateChanged.connect(self.process) self.equalize_check.stateChanged.connect(self.process) top_layout = QHBoxLayout() top_layout.addWidget(QLabel(self.tr("Component:"))) top_layout.addWidget(self.component_combo) top_layout.addWidget(QLabel(self.tr("Mode:"))) top_layout.addWidget(self.distance_radio) top_layout.addWidget(self.project_radio) top_layout.addWidget(self.crossprod_radio) top_layout.addWidget(self.invert_check) top_layout.addWidget(self.equalize_check) top_layout.addStretch() bottom_layout = QHBoxLayout() bottom_layout.addWidget(table_widget) main_layout = QVBoxLayout() main_layout.addLayout(top_layout) main_layout.addWidget(self.viewer) main_layout.addLayout(bottom_layout) self.setLayout(main_layout) def process(self): index = 3 * self.component_combo.currentIndex() if self.distance_radio.isChecked(): output = self.output[index] self.last_radio = self.distance_radio elif self.project_radio.isChecked(): output = self.output[index + 1] self.last_radio = self.project_radio elif self.crossprod_radio.isChecked(): output = self.output[index + 2] self.last_radio = self.crossprod_radio else: self.last_radio.setChecked(True) return if self.invert_check.isChecked(): output = cv.bitwise_not(output) if self.equalize_check.isChecked(): output = equalize_img(output) self.viewer.update_processed(output)
class NodeInput(QWidget): def __init__(self, content_widget): super(NodeInput, self).__init__() self.content_widget = content_widget self.widget_type = '' # gets specified automatically when creating ui below (see self.widget_combo_box_changed) # create UI # create all layouts self.grid_layout = QGridLayout(self) # move buttons self.up_button = QPushButton(' < ') self.down_button = QPushButton(' > ') # type and label self.type_combo_box = QComboBox(self) self.type_combo_box.addItem('exec') self.type_combo_box.addItem('data') self.type_combo_box.currentTextChanged.connect( self.type_combo_box_changed) self.label_text_edit = QPlainTextEdit(self) self.label_text_edit.setPlaceholderText('Label') self.label_text_edit.setFixedWidth(self.type_combo_box.width()) # self.label_text_edit.setMinimumHeight(20) self.label_text_edit.setMaximumHeight(56) # widget self.widget_grid_layout = QGridLayout() self.widget_yes_no_group_box = QGroupBox(self) self.widget_yes_no_group_box.setLayout(QVBoxLayout()) self.widget_yes_radio_button = QRadioButton('Yes', self) self.widget_yes_radio_button.setChecked(True) self.widget_yes_radio_button.toggled.connect(self.widget_yes_set) self.widget_no_radio_button = QRadioButton('No', self) self.widget_yes_no_group_box.layout().addWidget( self.widget_yes_radio_button) self.widget_yes_no_group_box.layout().addWidget( self.widget_no_radio_button) self.widget_grid_layout.addWidget(self.widget_yes_no_group_box, 0, 0, 4, 1) self.widget_group_box = QGroupBox(self) self.widget_group_box.setLayout(QVBoxLayout()) self.widget_type_combo_box = QComboBox(self) self.widget_type_combo_box.addItem('std line edit') self.widget_type_combo_box.addItem('std spin box') self.widget_type_combo_box.addItem('custom widget') self.widget_type_combo_box.currentTextChanged.connect( self.widget_type_combo_box_changed) self.custom_widget_line_edit = QLineEdit() self.custom_widget_line_edit.setPlaceholderText('input widget name') self.custom_widget_line_edit.editingFinished.connect( self.widget_name_line_edit_edited) self.custom_widget_line_edit.setEnabled(False) self.widget_under_label_radio_button = QRadioButton( 'widget under label') self.widget_under_label_radio_button.setChecked(True) self.widget_besides_label_radio_button = QRadioButton( 'widget besides label') self.widget_group_box.layout().addWidget(self.widget_type_combo_box) self.widget_group_box.layout().addWidget(self.custom_widget_line_edit) self.widget_group_box.layout().addWidget( self.widget_under_label_radio_button) self.widget_group_box.layout().addWidget( self.widget_besides_label_radio_button) self.widget_grid_layout.addWidget(self.widget_group_box, 0, 3, 4, 1) # del button self.del_button = QPushButton(self) self.del_button.setText(' Del ') self.del_button.clicked.connect(self.delete_clicked) # create layout self.grid_layout.addWidget(self.up_button, 0, 0, 1, 1) self.grid_layout.addWidget(self.down_button, 3, 0, 1, 1) self.grid_layout.addWidget(self.type_combo_box, 0, 1) self.grid_layout.addWidget(self.label_text_edit, 1, 1, 3, 1) self.grid_layout.addLayout(self.widget_grid_layout, 0, 2, 4, 1) self.grid_layout.addWidget(self.del_button, 0, 4, 4, 1) def get_type(self): return self.type_combo_box.currentText() def get_label(self): return self.label_text_edit.toPlainText() def has_widget(self): return self.widget_yes_radio_button.isChecked() def set_has_widget(self, has_widget): if has_widget: self.widget_yes_radio_button.setChecked(True) self.widget_no_radio_button.setChecked(False) else: self.widget_yes_radio_button.setChecked(False) self.widget_no_radio_button.setChecked(True) def get_widget_type(self): return self.widget_type_combo_box.currentText() def set_widget_type(self, new_widget_type): self.widget_type_combo_box.setCurrentText(new_widget_type) def get_widget_name(self): return self.content_widget.prepare_class_name( self.custom_widget_line_edit.text()) def set_widget_name(self, name): self.custom_widget_line_edit.setText(name) def get_widget_pos(self): under = self.widget_under_label_radio_button # besides = self.widget_besides_label_radio_button return 'under' if under.isChecked() else 'besides' def set_widget_pos(self, pos): if pos == 'under': self.widget_under_label_radio_button.setChecked(True) self.widget_besides_label_radio_button.setChecked(False) elif pos == 'besides': self.widget_under_label_radio_button.setChecked(False) self.widget_besides_label_radio_button.setChecked(True) def widget_yes_set(self): if self.widget_yes_radio_button.isChecked(): self.widget_group_box.setEnabled(True) else: self.widget_group_box.setEnabled(False) def widget_name_line_edit_edited(self): self.custom_widget_line_edit.setText( self.content_widget.prepare_class_name( self.custom_widget_line_edit.text())) def widget_type_combo_box_changed(self, new_text): self.widget_type = new_text if new_text == 'custom widget': self.custom_widget_line_edit.setEnabled(True) else: self.custom_widget_line_edit.setEnabled(False) def set_type(self, new_type): self.type_combo_box.setCurrentText(new_type) def type_combo_box_changed(self, new_type): if new_type == 'data': self.widget_grid_layout.setEnabled(True) elif new_type == 'exec': self.widget_grid_layout.setEnabled(False) def set_label(self, new_label): self.label_text_edit.setPlainText(new_label) def delete_clicked(self): ret = QMessageBox.warning( self, 'Input', 'Do you really want to delete this input? All changes' 'will be lost.', QMessageBox.Yes, QMessageBox.No) if ret == QMessageBox.Yes: self.content_widget.delete_input(self)
class BrowserWin(QWidget): def __init__(self, *args, **kwargs): super(BrowserWin, self).__init__(*args, **kwargs) # parent Maya window self.setParent(mainWindow) self.setWindowFlags(Qt.Window) # Window settings self.setWindowTitle('AC_AssetBrowser') # Build window self.mainLayout = QVBoxLayout() self.btnLayout = QHBoxLayout() self.radioLayout = QHBoxLayout() # radio buttons load import self.radioLabel = QLabel("Action: ") self.importRadioBtn = QRadioButton("Import File") self.openRadioBtn = QRadioButton("Open File") self.saveRadioBtn = QRadioButton("Save File") # Find asset directories to load from and populate the drop down self.fileType = QComboBox() self.__populate_list(self.fileType) self.curr_cat = self.fileType.currentText() # list of assets in self.list self.fileList = QListWidget() self.fileList.setSelectionMode(QAbstractItemView.ExtendedSelection) self.__populate_list(self.fileList, directory=os.path.join(DIRECTORY, self.curr_cat)) self.fileName = QLineEdit() self.loadBtn = QPushButton("Load Asset") self.publishBtn = QPushButton("Publish") self.closeBtn = QPushButton("Close") # Add widgets to layouts self.radioLayout.addWidget(self.radioLabel) self.radioLayout.addWidget(self.importRadioBtn) self.radioLayout.addWidget(self.openRadioBtn) self.radioLayout.addWidget(self.saveRadioBtn) self.mainLayout.addLayout(self.radioLayout) self.mainLayout.addWidget(self.fileType) self.mainLayout.addWidget(self.fileList) self.mainLayout.addWidget(self.fileName) self.btnLayout.addWidget(self.loadBtn) self.btnLayout.addWidget(self.publishBtn) self.btnLayout.addWidget(self.closeBtn) self.mainLayout.addLayout(self.btnLayout) self.setLayout(self.mainLayout) # Set state of widgets self.importRadioBtn.toggle() self.fileName.setPlaceholderText("file_name") self.fileName.setEnabled(False) self.publishBtn.setEnabled(False) # Signals self.fileType.currentIndexChanged.connect(self.selectionChanged) self.loadBtn.clicked.connect(self.loadBtnCmd) self.publishBtn.clicked.connect(self.publishBtnCmd) self.closeBtn.clicked.connect(self.closeBtnCmd) self.importRadioBtn.toggled.connect(self.onImportToggled) self.openRadioBtn.toggled.connect(self.onOpenToggled) self.saveRadioBtn.toggled.connect(self.onSaveToggled) def __populate_list(self, destination, directory=DIRECTORY): _dirs = os.listdir(directory) _items = [_dir for _dir in _dirs] return destination.addItems(_items) def selectionChanged(self): self.curr_cat = self.fileType.currentText() self.fileList.clear() self.__populate_list(self.fileList, directory=os.path.join(DIRECTORY, self.curr_cat)) def loadBtnCmd(self): if self.importRadioBtn.isChecked(): selected_files = self.fileList.selectedItems() for _file in selected_files: asset_file = os.path.join(DIRECTORY, self.curr_cat, _file.text()) cmds.file(asset_file, i=True) elif self.openRadioBtn.isChecked(): selected_file = self.fileList.currentItem() asset_file = os.path.join(DIRECTORY, self.curr_cat, selected_file.text()) cmds.file(asset_file, o=True, force=True) else: print("Did you mean to publish this asset?") def publishBtnCmd(self): if self.saveRadioBtn.isChecked() and self.fileName.text() is not None: path_to_save = os.path.join(DIRECTORY, self.curr_cat, self.fileName.text()) cmds.file(rn="{}.ma".format(path_to_save)) cmds.file(save=True) self.fileList.clear() self.__populate_list(self.fileList, directory=os.path.join( DIRECTORY, self.curr_cat)) def closeBtnCmd(self): self.close() def onSaveToggled(self): items = self.fileList.selectedItems() for item in items: item.setSelected(False) self.fileName.setEnabled(not self.fileName.isEnabled()) self.publishBtn.setEnabled(not self.publishBtn.isEnabled()) def onImportToggled(self): if self.importRadioBtn.isChecked(): self.fileList.setSelectionMode(QAbstractItemView.ExtendedSelection) def onOpenToggled(self): if self.openRadioBtn.isChecked(): items = self.fileList.selectedItems() items.pop() for item in items: item.setSelected(False) self.fileList.setSelectionMode(QAbstractItemView.SingleSelection)
class MyApp(QMainWindow): def __init__(self, parent=None): super().__init__(parent) self.resize(800, 600) self.setWindowTitle('Simple QtVoila example') # Voila widget self.voila_widget = QtVoila( parent=self, strip_sources=True, ) # Left side layout self.button_run = QPushButton("Run code") self.button_run.clicked.connect(self.pass_code_to_voila_widget) self.check_strip = QCheckBox('Strip code from notebook') self.check_strip.setChecked(True) self.check_strip.clicked.connect(self.change_strip_voila_widget) self.hbox0 = QHBoxLayout() self.hbox0.addWidget(self.button_run) self.hbox0.addWidget(self.check_strip) # Code blocks self.r0 = QRadioButton("Code") self.r0.setChecked(True) self.r1 = QRadioButton("Markdown") self.grp1 = QButtonGroup() self.grp1.addButton(self.r0) self.grp1.addButton(self.r1) self.hbox1 = QHBoxLayout() self.hbox1.addWidget(self.r0) self.hbox1.addWidget(self.r1) self.edit1 = QTextEdit() code1 = """import matplotlib.pyplot as plt %matplotlib inline plt.figure() plt.plot([1,4,6,2,3], '-ok') plt.show()""" self.edit1.insertPlainText(code1) self.r2 = QRadioButton("Code") self.r3 = QRadioButton("Markdown") self.r3.setChecked(True) self.grp2 = QButtonGroup() self.grp2.addButton(self.r2) self.grp2.addButton(self.r3) self.hbox2 = QHBoxLayout() self.hbox2.addWidget(self.r2) self.hbox2.addWidget(self.r3) code2 = "This is a **markdown** text" self.edit2 = QTextEdit(code2) self.r4 = QRadioButton("Code") self.r4.setChecked(True) self.r5 = QRadioButton("Markdown") self.grp3 = QButtonGroup() self.grp3.addButton(self.r4) self.grp3.addButton(self.r5) self.hbox3 = QHBoxLayout() self.hbox3.addWidget(self.r4) self.hbox3.addWidget(self.r5) code3 = """ plt.figure() plt.plot([8,6,7,7,0], '-or') plt.show() """ self.edit3 = QTextEdit(code3) layout_l1 = QVBoxLayout() layout_l1.addLayout(self.hbox0) layout_l1.addLayout(self.hbox1) layout_l1.addWidget(self.edit1) layout_l1.addLayout(self.hbox2) layout_l1.addWidget(self.edit2) layout_l1.addLayout(self.hbox3) layout_l1.addWidget(self.edit3) # Right side layout self.button_load = QPushButton('Load external notebook') self.button_load.clicked.connect(self.open_file) self.button_clear = QPushButton("Clear") self.button_clear.clicked.connect(self.clear) layout_r1 = QVBoxLayout() layout_r1.addWidget(self.button_load) layout_r1.addWidget(self.button_clear) layout_r1.addWidget(self.voila_widget) # Central layout left_w = QWidget() left_w.setLayout(layout_l1) right_w = QWidget() right_w.setLayout(layout_r1) splitter = QSplitter(QtCore.Qt.Horizontal) splitter.addWidget(left_w) splitter.addWidget(right_w) layout_central = QHBoxLayout() layout_central.addWidget(splitter) self.main_widget = QWidget(self) self.main_widget.setLayout(layout_central) self.setCentralWidget(self.main_widget) self.show() def pass_code_to_voila_widget(self): self.voila_widget.external_notebook = None code1 = self.edit1.toPlainText() if self.r0.isChecked(): self.voila_widget.add_notebook_cell(code=code1, cell_type='code') else: self.voila_widget.add_notebook_cell(code=code1, cell_type='markdown') code2 = self.edit2.toPlainText() if self.r2.isChecked(): self.voila_widget.add_notebook_cell(code=code2, cell_type='code') else: self.voila_widget.add_notebook_cell(code=code2, cell_type='markdown') code3 = self.edit3.toPlainText() if self.r4.isChecked(): self.voila_widget.add_notebook_cell(code=code3, cell_type='code') else: self.voila_widget.add_notebook_cell(code=code3, cell_type='markdown') # Run Voila self.voila_widget.run_voila() def change_strip_voila_widget(self): self.voila_widget.strip_sources = self.check_strip.isChecked() def clear(self): self.voila_widget.internal_notebook['cells'] = [] self.voila_widget.close_renderer() def open_file(self): """Opens notebook file.""" filename, _ = QFileDialog.getOpenFileName(None, 'Open file', '', "(*.ipynb)") if filename is not None: self.voila_widget.external_notebook = filename self.clear() self.voila_widget.run_voila()
class ComparisonWidget(ToolWidget): def __init__(self, filename, image, parent=None): super(ComparisonWidget, self).__init__(parent) load_button = QPushButton(self.tr('Load reference image...')) self.comp_label = QLabel(self.tr('Comparison:')) self.normal_radio = QRadioButton(self.tr('Normal')) self.normal_radio.setToolTip(self.tr('Show reference (raw pixels)')) self.normal_radio.setChecked(True) self.difference_radio = QRadioButton(self.tr('Difference')) self.difference_radio.setToolTip( self.tr('Show evidence/reference difference')) self.ssim_radio = QRadioButton(self.tr('SSIM Map')) self.ssim_radio.setToolTip(self.tr('Structure similarity quality map')) self.butter_radio = QRadioButton(self.tr('Butteraugli')) self.butter_radio.setToolTip( self.tr('Butteraugli spatial changes heatmap')) self.gray_check = QCheckBox(self.tr('Grayscale')) self.gray_check.setToolTip(self.tr('Show desaturated output')) self.equalize_check = QCheckBox(self.tr('Equalized')) self.equalize_check.setToolTip(self.tr('Apply histogram equalization')) self.last_radio = self.normal_radio self.metric_button = QPushButton(self.tr('Compute metrics')) self.metric_button.setToolTip( self.tr('Image quality assessment metrics')) self.evidence = image self.reference = self.difference = self.ssim_map = self.butter_map = None basename = os.path.basename(filename) self.evidence_viewer = ImageViewer( self.evidence, None, self.tr('Evidence: {}'.format(basename))) self.reference_viewer = ImageViewer(np.full_like(self.evidence, 127), None, self.tr('Reference')) self.table_widget = QTableWidget(21, 3) self.table_widget.setHorizontalHeaderLabels( [self.tr('Metric'), self.tr('Value'), self.tr('Better')]) self.table_widget.setItem(0, 0, QTableWidgetItem(self.tr('RMSE'))) self.table_widget.setItem( 0, 2, QTableWidgetItem(QIcon('gui/icons/low.svg'), '(0)')) self.table_widget.item(0, 0).setToolTip( self. tr('Root Mean Square Error (RMSE) is commonly used to compare \n' 'the difference between the reference and evidence images \n' 'by directly computing the variation in pixel values. \n' 'The combined image is close to the reference image when \n' 'RMSE value is zero. RMSE is a good indicator of the spectral \n' 'quality of the reference image.')) self.table_widget.setItem(1, 0, QTableWidgetItem(self.tr('SAM'))) self.table_widget.setItem( 1, 2, QTableWidgetItem(QIcon('gui/icons/low.svg'), '(0)')) self.table_widget.item(1, 0).setToolTip( self. tr('It computes the spectral angle between the pixel, vector of the \n' 'evidence image and reference image. It is worked out in either \n' 'degrees or radians. It is performed on a pixel-by-pixel base. \n' 'A SAM equal to zero denotes the absence of spectral distortion.' )) self.table_widget.setItem(2, 0, QTableWidgetItem(self.tr('ERGAS'))) self.table_widget.setItem( 2, 2, QTableWidgetItem(QIcon('gui/icons/low.svg'), '(0)')) self.table_widget.item(2, 0).setToolTip( self. tr('It is used to compute the quality of reference image in terms \n' 'of normalized average error of each band of the reference image. \n' 'Increase in the value of ERGAS indicates distortion in the \n' 'reference image, lower value of ERGAS indicates that it is \n' 'similar to the reference image.')) self.table_widget.setItem(3, 0, QTableWidgetItem(self.tr('MB'))) self.table_widget.setItem( 3, 2, QTableWidgetItem(QIcon('gui/icons/low.svg'), '(0)')) self.table_widget.item(3, 0).setToolTip( self. tr('Mean Bias is the difference between the mean of the evidence \n' 'image and reference image. The ideal value is zero and indicates \n' 'that the evidence and reference images are similar. Mean value \n' 'refers to the grey level of pixels in an image.')) self.table_widget.setItem(4, 0, QTableWidgetItem(self.tr('PFE'))) self.table_widget.setItem( 4, 2, QTableWidgetItem(QIcon('gui/icons/low.svg'), '(0)')) self.table_widget.item(4, 0).setToolTip( self. tr('It computes the norm of the difference between the corresponding \n' 'pixels of the reference and fused image to the norm of the reference \n' 'image. When the calculated value is zero, it indicates that both the \n' 'reference and fused images are similar and value will be increased \n' 'when the merged image is not similar to the reference image.')) self.table_widget.setItem(5, 0, QTableWidgetItem(self.tr('PSNR'))) self.table_widget.setItem( 5, 2, QTableWidgetItem(QIcon('gui/icons/high.svg'), '(+' + u'\u221e' + ')')) self.table_widget.item(5, 0).setToolTip( self. tr('It is widely used metric it is computed by the number of gray levels \n' 'in the image divided by the corresponding pixels in the evidence and \n' 'the reference images. When the value is high, both images are similar.' )) self.table_widget.setItem(6, 0, QTableWidgetItem(self.tr('PSNR-B'))) self.table_widget.setItem( 6, 2, QTableWidgetItem(QIcon('gui/icons/high.svg'), '(+' + u'\u221e' + ')')) self.table_widget.item(6, 0).setToolTip( self.tr('PSNR with Blocking Effect Factor.')) self.table_widget.setItem(7, 0, QTableWidgetItem(self.tr('SSIM'))) self.table_widget.setItem( 7, 2, QTableWidgetItem(QIcon('gui/icons/high.svg'), '(1)')) self.table_widget.item(7, 0).setToolTip( self. tr('SSIM is used to compare the local patterns of pixel intensities between \n' ' the reference and fused images. The range varies between -1 to 1. \n' 'The value 1 indicates the reference and fused images are similar.' )) self.table_widget.setItem(8, 0, QTableWidgetItem(self.tr('MS-SSIM'))) self.table_widget.setItem( 8, 2, QTableWidgetItem(QIcon('gui/icons/high.svg'), '(1)')) self.table_widget.item(8, 0).setToolTip( self.tr('Multiscale version of SSIM.')) self.table_widget.setItem(9, 0, QTableWidgetItem(self.tr('RASE'))) self.table_widget.setItem( 9, 2, QTableWidgetItem(QIcon('gui/icons/low.svg'), '(0)')) self.table_widget.item(9, 0).setToolTip( self.tr('Relative average spectral error')) self.table_widget.setItem(10, 0, QTableWidgetItem(self.tr('SCC'))) self.table_widget.setItem( 10, 2, QTableWidgetItem(QIcon('gui/icons/high.svg'), '(1)')) self.table_widget.item(10, 0).setToolTip( self.tr('Spatial Correlation Coefficient')) self.table_widget.setItem(11, 0, QTableWidgetItem(self.tr('UQI'))) self.table_widget.setItem( 11, 2, QTableWidgetItem(QIcon('gui/icons/high.svg'), '(1)')) self.table_widget.item(11, 0).setToolTip( self.tr('Universal Image Quality Index')) self.table_widget.setItem(12, 0, QTableWidgetItem(self.tr('VIF-P'))) self.table_widget.setItem( 12, 2, QTableWidgetItem(QIcon('gui/icons/high.svg'), '(1)')) self.table_widget.item(12, 0).setToolTip( self.tr('Pixel-based Visual Information Fidelity')) self.table_widget.setItem(13, 0, QTableWidgetItem(self.tr('SSIMulacra'))) self.table_widget.setItem( 13, 2, QTableWidgetItem(QIcon('gui/icons/low.svg'), '(0)')) self.table_widget.item(13, 0).setToolTip( self.tr('Structural SIMilarity Unveiling Local ' 'And Compression Related Artifacts')) self.table_widget.setItem(14, 0, QTableWidgetItem(self.tr('Butteraugli'))) self.table_widget.setItem( 14, 2, QTableWidgetItem(QIcon('gui/icons/low.svg'), '(0)')) self.table_widget.item(14, 0).setToolTip( self.tr('Estimate psychovisual error')) self.table_widget.setItem(15, 0, QTableWidgetItem(self.tr('Correlation'))) self.table_widget.setItem( 15, 2, QTableWidgetItem(QIcon('gui/icons/high.svg'), '(1)')) self.table_widget.item(15, 0).setToolTip(self.tr('Histogram correlation')) self.table_widget.setItem(16, 0, QTableWidgetItem(self.tr('Chi-Square'))) self.table_widget.setItem( 16, 2, QTableWidgetItem(QIcon('gui/icons/low.svg'), '(0)')) self.table_widget.item(16, 0).setToolTip(self.tr('Histogram Chi-Square')) self.table_widget.setItem(17, 0, QTableWidgetItem(self.tr('Chi-Square 2'))) self.table_widget.setItem( 17, 2, QTableWidgetItem(QIcon('gui/icons/low.svg'), '(0)')) self.table_widget.item(17, 0).setToolTip(self.tr('Alternative Chi-Square')) self.table_widget.setItem(18, 0, QTableWidgetItem(self.tr('Intersection'))) self.table_widget.setItem( 18, 2, QTableWidgetItem(QIcon('gui/icons/high.svg'), '(+' + u'\u221e' + ')')) self.table_widget.item(18, 0).setToolTip(self.tr('Histogram intersection')) self.table_widget.setItem(19, 0, QTableWidgetItem(self.tr('Hellinger'))) self.table_widget.setItem( 19, 2, QTableWidgetItem(QIcon('gui/icons/low.svg'), '(0)')) self.table_widget.item(19, 0).setToolTip( self.tr('Histogram Hellinger distance')) self.table_widget.setItem(20, 0, QTableWidgetItem(self.tr('Divergence'))) self.table_widget.setItem( 20, 2, QTableWidgetItem(QIcon('gui/icons/low.svg'), '(0)')) self.table_widget.item(20, 0).setToolTip( self.tr('Kullback-Leibler divergence')) for i in range(self.table_widget.rowCount()): modify_font(self.table_widget.item(i, 0), bold=True) self.table_widget.setSelectionMode(QAbstractItemView.SingleSelection) self.table_widget.setEditTriggers(QAbstractItemView.NoEditTriggers) self.table_widget.resizeColumnsToContents() self.table_widget.setMaximumWidth(250) self.table_widget.setAlternatingRowColors(True) self.stopped = False self.comp_label.setEnabled(False) self.normal_radio.setEnabled(False) self.difference_radio.setEnabled(False) self.ssim_radio.setEnabled(False) self.butter_radio.setEnabled(False) self.gray_check.setEnabled(False) self.equalize_check.setEnabled(False) self.metric_button.setEnabled(False) self.table_widget.setEnabled(False) load_button.clicked.connect(self.load) self.normal_radio.clicked.connect(self.change) self.difference_radio.clicked.connect(self.change) self.butter_radio.clicked.connect(self.change) self.gray_check.stateChanged.connect(self.change) self.equalize_check.stateChanged.connect(self.change) self.ssim_radio.clicked.connect(self.change) self.evidence_viewer.viewChanged.connect( self.reference_viewer.changeView) self.reference_viewer.viewChanged.connect( self.evidence_viewer.changeView) self.metric_button.clicked.connect(self.metrics) top_layout = QHBoxLayout() top_layout.addWidget(load_button) top_layout.addStretch() top_layout.addWidget(self.comp_label) top_layout.addWidget(self.normal_radio) top_layout.addWidget(self.difference_radio) top_layout.addWidget(self.ssim_radio) top_layout.addWidget(self.butter_radio) top_layout.addWidget(self.gray_check) top_layout.addWidget(self.equalize_check) metric_layout = QVBoxLayout() index_label = QLabel(self.tr('Image Quality Assessment')) index_label.setAlignment(Qt.AlignCenter) modify_font(index_label, bold=True) metric_layout.addWidget(index_label) metric_layout.addWidget(self.table_widget) metric_layout.addWidget(self.metric_button) center_layout = QHBoxLayout() center_layout.addWidget(self.evidence_viewer) center_layout.addWidget(self.reference_viewer) center_layout.addLayout(metric_layout) main_layout = QVBoxLayout() main_layout.addLayout(top_layout) main_layout.addLayout(center_layout) self.setLayout(main_layout) def load(self): filename, basename, reference = load_image(self) if filename is None: return if reference.shape != self.evidence.shape: QMessageBox.critical( self, self.tr('Error'), self.tr('Evidence and reference must have the same size!')) return self.reference = reference self.reference_viewer.set_title( self.tr('Reference: {}'.format(basename))) self.difference = norm_mat(cv.absdiff(self.evidence, self.reference)) self.comp_label.setEnabled(True) self.normal_radio.setEnabled(True) self.difference_radio.setEnabled(True) self.ssim_radio.setEnabled(False) self.butter_radio.setEnabled(False) self.gray_check.setEnabled(True) self.equalize_check.setEnabled(True) self.metric_button.setEnabled(True) for i in range(self.table_widget.rowCount()): self.table_widget.setItem(i, 1, QTableWidgetItem()) self.normal_radio.setChecked(True) self.table_widget.setEnabled(False) self.change() def change(self): if self.normal_radio.isChecked(): result = self.reference self.gray_check.setEnabled(False) self.equalize_check.setEnabled(False) self.last_radio = self.normal_radio elif self.difference_radio.isChecked(): result = self.difference self.gray_check.setEnabled(True) self.equalize_check.setEnabled(True) self.last_radio = self.difference_radio elif self.ssim_radio.isChecked(): result = self.ssim_map self.gray_check.setEnabled(False) self.equalize_check.setEnabled(True) self.last_radio = self.ssim_radio elif self.butter_radio.isChecked(): result = self.butter_map self.gray_check.setEnabled(True) self.equalize_check.setEnabled(False) self.last_radio = self.butter_radio else: self.last_radio.setChecked(True) return if self.equalize_check.isChecked(): result = equalize_img(result) if self.gray_check.isChecked(): result = desaturate(result) self.reference_viewer.update_original(result) def metrics(self): progress = QProgressDialog(self.tr('Computing metrics...'), self.tr('Cancel'), 1, self.table_widget.rowCount(), self) progress.canceled.connect(self.cancel) progress.setWindowModality(Qt.WindowModal) img1 = cv.cvtColor(self.evidence, cv.COLOR_BGR2GRAY) img2 = cv.cvtColor(self.reference, cv.COLOR_BGR2GRAY) x = img1.astype(np.float64) y = img2.astype(np.float64) rmse = self.rmse(x, y) progress.setValue(1) if self.stopped: return sam = sewar.sam(img1, img2) progress.setValue(2) if self.stopped: return ergas = sewar.ergas(img1, img2) progress.setValue(3) if self.stopped: return mb = self.mb(x, y) progress.setValue(4) if self.stopped: return pfe = self.pfe(x, y) progress.setValue(5) if self.stopped: return psnr = self.psnr(x, y) progress.setValue(6) if self.stopped: return try: psnrb = sewar.psnrb(img1, img2) except NameError: # FIXME: C'\`e un bug in psnrb (https://github.com/andrewekhalel/sewar/issues/17) psnrb = 0 progress.setValue(7) if self.stopped: return ssim, self.ssim_map = self.ssim(x, y) progress.setValue(8) if self.stopped: return mssim = sewar.msssim(img1, img2).real progress.setValue(9) if self.stopped: return rase = sewar.rase(img1, img2) progress.setValue(10) if self.stopped: return scc = sewar.scc(img1, img2) progress.setValue(11) if self.stopped: return uqi = sewar.uqi(img1, img2) progress.setValue(12) if self.stopped: return vifp = sewar.vifp(img1, img2) progress.setValue(13) if self.stopped: return ssimul = self.ssimul(img1, img2) progress.setValue(14) if self.stopped: return butter, self.butter_map = self.butter(img1, img2) progress.setValue(15) if self.stopped: return sizes = [256, 256, 256] ranges = [0, 256] * 3 channels = [0, 1, 2] hist1 = cv.calcHist([self.evidence], channels, None, sizes, ranges) hist2 = cv.calcHist([self.reference], channels, None, sizes, ranges) correlation = cv.compareHist(hist1, hist2, cv.HISTCMP_CORREL) progress.setValue(16) if self.stopped: return chi_square = cv.compareHist(hist1, hist2, cv.HISTCMP_CHISQR) progress.setValue(17) if self.stopped: return chi_square2 = cv.compareHist(hist1, hist2, cv.HISTCMP_CHISQR_ALT) progress.setValue(18) if self.stopped: return intersection = cv.compareHist(hist1, hist2, cv.HISTCMP_INTERSECT) progress.setValue(19) if self.stopped: return hellinger = cv.compareHist(hist1, hist2, cv.HISTCMP_HELLINGER) progress.setValue(20) if self.stopped: return divergence = cv.compareHist(hist1, hist2, cv.HISTCMP_KL_DIV) progress.setValue(21) self.table_widget.setItem(0, 1, QTableWidgetItem('{:.2f}'.format(rmse))) self.table_widget.setItem(1, 1, QTableWidgetItem('{:.4f}'.format(sam))) self.table_widget.setItem(2, 1, QTableWidgetItem('{:.2f}'.format(ergas))) self.table_widget.setItem(3, 1, QTableWidgetItem('{:.4f}'.format(mb))) self.table_widget.setItem(4, 1, QTableWidgetItem('{:.2f}'.format(pfe))) if psnr > 0: self.table_widget.setItem( 5, 1, QTableWidgetItem('{:.2f} dB'.format(psnr))) else: self.table_widget.setItem( 5, 1, QTableWidgetItem('+' + u'\u221e' + ' dB')) self.table_widget.setItem(6, 1, QTableWidgetItem('{:.2f}'.format(psnrb))) self.table_widget.setItem(7, 1, QTableWidgetItem('{:.4f}'.format(ssim))) self.table_widget.setItem(8, 1, QTableWidgetItem('{:.4f}'.format(mssim))) self.table_widget.setItem(9, 1, QTableWidgetItem('{:.2f}'.format(rase))) self.table_widget.setItem(10, 1, QTableWidgetItem('{:.4f}'.format(scc))) self.table_widget.setItem(11, 1, QTableWidgetItem('{:.4f}'.format(uqi))) self.table_widget.setItem(12, 1, QTableWidgetItem('{:.4f}'.format(vifp))) self.table_widget.setItem(13, 1, QTableWidgetItem('{:.4f}'.format(ssimul))) self.table_widget.setItem(14, 1, QTableWidgetItem('{:.2f}'.format(butter))) self.table_widget.setItem( 15, 1, QTableWidgetItem('{:.2f}'.format(correlation))) self.table_widget.setItem( 16, 1, QTableWidgetItem('{:.2f}'.format(chi_square))) self.table_widget.setItem( 17, 1, QTableWidgetItem('{:.2f}'.format(chi_square2))) self.table_widget.setItem( 18, 1, QTableWidgetItem('{:.2f}'.format(intersection))) self.table_widget.setItem(19, 1, QTableWidgetItem('{:.2f}'.format(hellinger))) self.table_widget.setItem( 20, 1, QTableWidgetItem('{:.2f}'.format(divergence))) self.table_widget.resizeColumnsToContents() self.table_widget.setEnabled(True) self.metric_button.setEnabled(False) self.ssim_radio.setEnabled(True) self.butter_radio.setEnabled(True) def cancel(self): self.stopped = True @staticmethod def rmse(x, y): return np.sqrt(np.mean(np.square(x - y))) @staticmethod def mb(x, y): mx = np.mean(x) my = np.mean(y) return (mx - my) / mx @staticmethod def pfe(x, y): return np.linalg.norm(x - y) / np.linalg.norm(x) * 100 @staticmethod def ssim(x, y): c1 = 6.5025 c2 = 58.5225 k = (11, 11) s = 1.5 x2 = x**2 y2 = y**2 xy = x * y mu_x = cv.GaussianBlur(x, k, s) mu_y = cv.GaussianBlur(y, k, s) mu_x2 = mu_x**2 mu_y2 = mu_y**2 mu_xy = mu_x * mu_y s_x2 = cv.GaussianBlur(x2, k, s) - mu_x2 s_y2 = cv.GaussianBlur(y2, k, s) - mu_y2 s_xy = cv.GaussianBlur(xy, k, s) - mu_xy t1 = 2 * mu_xy + c1 t2 = 2 * s_xy + c2 t3 = t1 * t2 t1 = mu_x2 + mu_y2 + c1 t2 = s_x2 + s_y2 + c2 t1 *= t2 ssim_map = cv.divide(t3, t1) ssim = cv.mean(ssim_map)[0] return ssim, 255 - norm_mat(ssim_map, to_bgr=True) @staticmethod def corr(x, y): return np.corrcoef(x, y)[0, 1] @staticmethod def psnr(x, y): k = np.mean(np.square(x - y)) if k == 0: return -1 return 20 * math.log10((255**2) / k) @staticmethod def butter(x, y): try: exe = butter_exe() if exe is None: raise FileNotFoundError temp_dir = QTemporaryDir() if temp_dir.isValid(): filename1 = os.path.join(temp_dir.path(), 'img1.png') cv.imwrite(filename1, x) filename2 = os.path.join(temp_dir.path(), 'img2.png') cv.imwrite(filename2, y) filename3 = os.path.join(temp_dir.path(), 'map.ppm') p = run([exe, filename1, filename2, filename3], stdout=PIPE) value = float(p.stdout) heatmap = cv.imread(filename3, cv.IMREAD_COLOR) return value, heatmap except FileNotFoundError: return -1, cv.cvtColor(np.full_like(x, 127), cv.COLOR_GRAY2BGR) @staticmethod def ssimul(x, y): try: exe = ssimul_exe() if exe is None: raise FileNotFoundError temp_dir = QTemporaryDir() if temp_dir.isValid(): filename1 = os.path.join(temp_dir.path(), 'img1.png') cv.imwrite(filename1, x) filename2 = os.path.join(temp_dir.path(), 'img2.png') cv.imwrite(filename2, y) p = run([exe, filename1, filename2], stdout=PIPE) value = float(p.stdout) return value except FileNotFoundError: return -1
class ImageViewer(QWidget): viewChanged = Signal(QRect, float, int, int) def __init__(self, original, processed, title=None, parent=None, export=False): super(ImageViewer, self).__init__(parent) if original is None and processed is None: raise ValueError( self.tr('ImageViewer.__init__: Empty image received')) if original is None and processed is not None: original = processed self.original = original self.processed = processed if self.original is not None and self.processed is None: self.view = DynamicView(self.original) else: self.view = DynamicView(self.processed) # view_label = QLabel(self.tr('View:')) self.original_radio = QRadioButton(self.tr('Original')) self.original_radio.setToolTip( self.tr('Show the original image for comparison')) self.process_radio = QRadioButton(self.tr('Processed')) self.process_radio.setToolTip( self.tr('Show result of the current processing')) self.zoom_label = QLabel() full_button = QToolButton() full_button.setText(self.tr('100%')) fit_button = QToolButton() fit_button.setText(self.tr('Fit')) height, width, _ = self.original.shape size_label = QLabel(self.tr('[{}x{} px]'.format(height, width))) export_button = QToolButton() export_button.setToolTip(self.tr('Export current image to PNG')) # export_button.setText(self.tr('Export...')) export_button.setIcon(QIcon('icons/export.svg')) tool_layout = QHBoxLayout() tool_layout.addWidget(QLabel(self.tr('Zoom:'))) tool_layout.addWidget(self.zoom_label) # tool_layout.addWidget(full_button) # tool_layout.addWidget(fit_button) tool_layout.addStretch() if processed is not None: # tool_layout.addWidget(view_label) tool_layout.addWidget(self.original_radio) tool_layout.addWidget(self.process_radio) tool_layout.addStretch() tool_layout.addWidget(size_label) if export or processed is not None: tool_layout.addWidget(export_button) if processed is not None: self.original_radio.setChecked(False) self.process_radio.setChecked(True) self.toggle_mode(False) vert_layout = QVBoxLayout() if title is not None: self.title_label = QLabel(title) modify_font(self.title_label, bold=True) self.title_label.setAlignment(Qt.AlignCenter) vert_layout.addWidget(self.title_label) else: self.title_label = None vert_layout.addWidget(self.view) vert_layout.addLayout(tool_layout) self.setLayout(vert_layout) self.original_radio.toggled.connect(self.toggle_mode) fit_button.clicked.connect(self.view.zoom_fit) full_button.clicked.connect(self.view.zoom_full) export_button.clicked.connect(self.export_image) self.view.viewChanged.connect(self.forward_changed) # view_label.setVisible(processed is not None) # self.original_radio.setVisible(processed is not None) # self.process_radio.setVisible(processed is not None) # export_button.setVisible(processed is not None) # if processed is not None: # # self.adjustSize() def update_processed(self, image): if self.processed is None: return self.processed = image self.toggle_mode(self.original_radio.isChecked()) def update_original(self, image): self.original = image self.toggle_mode(True) def changeView(self, rect, scaling, horizontal, vertical): self.view.change_view(rect, scaling, horizontal, vertical) def forward_changed(self, rect, scaling, horizontal, vertical): self.zoom_label.setText('{:.2f}%'.format(scaling * 100)) modify_font(self.zoom_label, scaling == 1) self.viewChanged.emit(rect, scaling, horizontal, vertical) def get_rect(self): return self.view.get_rect() def keyPressEvent(self, event): if event.key() == Qt.Key_Space: if self.original_radio.isChecked(): self.process_radio.setChecked(True) else: self.original_radio.setChecked(True) QWidget.keyPressEvent(self, event) def toggle_mode(self, toggled): if toggled: self.view.set_image(self.original) elif self.processed is not None: self.view.set_image(self.processed) def export_image(self): settings = QSettings() filename = QFileDialog.getSaveFileName( self, self.tr('Export image...'), settings.value('save_folder'), self.tr('PNG images (*.png)'))[0] if not filename: return if not filename.endswith('.png'): filename += '.png' cv.imwrite( filename, self.processed if self.processed is not None else self.original) def set_title(self, title): if self.title_label is not None: self.title_label.setText(title)
class LCAResultsTab(NewAnalysisTab): """Class for the 'LCA Results' sub-tab. This tab allows the user to get a basic overview of the results of the calculation setup. Shows: 'Overview' and 'by LCIA method' options for different plots/graphs Plots/graphs Export buttons """ def __init__(self, parent=None): super().__init__(parent) self.parent = parent self.lca_scores_widget = LCAScoresTab(parent) self.lca_overview_widget = LCIAResultsTab(parent) self.layout.setAlignment(QtCore.Qt.AlignTop) self.layout.addLayout(get_header_layout('LCA Results')) # buttons button_layout = QHBoxLayout() self.button_group = QButtonGroup() self.button_overview = QRadioButton("Overview") self.button_overview.setToolTip( "Show a matrix of all functional units and all impact categories") button_layout.addWidget(self.button_overview) self.button_by_method = QRadioButton("by LCIA method") self.button_by_method.setToolTip( "Show the impacts of each functional unit for the selected impact categories" ) self.button_by_method.setChecked(True) self.scenario_label = QLabel("Scenario:") self.button_group.addButton(self.button_overview, 0) self.button_group.addButton(self.button_by_method, 1) button_layout.addWidget(self.button_by_method) button_layout.addWidget(self.scenario_label) button_layout.addWidget(self.scenario_box) button_layout.addStretch(1) self.layout.addLayout(button_layout) self.layout.addWidget(self.lca_scores_widget) self.layout.addWidget(self.lca_overview_widget) self.button_clicked(False) self.connect_signals() def connect_signals(self): self.button_overview.toggled.connect(self.button_clicked) if self.using_presamples: self.scenario_box.currentIndexChanged.connect( self.parent.update_scenario_data) self.parent.update_scenario_box_index.connect( lambda index: self.set_combobox_index(self.scenario_box, index )) self.button_by_method.toggled.connect( lambda on_lcia: self.scenario_box.setHidden(on_lcia)) self.button_by_method.toggled.connect( lambda on_lcia: self.scenario_label.setHidden(on_lcia)) @QtCore.Slot(bool, name="overviewToggled") def button_clicked(self, is_overview: bool): self.lca_overview_widget.setVisible(is_overview) self.lca_scores_widget.setHidden(is_overview) def configure_scenario(self): """Allow scenarios options to be visible when used.""" super().configure_scenario() self.scenario_box.setHidden(self.button_by_method.isChecked()) self.scenario_label.setHidden(self.button_by_method.isChecked()) def update_tab(self): """Update the tab.""" self.lca_scores_widget.update_tab() self.lca_overview_widget.update_plot() self.lca_overview_widget.update_table()
class SettingsDialog(CustomDialog): def __init__(self, parent=None): super(SettingsDialog, self).__init__(parent, "Settings") mouse_box = QGroupBox("Mouse", self) mouse_box.setLayout(QVBoxLayout()) scroll_layout = QHBoxLayout() label = QLabel("Scroll objects with mouse wheel:") label.setToolTip( "Select an object and scroll up and down to change its type.") self._scroll_check_box = QCheckBox("Enabled") self._scroll_check_box.setChecked(SETTINGS["object_scroll_enabled"]) self._scroll_check_box.toggled.connect(self._update_settings) scroll_layout.addWidget(label) scroll_layout.addStretch(1) scroll_layout.addWidget(self._scroll_check_box) resize_layout = QHBoxLayout() self.lmb_radio = QRadioButton("Left Mouse Button") rmb_radio = QRadioButton("Right Mouse Button") self.lmb_radio.setChecked(SETTINGS["resize_mode"] == RESIZE_LEFT_CLICK) rmb_radio.setChecked(SETTINGS["resize_mode"] == RESIZE_RIGHT_CLICK) self.lmb_radio.toggled.connect(self._update_settings) radio_group = QButtonGroup() radio_group.addButton(self.lmb_radio) radio_group.addButton(rmb_radio) resize_layout.addWidget(QLabel("Object resize mode:")) resize_layout.addStretch(1) resize_layout.addWidget(self.lmb_radio) resize_layout.addWidget(rmb_radio) mouse_box.layout().addLayout(scroll_layout) mouse_box.layout().addLayout(resize_layout) # emulator command self.emulator_command_input = QLineEdit(self) self.emulator_command_input.setPlaceholderText("Path to emulator") self.emulator_command_input.setText(SETTINGS["instaplay_emulator"]) self.emulator_command_input.textChanged.connect(self._update_settings) self.emulator_path_button = QPushButton(icon("folder.svg"), "", self) self.emulator_path_button.pressed.connect(self._get_emulator_path) self.command_arguments_input = QLineEdit(self) self.command_arguments_input.setPlaceholderText("%f") self.command_arguments_input.setText(SETTINGS["instaplay_arguments"]) self.command_arguments_input.textEdited.connect(self._update_settings) self.command_label = QLabel() command_box = QGroupBox("Emulator", self) command_layout = QVBoxLayout(command_box) command_layout.addWidget(QLabel('Emulator command or "path to exe":')) command_input_layout = QHBoxLayout() command_input_layout.addWidget(self.emulator_command_input) command_input_layout.addWidget(self.emulator_path_button) command_layout.addLayout(command_input_layout) command_layout.addWidget( QLabel("Command arguments (%f will be replaced with rom path):")) command_layout.addWidget(self.command_arguments_input) command_layout.addWidget(QLabel("Command used to play the rom:")) command_layout.addWidget(self.command_label) command_layout.addWidget(HorizontalLine()) command_layout.addWidget( QLabel("Power up of Mario when playing level:")) self.powerup_combo_box = QComboBox() for name, x, y, value, p_wing in POWERUPS: powerup_icon = self._load_from_png(x, y) self.powerup_combo_box.addItem(powerup_icon, name) self.powerup_combo_box.currentIndexChanged.connect( self._update_settings) self.powerup_combo_box.setCurrentIndex(SETTINGS["default_powerup"]) command_layout.addWidget(self.powerup_combo_box) # ---------------------- layout = QVBoxLayout(self) layout.addWidget(mouse_box) layout.addWidget(command_box) self.update() def update(self): self.command_label.setText( f" > {SETTINGS['instaplay_emulator']} {SETTINGS['instaplay_arguments']}" ) def _update_settings(self, _): SETTINGS["instaplay_emulator"] = self.emulator_command_input.text() SETTINGS["instaplay_arguments"] = self.command_arguments_input.text() if self.lmb_radio.isChecked(): SETTINGS["resize_mode"] = RESIZE_LEFT_CLICK else: SETTINGS["resize_mode"] = RESIZE_RIGHT_CLICK SETTINGS["object_scroll_enabled"] = self._scroll_check_box.isChecked() SETTINGS["default_powerup"] = self.powerup_combo_box.currentIndex() self.update() def _get_emulator_path(self): path_to_emulator, _ = QFileDialog.getOpenFileName( self, caption="Select emulator executable") if not path_to_emulator: return self.emulator_command_input.setText(path_to_emulator) @staticmethod def _load_from_png(x: int, y: int) -> QIcon: image = png.copy(QRect(x * 16, y * 16, 16, 16)) mask = image.createMaskFromColor( QColor(*MASK_COLOR).rgb(), Qt.MaskOutColor) image.setAlphaChannel(mask) pixmap = QPixmap.fromImage(image) icon = QIcon(pixmap) return icon def on_exit(self): save_settings() super(SettingsDialog, self).on_exit()