def showColorPicker(self): dialogue = QColorDialog() dialogue.setCurrentColor(self._colour) dialogue.setOption(QColorDialog.ShowAlphaChannel) if dialogue.exec_(): self.setColor(dialogue.currentColor())
def openColorDialog(self, label): dialog = QColorDialog() dialog.setOption(QColorDialog.ShowAlphaChannel, on=True) print(dialog.testOption(dialog.ShowAlphaChannel)) #returning True color = QColorDialog.getColor(options=QColorDialog.ShowAlphaChannel) if color.isValid(): label.setStyleSheet("background-color:" + color.name(QColor.HexArgb) + ";")
def brd(): qcd = QColorDialog(parent=vis.get_main_window()) qcd.setOption(QColorDialog.ShowAlphaChannel) qcd.setWindowFlag(Qt.WindowStaysOnTopHint, True) qcd.setCurrentColor(QColor.fromRgbF(*vis.get_grid_border_color())) qcd.exec() if qcd.result() == 1: vis.set_grid_border_color((qcd.selectedColor().getRgbF()))
def __choose_color(self): dialog = QColorDialog(self.window()) dialog.setOption(QColorDialog.ShowAlphaChannel, True) dialog.setCurrentColor(QColor.fromRgba(self.__color.argb)) if dialog.exec_() == QColorDialog.Accepted: self.__color = Color(dialog.currentColor().rgba()) self.__refresh_label() self.color_changed.emit(self.__color)
def on_user_event(self): colord = QColorDialog()#self._color) colord.setOption(QColorDialog.DontUseNativeDialog) if self._kind == "rgbf": colord.setOption(QColorDialog.ShowAlphaChannel) colord.setCurrentColor(self._color) colord.setCustomColor(0, self._color) if colord.exec(): self.update_color(colord.currentColor())
def colorBtn_clicked(self): colorDialog = QColorDialog() colorDialog.setOption(QColorDialog.ShowAlphaChannel) color = colorDialog.getColor() if color.isValid(): self.frame.setStyleSheet(self.borderColor + ";" + 'background-color: %s' % color.name()) return
def getColor(context, initial, title): if not isLinux: return QColorDialog.getColor(initial=initial, title=title) dlg = QColorDialog(initial, context) dlg.setWindowTitle(title) dlg.setOption(QColorDialog.DontUseNativeDialog) color = QColor() if dlg.exec() == QDialog.Accepted: color = dlg.currentColor() return color
def _doubleClicked(self, index): model = self.model() if model is None: return data = model.data(index) if isinstance(data, QColor): if QApplication.keyboardModifiers() & Qt.AltModifier: model.setData(index, QColor()) else: dialog = QColorDialog(self) dialog.setCurrentColor(data) dialog.setOption(QColorDialog.ShowAlphaChannel) ret = dialog.exec_() if ret: color = dialog.currentColor() model.setData(index, color)
class ColorInput(QPushButton, Input): def __init__(self, dtype): super().__init__(dtype=dtype) self._color_dialog = QColorDialog() self._palette = QPalette() self._init_widget() def set_value(self, value: list): color = QColor.fromRgbF(*value) self._set_display_color(color) self._color_dialog.setCurrentColor(color) def get_gl_value(self) -> np.ndarray: if self._dtype == DataType.Vec3_RGB: return np.array((self._color.getRgbF()[:3]), dtype=np.float32) else: raise TypeError( "Internal type {} not supported for ColorInput!".format( self._dtype)) def get_value(self) -> typing.Any: return self._color def _init_widget(self): self._color_dialog.currentColorChanged.connect( self._current_color_changed) self._color_dialog.setOption(QColorDialog.ShowAlphaChannel, True) self.clicked.connect(self._open_color_dialog) @pyqtSlot(QColor) def _current_color_changed(self, color: QColor): self._set_display_color(color) self.input_changed.emit() def _open_color_dialog(self): self._color_dialog.open() def _set_display_color(self, color: QColor): self._palette.setColor(QPalette.Button, color) self.setAutoFillBackground(True) self.setFlat(True) self.setPalette(self._palette) self.update() self._color = color
def set_color(self): dialog = QColorDialog() dialog.setOption(QColorDialog.ShowAlphaChannel, False) color = dialog.getColor() if color == QColor(): return row = self.label_select.currentIndex() label = self.label_select.model().item(row, 0) label.color = color label.set_icon() for i in range(0, label.rowCount()): shape = label.child(i) shape.set_icon() # Refresh label (for scene reticle etc.) self.label_select.setCurrentIndex(0) self.label_select.setCurrentIndex(row) self.label_select.color_display.update()
def show_color_dialog(self, bg=True): def set_color(color): palette = self.palette() if bg: palette.setColor(QPalette.Active, QPalette.Window, color) palette.setColor(QPalette.Active, QPalette.Base, color) palette.setColor(QPalette.Inactive, QPalette.Window, color) palette.setColor(QPalette.Inactive, QPalette.Base, color) else: palette.setColor(QPalette.Active, QPalette.WindowText, color) palette.setColor(QPalette.Active, QPalette.Text, color) palette.setColor(QPalette.Inactive, QPalette.WindowText, color) palette.setColor(QPalette.Inactive, QPalette.Text, color) self.label.setPalette(palette) self.setPalette(palette) dialog = QColorDialog(self) dialog.currentColorChanged.connect(set_color) dialog.colorSelected.connect(set_color) dialog.setOption(QColorDialog.ShowAlphaChannel, True) dialog.exec()
class PreferencesView(QTabWidget): closed = pyqtSignal() def __init__(self, parent = None): super(PreferencesView, self).__init__(parent) # If QApplication does not exists then don't do anything. if QApplication.instance() is None: logging.warn("No QApplication exists. Won't do anything.") return -1 self.setWindowTitle("Preferences") self.chemicalSimulationDt = self.createFloatingPointEditor() self.chemicalDiffusionDt = self.createFloatingPointEditor() self.chemicalPlotUpdateInterval = self.createFloatingPointEditor() self.chemicalDefaultSimulationRuntime = self.createFloatingPointEditor() self.chemicalGuiUpdateInterval = self.createFloatingPointEditor() self.chemicalSolver = QButtonGroup() self.chemicalSolvers = { "Exponential Euler" : QRadioButton("Exponential Euler") , "Gillespie" : QRadioButton("Gillespie") , "Runge Kutta" : QRadioButton("Runge Kutta") } self.chemicalSimulationApply = QPushButton("Apply") self.chemicalSimulationCancel = QPushButton("Cancel") self.electricalSimulationDt = self.createFloatingPointEditor() self.electricalPlotUpdateInterval = self.createFloatingPointEditor() self.electricalDefaultSimulationRuntime = self.createFloatingPointEditor() self.electricalGuiUpdateInterval = self.createFloatingPointEditor() self.electricalSolver = QButtonGroup() self.electricalSolvers = { "Gillespie" : QRadioButton("Gillespie") , "Runge Kutta" : QRadioButton("Runge Kutta") } self.electricalSimulationApply = QPushButton("Apply") self.electricalSimulationCancel = QPushButton("Cancel") self.electricalVisualizationApply = QPushButton("Apply") self.electricalVisualizationCancel = QPushButton("Cancel") self.electricalBaseColorButton = QPushButton() self.electricalBaseColorDialog = QColorDialog() self.electricalPeakColorButton = QPushButton() self.electricalPeakColorDialog = QColorDialog() self.electricalBackgroundColorButton = QPushButton() self.electricalBackgroundColorDialog = QColorDialog() self.electricalBaseMembraneVoltage = self.createFloatingPointEditor() self.electricalPeakMembraneVoltage = self.createFloatingPointEditor() self.create() def closeEvent(self, event): self.closed.emit() def create(self): # Set up the column titles self.setUsesScrollButtons(True) self.setFocusPolicy(QtCore.Qt.NoFocus) self.addTab( self.createChemicalSettingsTab(), "Chemical") self.addTab( self.createElectricalSettingsTab(), "Electrical") def createChemicalSettingsTab(self): chemicalSettingsTab = QWidget() layout = QGridLayout() chemicalSettingsTab.setLayout(layout) layout.addWidget(QLabel('Simulation dt'), 0, 0) layout.addWidget(self.chemicalSimulationDt, 0, 1) layout.addWidget(QLabel('Diffusion dt'), 1, 0) layout.addWidget(self.chemicalDiffusionDt, 1, 1) layout.addWidget(QLabel('Plot Update Interval'), 2, 0) layout.addWidget(self.chemicalPlotUpdateInterval, 2, 1) layout.addWidget(QLabel('GUI Update Interval'), 3, 0) layout.addWidget(self.chemicalGuiUpdateInterval, 3, 1) # layout.addWidget(QLabel('Default Runtime'), 4, 0) # layout.addWidget(self.chemicalDefaultSimulationRuntime, 4, 1) layout.addWidget(QLabel('Solver'), 5, 0) index = 0 for solver in self.chemicalSolvers: layout.addWidget(self.chemicalSolvers[solver], 5 + index, 1) self.chemicalSolver.addButton(self.chemicalSolvers[solver], index) self.chemicalSolvers[solver].setFocusPolicy(QtCore.Qt.NoFocus) index += 1 self.chemicalSolver.setExclusive(True) buttonLayout = QGridLayout() layout.addLayout(buttonLayout, 5 + index, 1) buttonLayout.addWidget(self.chemicalSimulationCancel, 0, 0, Qt.Qt.AlignRight) buttonLayout.addWidget(self.chemicalSimulationApply, 0, 1, Qt.Qt.AlignLeft) return chemicalSettingsTab def createElectricalSettingsTab(self): electricalSettingsTab = QTabWidget() electricalSettingsTab.addTab( self.createElectricalSimulationSettingsTab() , "Simulation" ) electricalSettingsTab.addTab( self.createElectricalSimulationVisualizationTab() , "Visualization" ) electricalSettingsTab.setTabPosition(QTabWidget.East) electricalSettingsTab.setTabShape(QTabWidget.Triangular) electricalSettingsTab.setDocumentMode(True) electricalSettingsTab.setUsesScrollButtons(True) electricalSettingsTab.setFocusPolicy(QtCore.Qt.NoFocus) return electricalSettingsTab def createElectricalSimulationSettingsTab(self): widget = QWidget() layout = QGridLayout() widget.setLayout(layout) layout.addWidget(QLabel('Simulation dt'), 0, 0) layout.addWidget(self.electricalSimulationDt, 0, 1) layout.addWidget(QLabel('Plot Update Interval'), 2, 0) layout.addWidget(self.electricalPlotUpdateInterval, 2, 1) layout.addWidget(QLabel('GUI Update Interval'), 3, 0) layout.addWidget(self.electricalGuiUpdateInterval, 3, 1) # layout.addWidget(QLabel('Default Runtime'), 4, 0) # layout.addWidget(self.electricalDefaultSimulationRuntime, 4, 1) # layout.addWidget(QLabel('Solver'), 5, 0) index = 0 for solver in self.electricalSolvers: # layout.addWidget(self.electricalSolvers[solver], 5 + index, 1) self.electricalSolver.addButton(self.electricalSolvers[solver], index) self.electricalSolvers[solver].setFocusPolicy(QtCore.Qt.NoFocus) index += 1 self.electricalSolver.setExclusive(True) buttonLayout = QGridLayout() layout.addLayout(buttonLayout, 5 + index, 1) buttonLayout.addWidget(self.electricalSimulationCancel, 0, 0, Qt.Qt.AlignRight) buttonLayout.addWidget(self.electricalSimulationApply, 0, 1, Qt.Qt.AlignLeft) return widget def createElectricalSimulationVisualizationTab(self): widget = QWidget() layout = QGridLayout() widget.setLayout(layout) layout.addWidget(QLabel('Base Membrane Voltage'), 1, 0) layout.addWidget(self.electricalBaseMembraneVoltage, 1, 1) layout.addWidget(QLabel('Base Compartment Color'), 2, 0) self.electricalBaseColorDialog.setOption(QColorDialog.ShowAlphaChannel, True) layout.addWidget(self.electricalBaseColorButton, 2, 1) self.electricalBaseColorButton.clicked.connect(self.electricalBaseColorDialog.show) self.electricalBaseColorButton.setFocusPolicy(QtCore.Qt.NoFocus) self.electricalBaseColorDialog.colorSelected.connect( lambda color: self.electricalBaseColorButton.setStyleSheet( "QPushButton {" + "background-color: {0}; color: {0};".format(color.name()) + "}" ) ) layout.addWidget(QLabel('Peak Membrane Voltage'), 3, 0) layout.addWidget(self.electricalPeakMembraneVoltage, 3, 1) layout.addWidget(QLabel('Peak Compartment Color'), 4, 0) self.electricalPeakColorDialog.setOption(QColorDialog.ShowAlphaChannel, True) layout.addWidget(self.electricalPeakColorButton, 4, 1) self.electricalPeakColorButton.clicked.connect(self.electricalPeakColorDialog.show) self.electricalPeakColorButton.setFocusPolicy(QtCore.Qt.NoFocus) self.electricalPeakColorDialog.colorSelected.connect( lambda color: self.electricalPeakColorButton.setStyleSheet( "QPushButton {" + "background-color: {0}; color: {0};".format(color.name()) + "}" ) ) layout.addWidget(QLabel('Background Color'), 5, 0) self.electricalBackgroundColorDialog.setOption(QColorDialog.ShowAlphaChannel, True) layout.addWidget(self.electricalBackgroundColorButton, 5, 1) self.electricalBackgroundColorButton.clicked.connect(self.electricalBackgroundColorDialog.show) self.electricalBackgroundColorButton.setFocusPolicy(QtCore.Qt.NoFocus) self.electricalBackgroundColorDialog.colorSelected.connect( lambda color: self.electricalBackgroundColorButton.setStyleSheet( "QPushButton {" + "background-color: {0}; color: {0};".format(color.name()) + "}" ) ) buttonLayout = QGridLayout() layout.addLayout(buttonLayout, 6, 1) buttonLayout.addWidget(self.electricalVisualizationCancel, 0, 0, Qt.Qt.AlignRight) buttonLayout.addWidget(self.electricalVisualizationApply, 0, 1, Qt.Qt.AlignLeft) return widget def createFloatingPointEditor(self, value = 0.0, minValue = float("-inf"), maxValue = float("+inf"), decimals = 1000): floatingPointEditor = QLineEdit(str(value)) floatingPointEditor.setValidator(QDoubleValidator(minValue, maxValue, decimals)) return floatingPointEditor
def getDlgClr(self,default): dlg = QColorDialog(QColor(default),self) dlg.setOption(QColorDialog.ShowAlphaChannel, on=True) if dlg.exec() == 1: return dlg.selectedColor().name(QColor.HexArgb) else: return default
class Threshold: """QGIS Plugin Implementation.""" def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join(self.plugin_dir, 'i18n', 'Threshold3_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) # Declare instance attributes self.actions = [] self.menu = self.tr(u'&Threshold3') self.color_picker = QColorDialog() self.color_picker.setOption(QColorDialog.ShowAlphaChannel, on=True) self.t_0_COLOR = QColor(0, 0, 255) self.t_1_COLOR = QColor(0, 255, 0) self.t_2_COLOR = QColor(255, 0, 0) self.CLEAR = QColor(255, 255, 255, 0) self.layer = None self.fcn = None self.shader = None self.renderer = None self.is_initial = True self.MIN = float("inf") self.MAX = float("-inf") self.precision = 2 self.last_time = time() * 1000 self.render_debounce_timer = QTimer() self.render_debounce_timer.timeout.connect(self.render) self.render_debounce_timer.setSingleShot(True) # TODO: We are going to let the user set this up in a future iteration self.toolbar = self.iface.addToolBar(u'Threshold3') self.toolbar.setObjectName(u'Threshold3') # noinspection PyMethodMayBeStatic def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('Threshold3', message) def add_action(self, icon_path, text, callback, enabled_flag=True, add_to_menu=True, add_to_toolbar=True, status_tip=None, whats_this=None, parent=None): """Add a toolbar icon to the toolbar. :param icon_path: Path to the icon for this action. Can be a resource path (e.g. ':/plugins/foo/bar.png') or a normal file system path. :type icon_path: str :param text: Text that should be shown in menu items for this action. :type text: str :param callback: Function to be called when the action is triggered. :type callback: function :param enabled_flag: A flag indicating if the action should be enabled by default. Defaults to True. :type enabled_flag: bool :param add_to_menu: Flag indicating whether the action should also be added to the menu. Defaults to True. :type add_to_menu: bool :param add_to_toolbar: Flag indicating whether the action should also be added to the toolbar. Defaults to True. :type add_to_toolbar: bool :param status_tip: Optional text to show in a popup when mouse pointer hovers over the action. :type status_tip: str :param parent: Parent widget for the new action. Defaults None. :type parent: QWidget :param whats_this: Optional text to show in the status bar when the mouse pointer hovers over the action. :returns: The action that was created. Note that the action is also added to self.actions list. :rtype: QAction """ # Create the dialog (after translation) and keep reference self.dlg = ThresholdDialog() icon = QIcon(icon_path) action = QAction(icon, text, parent) action.triggered.connect(callback) action.setEnabled(enabled_flag) if status_tip is not None: action.setStatusTip(status_tip) if whats_this is not None: action.setWhatsThis(whats_this) if add_to_toolbar: self.toolbar.addAction(action) if add_to_menu: self.iface.addPluginToMenu(self.menu, action) self.actions.append(action) return action def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" icon_path = ':/plugins/Threshold3/icon.png' self.add_action( icon_path, text=self.tr( u'Add colored layers according to user-defined thresholds.'), callback=self.run, parent=self.iface.mainWindow()) def unload(self): """Removes the plugin menu item and icon from QGIS GUI.""" for action in self.actions: self.iface.removePluginMenu(self.tr(u'&Threshold3'), action) self.iface.removeToolBarIcon(action) # remove the toolbar del self.toolbar def run(self): """Run method that performs all the real work""" # show the dialog self.dlg.show() self.toggle_widgets(False) self.layer = self.iface.activeLayer() if self.layer is None: self.dlg.header.setText("No layer selected.") self.dlg.header.setStyleSheet("color: #000000;") else: if isinstance(self.layer, QgsRasterLayer) is False: raise TypeError("Expected QgsRasterLayer, got {}".format( type(self.layer))) self.dlg.header.setText("") # Active layer if not hasattr(self.layer, "hasFilter"): self.fcn = QgsColorRampShader() self.fcn.setColorRampType(QgsColorRampShader.Interpolated) self.layer.hasFilter = True else: self.toggle_widgets(True) if self.MAX == float("-inf"): self.startWorker(self.iface, self.layer) # Run the dialog event loop # self.set_values(True) result = self.dlg.exec_() self.dlg.threshold_0_button.clicked.disconnect() self.dlg.threshold_1_button.clicked.disconnect() self.dlg.threshold_2_button.clicked.disconnect() # See if OK was pressed if result: pass # print("OK was pressed.") # Do something useful here - delete the line containing pass and # substitute with your code. else: pass # print("CANCEL was pressed.") def set_values(self, connect=False): self.dlg.precision_spinbox.setMinimum(1) self.dlg.precision_spinbox.setMaximum(5) if connect: self.dlg.precision_spinbox.setValue(2) self.dlg.precision_spinbox.valueChanged.connect( lambda: self.on_changed(None, "precision")) increment = 1.0 / (10**self.precision) self.dlg.doubleSpinBox_b.setSingleStep(increment) self.dlg.doubleSpinBox_1.setSingleStep(increment) self.dlg.doubleSpinBox_2.setSingleStep(increment) self.dlg.doubleSpinBox_3.setSingleStep(increment) self.dlg.doubleSpinBox_b.setDecimals(5) self.dlg.doubleSpinBox_1.setDecimals(5) self.dlg.doubleSpinBox_2.setDecimals(5) self.dlg.doubleSpinBox_3.setDecimals(5) self.dlg.doubleSpinBox_b.setMinimum(0) self.dlg.doubleSpinBox_1.setMinimum(self.MIN) self.dlg.doubleSpinBox_2.setMinimum(self.MIN) self.dlg.doubleSpinBox_3.setMinimum(self.MIN) self.dlg.doubleSpinBox_b.setMaximum(abs(self.MAX - self.MIN)) self.dlg.doubleSpinBox_1.setMaximum(self.MAX) self.dlg.doubleSpinBox_2.setMaximum(self.MAX) self.dlg.doubleSpinBox_3.setMaximum(self.MAX) if connect: self.dlg.doubleSpinBox_b.valueChanged.connect( lambda: self.on_changed(None, "box")) self.dlg.doubleSpinBox_1.valueChanged.connect( lambda: self.on_changed(0, "box")) self.dlg.doubleSpinBox_2.valueChanged.connect( lambda: self.on_changed(1, "box")) self.dlg.doubleSpinBox_3.valueChanged.connect( lambda: self.on_changed(2, "box")) self.dlg.alpha_0_slider.setMinimum(0) self.dlg.alpha_0_slider.setMaximum(255) self.dlg.alpha_1_slider.setMinimum(0) self.dlg.alpha_1_slider.setMaximum(255) self.dlg.alpha_2_slider.setMinimum(0) self.dlg.alpha_2_slider.setMaximum(255) self.dlg.alpha_0_slider.setValue(255) self.dlg.alpha_1_slider.setValue(255) self.dlg.alpha_2_slider.setValue(255) if connect: self.dlg.alpha_0_slider.valueChanged.connect( lambda: self.on_changed(None)) self.dlg.alpha_1_slider.valueChanged.connect( lambda: self.on_changed(None)) self.dlg.alpha_2_slider.valueChanged.connect( lambda: self.on_changed(None)) self.dlg.base_slider.setMinimum(0) # setMaximum throws Error here, and sockets don't get connected # This is why some sliders won't work. # Find out why OverflowError occurs or add self.dlg.base_slider.setMaximum( abs(self.MAX - self.MIN) * (10**self.precision)) self.dlg.base_slider.setValue(0) self.dlg.threshold_0_slider.setMinimum(self.MIN * (10**self.precision)) self.dlg.threshold_0_slider.setMaximum(self.MAX * (10**self.precision)) self.dlg.threshold_1_slider.setMinimum(self.MIN * (10**self.precision)) self.dlg.threshold_1_slider.setMaximum(self.MAX * (10**self.precision)) self.dlg.threshold_2_slider.setMinimum(self.MIN * (10**self.precision)) self.dlg.threshold_2_slider.setMaximum(self.MAX * (10**self.precision)) if connect: self.dlg.base_slider.valueChanged.connect( lambda: self.on_changed("base")) self.dlg.threshold_0_slider.valueChanged.connect( lambda: self.on_changed(0)) self.dlg.threshold_1_slider.valueChanged.connect( lambda: self.on_changed(1)) self.dlg.threshold_2_slider.valueChanged.connect( lambda: self.on_changed(2)) # Turn it on and off again... I don't know why but # connecting and disconnecting these listeners fixes # the double popup problem. self.dlg.threshold_0_button.clicked.connect( lambda: self.on_color_button_clicked(0)) self.dlg.threshold_1_button.clicked.connect( lambda: self.on_color_button_clicked(1)) self.dlg.threshold_2_button.clicked.connect( lambda: self.on_color_button_clicked(2)) self.dlg.threshold_0_button.clicked.disconnect() self.dlg.threshold_1_button.clicked.disconnect() self.dlg.threshold_2_button.clicked.disconnect() self.dlg.threshold_0_button.clicked.connect( lambda: self.on_color_button_clicked(0)) self.dlg.threshold_1_button.clicked.connect( lambda: self.on_color_button_clicked(1)) self.dlg.threshold_2_button.clicked.connect( lambda: self.on_color_button_clicked(2)) self.dlg.threshold_0_color_box.setStyleSheet( "background-color: {}".format(self.t_0_COLOR.name())) self.dlg.threshold_1_color_box.setStyleSheet( "background-color: {}".format(self.t_1_COLOR.name())) self.dlg.threshold_2_color_box.setStyleSheet( "background-color: {}".format(self.t_2_COLOR.name())) pass def render(self): t_0 = self.dlg.threshold_0_slider.value() / (10.0**self.precision) t_1 = self.dlg.threshold_1_slider.value() / (10.0**self.precision) t_2 = self.dlg.threshold_2_slider.value() / (10.0**self.precision) base = self.dlg.base_slider.value() / (10.0**self.precision) lst = [ QgsColorRampShader.ColorRampItem(t_0 - base, self.CLEAR), QgsColorRampShader.ColorRampItem(t_0, self.t_0_COLOR), QgsColorRampShader.ColorRampItem(t_1, self.t_1_COLOR), QgsColorRampShader.ColorRampItem(t_2, self.t_2_COLOR), ] self.fcn = QgsColorRampShader() self.fcn.setColorRampType(QgsColorRampShader.Interpolated) self.fcn.setColorRampItemList(lst) self.shader = QgsRasterShader() self.shader.setRasterShaderFunction(self.fcn) self.renderer = QgsSingleBandPseudoColorRenderer( self.layer.dataProvider(), 1, self.shader) self.layer.setRenderer(self.renderer) self.layer.triggerRepaint() @QtCore.pyqtSlot(bool) def on_color_button_clicked(self, which): print(which) setattr( self, "t_{}_COLOR".format(which), self.color_picker.getColor( getattr(self, "t_{}_COLOR".format(which)))) getattr(self.dlg, "threshold_{}_color_box".format(which)).setStyleSheet( "background-color: {}".format( getattr(self, "t_{}_COLOR".format(which)).name())) self.render() def on_changed(self, which, source=""): if time() * 1000 - self.last_time < 25: return else: self.last_time = time() * 1000 base = self.dlg.doubleSpinBox_b.value() t_0 = self.dlg.doubleSpinBox_1.value() t_1 = self.dlg.doubleSpinBox_2.value() t_2 = self.dlg.doubleSpinBox_3.value() coef = 10**self.precision if source == "box": base = self.dlg.doubleSpinBox_b.value() t_0 = self.dlg.doubleSpinBox_1.value() t_1 = self.dlg.doubleSpinBox_2.value() t_2 = self.dlg.doubleSpinBox_3.value() elif source == "precision": prec = self.dlg.precision_spinbox.value() self.precision = prec # self.dlg.doubleSpinBox_b.setSingleStep(figs) # self.dlg.doubleSpinBox_1.setSingleStep(figs) # self.dlg.doubleSpinBox_2.setSingleStep(figs) # self.dlg.doubleSpinBox_3.setSingleStep(figs) self.set_values() else: base = self.dlg.base_slider.value() / float(coef) t_0 = self.dlg.threshold_0_slider.value() / float(coef) t_1 = self.dlg.threshold_1_slider.value() / float(coef) t_2 = self.dlg.threshold_2_slider.value() / float(coef) alpha_0 = self.dlg.alpha_0_slider.value() alpha_1 = self.dlg.alpha_1_slider.value() alpha_2 = self.dlg.alpha_2_slider.value() self.t_0_COLOR.setAlpha(alpha_0) self.t_1_COLOR.setAlpha(alpha_1) self.t_2_COLOR.setAlpha(alpha_2) #print("Which: {}".format(which)) if which == 0: if t_0 > t_1: t_1 = t_0 self.dlg.threshold_1_slider.setValue(t_1) self.dlg.doubleSpinBox_2.setValue(t_1) if t_1 > t_2: t_2 = t_1 self.dlg.threshold_2_slider.setValue(t_2) self.dlg.doubleSpinBox_3.setValue(t_2) elif which == 1: if t_0 > t_1: t_0 = t_1 self.dlg.threshold_0_slider.setValue(t_0) self.dlg.doubleSpinBox_1.setValue(t_0) if t_1 > t_2: t_2 = t_1 self.dlg.threshold_2_slider.setValue(t_2) self.dlg.doubleSpinBox_3.setValue(t_2) elif which == 2: if t_0 > t_1: t_1 = t_0 self.dlg.threshold_1_slider.setValue(t_1) self.dlg.doubleSpinBox_2.setValue(t_1) if t_1 > t_2: t_1 = t_2 self.dlg.threshold_1_slider.setValue(t_1) self.dlg.doubleSpinBox_2.setValue(t_1) if t_0 > t_2: t_0 = t_2 self.dlg.threshold_1_slider.setValue(t_0) self.dlg.doubleSpinBox_2.setValue(t_0) # if base > t_0: # base = t_0 # self.dlg.base_slider.setValue(base) # self.dlg.doubleSpinBox_b.setValue(base) self.dlg.base_slider.setValue(base * coef) # self.dlg.base_value.setText(str(base)) # self.dlg.threshold_0_value.setText(str(t_0)) # self.dlg.threshold_1_value.setText(str(t_1)) # self.dlg.threshold_2_value.setText(str(t_2)) self.dlg.threshold_0_slider.setValue(t_0 * coef) self.dlg.threshold_1_slider.setValue(t_1 * coef) self.dlg.threshold_2_slider.setValue(t_2 * coef) self.dlg.doubleSpinBox_1.setValue(t_0) self.dlg.doubleSpinBox_2.setValue(t_1) self.dlg.doubleSpinBox_3.setValue(t_2) self.dlg.doubleSpinBox_b.setValue(base) self.dlg.alpha_0_value.setText(str(alpha_0)) self.dlg.alpha_1_value.setText(str(alpha_1)) self.dlg.alpha_2_value.setText(str(alpha_2)) if source == "box": self.render_debounce_timer.start(25) else: self.render_debounce_timer.start(75) def toggle_widgets(self, value): self.dlg.doubleSpinBox_1.setEnabled(value) self.dlg.doubleSpinBox_2.setEnabled(value) self.dlg.doubleSpinBox_3.setEnabled(value) self.dlg.doubleSpinBox_b.setEnabled(value) self.dlg.threshold_0_slider.setEnabled(value) self.dlg.threshold_1_slider.setEnabled(value) self.dlg.threshold_2_slider.setEnabled(value) self.dlg.threshold_0_button.setEnabled(value) self.dlg.threshold_1_button.setEnabled(value) self.dlg.threshold_2_button.setEnabled(value) self.dlg.alpha_0_slider.setEnabled(value) self.dlg.alpha_1_slider.setEnabled(value) self.dlg.alpha_2_slider.setEnabled(value) self.dlg.precision_spinbox.setEnabled(value) def startWorker(self, iface, layer): self.dlg.header.setText("Calculating...") worker = Worker(iface, layer) messageBar = self.iface.messageBar().createMessage( 'Calculating range...', ) progressBar = QProgressBar() progressBar.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) cancelButton = QPushButton() cancelButton.setText('Cancel') cancelButton.clicked.connect(worker.kill) messageBar.layout().addWidget(progressBar) messageBar.layout().addWidget(cancelButton) self.iface.messageBar().pushWidget(messageBar) self.messageBar = messageBar #start the worker in a new thread thread = QThread() worker.moveToThread(thread) worker.finished.connect(self.workerFinished) worker.error.connect(self.workerError) worker.progress.connect(progressBar.setValue) thread.started.connect(worker.run) thread.start() self.thread = thread self.worker = worker pass def workerFinished(self, ret): self.dlg.header.setText("") # clean up the worker and thread self.worker.deleteLater() self.thread.quit() self.thread.wait() self.thread.deleteLater() # remove widget from message bar self.iface.messageBar().popWidget(self.messageBar) if ret is not None: # report the result _min, _max = ret self.MIN = _min self.MAX = _max self.set_values(self.is_initial) self.toggle_widgets(True) self.iface.messageBar().pushMessage( "Worker finished: MAX {}, MIN {}".format(_max, _min)) # self.iface.messageBar().pushMessage('min: {}, max: {}'.format(_min, _max)) else: # notify the user that something went wrong self.iface.messageBar().pushMessage( 'Something went wrong! See the message log for more information.', level=QgsMessageBar.CRITICAL, duration=3) if self.is_initial: self.is_initial = False def workerError(self, e, exception_string): raise Exception("workerError {}".format(exception_string))
class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowFlags( #stay on top so it always appears visibly when we active with keyboard shortcut QtCore.Qt.WindowStaysOnTopHint | #we want to have minimal top bar so it looks clean, but still be resizable so not a frameless window QtCore.Qt.CustomizeWindowHint) #initialise starting state self.showing = False self.dialog = False self.loadDefaultColor() #set window color, position and size self.setStyleSheet("background-color: " + self.color.name() + ";") self.setWindowOpacity(self.color.alpha() / 255) self.oldPos = self.pos() self.setGeometry(0, 0, 500, 500) self.center() #need to show then hide otherwise program just ends if we do nothing self.show() self.hide() #when keyboard shortcut is pressed, show/hide accordingly def on_activate(self): if self.showing: self.hide() else: self.show() self.showing = not self.showing #just puts the window in the centre of the screen def center(self): qr = self.frameGeometry() cp = QDesktopWidget().availableGeometry().center() qr.moveCenter(cp) self.move(qr.topLeft()) #called when a colour is selected in the color dialog def updateColor(self, color): self.show() if color.isValid(): self.setStyleSheet("background-color: " + color.name() + ";") self.setWindowOpacity(color.alpha() / 255) self.color = color self.saveDefaultColor() #saves color to settings.txt so it can be restored when program is next ran def saveDefaultColor(self): with open("settings.txt", "w") as f: s = ",".join([ str(self.color.alpha()), str(self.color.red()), str(self.color.green()), str(self.color.blue()) ]) f.write(s) #load most recent colour from last time def loadDefaultColor(self): with open("settings.txt", "r") as f: s = f.read().split(",") self.color = QtGui.QColor(int(s[1]), int(s[2]), int(s[3])) self.color.setAlpha(int(s[0])) #when color dialog is rejected (cancel is pressed) #need to still reshow the overlay def dialogClosed(self): self.dialog.done(0) self.show() self.showing = True #when we click on the overlay def mousePressEvent(self, event): #if left, we are dragging and moving the overlay if event.button() == Qt.LeftButton: self.oldPos = event.globalPos() #if right, we open color dialog elif event.button() == Qt.RightButton: self.hide() showing = False #initialise and show color dialog, with current colour as default self.dialog = QColorDialog(self) self.dialog.setStyleSheet("background-color: #dddddd;") self.dialog.setOption(QColorDialog.ShowAlphaChannel) self.dialog.reject = self.dialogClosed self.dialog.setCurrentColor(self.color) self.dialog.colorSelected.connect(self.updateColor) self.dialog.show() #when mouse is moved, we move overlay accordingly def mouseMoveEvent(self, event): delta = QPoint(event.globalPos() - self.oldPos) self.move(self.x() + delta.x(), self.y() + delta.y()) self.oldPos = event.globalPos()
class GuiCam(QMainWindow): def __init__(self): super(GuiCam, self).__init__() self.cameras = [] self.cam_sync = True # Create Camera sub_window contents self.list_cameras = QListWidget() self.list_cameras.setAlternatingRowColors(True) self.button_select_camera = QPushButton("Select Camera") # Add availableCameras to a list to be displayed in list widget. # Use QCameraInfo() to auto detected local camera(s) and list available cameras. # cameras = QCameraInfo().availableCameras() # self.init_list(self.list_cameras, [cam.deviceName() for cam in list(cameras)]) # + list(videos)) self.init_list(self.list_cameras, ["Front Camera", "Real Camera"]) # + list(videos)) # dictionary data structure to construct camera filter functions tuning parameters self.functions = {thresholding: [["0: Disable Filter; 1:Active Filter", 1], ["0:gray; 1:Simple Thresholding; 2:Adaptive Thresholding", 0], ["Simple Thresholding: 0:BINARY; 1:BINARY_INV; 2:TRUNC; 3:TOZERO; " "4:TOZERO_INV; 5:THRESH_OTSU", 0], ["Simple Thresholding: Threshold value", 127], ["Kernel", 0]], smoothing: [["0: Disable Filter; 1:Active Filter", 1], ["0:Averaging; 1:Gaussian; 2:Median; 3: Bilateral; 4: De Noise", 0], ["", 0], ["", 0], ["Kernel", 0]], morphology: [["0: Disable Filter; 1:Active Filter", 1], ["0:Erosion; 1:Dilation; 2:Morphology; ", 0], ["Morphology Operator 0:Open;1:Close;2:GRADIENT;3:TOPHAT;4:BLACKHAT", 0], ["morph_element 0:RECT; 1:CROSS; 2:ELLIPSE", 0], ["Kernel", 0]], histograms: [["0: Disable Filter; 1:Active Filter", 1], ["0:Equalization; 1:adaptive equalization; 2:Contrast&Brightness; 3:gamma; " "4:low-light;", 0], ["alpha-contrast", 50], ["beta-brightness", 50], ["", 0]], arithmetic: [["0: Disable Filter; 1:Active Filter", 1], ["", 0], ["Scale", 0], ["alpha-contrast", 50], ["beta-brightness", 50]], transformations: [["0: Disable Filter; 1:Active Filter", 1], ["0:Scaling(select rect); 1:Perspective(by select 4 points); " "2:Affine(by select 3 points);", 0], ["Scaling factor", 0], ["", 0], ["", 0]], extraction: [["0: Disable Filter; 1:Active Filter", 1], ["", 0], ["", 0], ["", 0], ["", 0]], none: [["", 0], ["", 0], ["", 0], ["", 0], ["", 0]], } # hold camera filter functions # data struct: {function: [["description", value],,,]} self.spinbox_tip_value = [] # Camera AI parts self.models = [BarCode, Color, CascadeClassifier, Diff2frame, Diff3frame, Background, Lane, Face, HOGDescriptor, GoodFeature, Tracker, CamShift, Template, ColorShape, Feature, SimpleBlob, Caffe, Tensorflow, Yolo, GrabCut, Model, ] self.spin_boxes = [] # hold camera filter function parameters using spinbox value self.list_functions = QListWidget() self.list_functions.setAlternatingRowColors(True) self.button_select_filter = QPushButton("Select filter") self.dialog_color = QColorDialog() self.camera_contents = QWidget() self.dock_camera = QDockWidget() self.filter_contents = QWidget() self.dock_filter = QDockWidget() self.color_contents = QWidget() self.dock_color = QDockWidget() # Create Model sub_window contents # self.models = [] # hold AI models for objects detecting and tracing self.list_models = QListWidget() self.list_models.setAlternatingRowColors(True) self.button_select_model = QPushButton("Select Model") self.gbox_model = QGroupBox() self.sub_window_models = QMdiSubWindow() self.sub_window_models.setAttribute(Qt.WA_DeleteOnClose) self.sub_window_models.setWindowTitle("AI Model") # Create View sub_window contents self.label_image = QLabel() self.label_image.setAlignment(Qt.AlignTop) self.sub_window_view = QMdiSubWindow() self.sub_window_view.setAttribute(Qt.WA_DeleteOnClose) self.sub_window_view.setWindowTitle("View") # Create Menu Actions self.act_file_open = QAction(QIcon('images/open_file.png'), "Open", self) self.act_file_close = QAction(QIcon('images/close_file.png'), "Close", self) self.act_file_save = QAction(QIcon('images/save_file.png'), "Save", self) self.act_file_record = QAction(QIcon('images/record_file.png'), "Record", self) self.act_file_print = QAction(QIcon('images/print.png'), "Print", self) self.act_file_exit = QAction(QIcon('images/exit.png'), 'Exit', self) self.act_edit_image = QAction(QIcon('images/add_image.png'), "Add image", self) self.act_edit_logo = QAction(QIcon('images/add_logo.png'), "Add logo", self) self.init_ui() def init_ui(self): """ Initialize the window and display its contents to the screen """ # defines the location of the window on computer screen and its # dimensions, width and height. So the window we just started is located # at x=100,; y=100 in the window and has width=1600 and height=800 self.setGeometry(900, 100, 1600, 800) self.setWindowTitle('12.2 – Camera GUI') self.init_menu() self.init_toolbar() self.init_camera() self.init_filter() self.init_color() self.init_model() self.init_window() self.show() @staticmethod def init_list(list_widget, list_widget_items): list_widget.clear() for item_text in list_widget_items: item = QListWidgetItem() item.setText(str(item_text)) list_widget.addItem(item) def init_menu(self): """ Create menu for CVision GUI """ # Create actions for file menu self.act_file_open.setShortcut('Ctrl+O') self.act_file_open.setStatusTip('Open a new image/video') self.act_file_open.triggered.connect(self.open_file) self.act_file_close.setShortcut('Ctrl+E') self.act_file_close.setStatusTip('Close an image/video') self.act_file_close.triggered.connect(self.close_file) self.act_file_save.setShortcut('Ctrl+S') self.act_file_save.setStatusTip('Save image') self.act_file_save.triggered.connect(self.save_file) self.act_file_record.setShortcut('Ctrl+R') self.act_file_record.setStatusTip('Record video') self.act_file_record.triggered.connect(self.record_file) self.act_file_print.setShortcut('Ctrl+P') self.act_file_print.setStatusTip('Print image') self.act_file_print.triggered.connect(self.print) self.act_file_print.setEnabled(False) self.act_file_exit.setShortcut('Ctrl+Q') self.act_file_exit.setStatusTip('Quit program') self.act_file_exit.triggered.connect(self.exit) # Create actions for edit menu self.act_edit_image.setShortcut('Ctrl+A') self.act_edit_image.setStatusTip('Open a blend image') self.act_edit_image.triggered.connect(self.add_image) self.act_edit_logo.setShortcut('Ctrl+L') self.act_edit_logo.setStatusTip('Open a logo image') self.act_edit_logo.triggered.connect(self.add_logo) # Create menu_bar menu_bar = self.menuBar() menu_bar.setNativeMenuBar(False) # Create file menu and add actions file_menu = menu_bar.addMenu('File') file_menu.addAction(self.act_file_open) file_menu.addAction(self.act_file_close) file_menu.addAction(self.act_file_save) file_menu.addAction(self.act_file_record) file_menu.addSeparator() file_menu.addAction(self.act_file_print) file_menu.addSeparator() file_menu.addAction(self.act_file_exit) # Create edit menu and add actions edit_menu = menu_bar.addMenu('Edit') edit_menu.addAction(self.act_edit_image) edit_menu.addAction(self.act_edit_logo) # Create view menu and add actions view_menu = menu_bar.addMenu('View') view_menu.addAction(self.dock_camera.toggleViewAction()) view_menu.addAction(self.dock_filter.toggleViewAction()) view_menu.addAction(self.dock_color.toggleViewAction()) # Display info about shell, menu, and view in the status bar self.setStatusBar(QStatusBar(self)) def init_toolbar(self): """ Create toolbar for CVision GUI """ tool_bar = QToolBar("Photo Editor Toolbar") tool_bar.setIconSize(QSize(24, 24)) self.addToolBar(tool_bar) # Add actions to toolbar tool_bar.addAction(self.act_file_open) tool_bar.addAction(self.act_file_close) tool_bar.addAction(self.act_file_save) tool_bar.addAction(self.act_file_record) tool_bar.addAction(self.act_file_print) tool_bar.addSeparator() tool_bar.addAction(self.act_edit_image) tool_bar.addAction(self.act_edit_logo) # tool_bar.addAction(self.clear_act) tool_bar.addSeparator() tool_bar.addAction(self.act_file_exit) def open_file(self): """ Open an image file and display its contents in label widget. Display error message if image can't be opened. """ file, _ = QFileDialog.getOpenFileName(self, "Open Image", f"{CWD}//data//Sample//", "Video Files (*.mp4 *.avi );;" "JPG Files (*.jpeg *.jpg );;" "PNG Files (*.png);;" "Bitmap Files (*.bmp);;" "GIF Files (*.gif);;" "All Files (*)") if file: self.select_camera(file) else: QMessageBox.information(self, "Error", "Unable to open image.", QMessageBox.Ok) self.act_file_print.setEnabled(True) def add_image(self): """ Open an image file as back ground blending image. Display error message if image can't be opened. """ for cam in self.cameras: file, _ = QFileDialog.getOpenFileName(self, "Open Image", f"{CWD}//data//Sample//", "JPG Files (*.jpeg *.jpg );;" "PNG Files (*.png);;" "Bitmap Files (*.bmp);;" "GIF Files (*.gif)") if file: cam.image_background = cv2.imread(file) cam.register_filters(rotation, arithmetic) # add image arithmetic algorithm self.spinbox_tip_value = [["0: Disable Filter; 1:Active Filter", 1], ["", 0], ["Switch foreground/background image", 0], ["alpha", 127], ["beta", 50]] self.set_spinbox() else: QMessageBox.information(self, "Error", "Unable to add image.", QMessageBox.Ok) self.button_select_filter.setText(f"Select: Add Image") def add_logo(self): """ Open an image file as back ground blending image. Display error message if image can't be opened. """ for cam in self.cameras: file, _ = QFileDialog.getOpenFileName(self, "Open Logo", f"{CWD}//data//Sample//", "JPG Files (*.jpeg *.jpg );;" "PNG Files (*.png);;" "Bitmap Files (*.bmp);;" "GIF Files (*.gif)") if file: cam.image_logo = cv2.imread(file) # add logo icon cam.register_filters(rotation, arithmetic) # add image arithmetic algorithm self.spinbox_tip_value = [["0: Disable Filter; 1:Active Filter", 1], ["", 0], ["0:THRESH_BINARY; 1:THRESH_BINARY_INV", 0], ["threshold", 230], ["scale", 255]] self.set_spinbox() else: QMessageBox.information(self, "Error", "Unable to open logo image.", QMessageBox.Ok) self.button_select_filter.setText(f"Select: Add Logo") def close_file(self): self.stop_camera() self.cameras.clear() def save_file(self): for cam in self.cameras: cam.save_image(cam.filter_image) def record_file(self): for cam in self.cameras: cam.boolean_record = not cam.boolean_record def print(self): pass def exit(self): self.close_file() self.close() def init_camera(self): # Camera Control Dock layout_vbox_camera = QVBoxLayout() slider_spinbox_direction = SliderSpinBox("Angle", 360, self.update_angle) slider_spinbox_direction.setStatusTip("Rotate image") label_camera = QLabel("Available Cameras") # Create instances of radio buttons radio_sync = QRadioButton("Sync") radio_sync.setChecked(True) radio_sync.setStatusTip("Camera Capture in Main() thread") radio_sync.toggled.connect(lambda: self.radio_toggle(radio_sync)) radio_async = QRadioButton("Async") radio_async.setStatusTip("Camera Capture in respective thread") radio_async.toggled.connect(lambda: self.radio_toggle(radio_async)) # Set up layout and add child widgets to the layout radio_h_box = QHBoxLayout() radio_h_box.addWidget(label_camera) radio_h_box.addStretch() # used to help arrange widgets in a layout manager. radio_h_box.addWidget(radio_sync) radio_h_box.addWidget(radio_async) # Set a specific layout manager inside a parent window or widget radio_contents = QWidget() radio_contents.setLayout(radio_h_box) # Create button that will allow user to select camera self.button_select_camera.clicked.connect(self.select_camera) layout_vbox_camera.addWidget(radio_contents) layout_vbox_camera.addWidget(self.list_cameras) layout_vbox_camera.addWidget(slider_spinbox_direction) layout_vbox_camera.addWidget(self.button_select_camera) # Create child widgets and layout self.camera_contents.setLayout(layout_vbox_camera) def init_filter(self): # Camera Control Dock layout_vbox_filter = QVBoxLayout() label_filter = QLabel("Available Filters") # Set up layout and add child widgets to the layout label_h_filter = QLabel("Filter parameters") filter_h_box = QHBoxLayout() filter_h_box.addWidget(label_h_filter) # create 5 instances of QSpinBox class to hold camera filter function parameters for i in range(5): spinbox = QSpinBox() spinbox.setMaximum(255) spinbox.valueChanged.connect(self.update_filter_param) filter_h_box.addWidget(spinbox) self.spin_boxes.append(spinbox) # Set a specific layout manager inside a parent window or widget filter_contents = QWidget() filter_contents.setLayout(filter_h_box) # Create button that will allow user to select camera filter self.button_select_filter.clicked.connect(self.select_filter) self.button_select_filter.setDisabled(True) layout_vbox_filter.addWidget(label_filter) layout_vbox_filter.addWidget(self.list_functions) layout_vbox_filter.addWidget(filter_contents) # layout_vbox_camera.addWidget(slider_spinbox_filter) layout_vbox_filter.addWidget(self.button_select_filter) # Create child widgets and layout self.filter_contents.setLayout(layout_vbox_filter) def init_color(self): # Color Control Dock layout_vbox_color = QVBoxLayout() slider_spinbox_color = SliderSpinBox("Color %: ", 100, self.update_color_param) slider_spinbox_color.setStatusTip("Blend image background color") # Create instance of QColorDialog widget and pass the image as an argument to RGBSlider self.dialog_color.setOption(QColorDialog.NoButtons) self.dialog_color.currentColorChanged.connect(self.update_color) layout_vbox_color.addWidget(self.dialog_color) layout_vbox_color.addWidget(slider_spinbox_color) # Create child widgets and layout self.color_contents.setLayout(layout_vbox_color) def init_model(self): # Set up list widget that will display identified # models on your computer. label_model = QLabel("Available models") # Create button that will allow user to select model self.button_select_model.clicked.connect(self.select_models) self.button_select_model.setDisabled(True) # Create child widgets and layout for model controls sub_window layout_vbox_model = QVBoxLayout() layout_vbox_model.addWidget(label_model) layout_vbox_model.addWidget(self.list_models) layout_vbox_model.addWidget(self.button_select_model) # Create layout for model controls sub_window self.gbox_model.setTitle("Model Controls") self.gbox_model.setLayout(layout_vbox_model) def init_window(self): """ Set up QMdiArea parent and sub_windows. Add available cameras on local system as items to list widget. """ # Load image in sub_window_view self.load_image("images/chameleon.png") self.sub_window_view.setWidget(self.label_image) self.sub_window_models.setWidget(self.gbox_model) # Create QMdiArea widget to manage sub_windows mdi_area = QMdiArea() mdi_area.tileSubWindows() # mdi_area.addSubWindow(self.sub_window_camera) mdi_area.addSubWindow(self.sub_window_models) mdi_area.addSubWindow(self.sub_window_view) # Set up dock widget self.dock_camera.setWindowTitle("Camera Control") self.dock_camera.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea) self.dock_camera.setWidget(self.camera_contents) self.dock_filter.setWindowTitle("Camera Filter") self.dock_filter.setWidget(self.filter_contents) self.dock_color.setWindowTitle("Camera Color") self.dock_color.setWidget(self.color_contents) self.dock_color.setVisible(False) # Set initial location of dock widget in main window self.addDockWidget(Qt.RightDockWidgetArea, self.dock_camera) self.addDockWidget(Qt.RightDockWidgetArea, self.dock_filter) self.addDockWidget(Qt.RightDockWidgetArea, self.dock_color) # Set mdi_area widget as the central widget of main window self.setCentralWidget(mdi_area) def load_image(self, image): try: with open(image): pixmap = QPixmap(image) self.label_image.setPixmap(pixmap) self.label_image.move(25, 40) except FileNotFoundError: print("Image not found.") def radio_toggle(self, radio): if radio.text() == "Sync" and radio.isChecked(): self.cam_sync = True else: self.cam_sync = False def select_camera(self, name=None): """ Slot for selecting one of the available cameras displayed in list widget. """ def camera(device_name): webcam = WebCam(device=device_name, sync=self.cam_sync) self.cameras.append(webcam) for webcam in self.cameras: webcam.register_filters(rotation, arithmetic, none) # srv = ('127.0.0.1', 61215, '10000000e7268f60') # webcam = WebCam(channel=0, service=srv, device=1, sync=False) # webcam.gui = self webcam.start() webcam.start_show() self.init_list(self.list_functions, [func.__name__ for func in list(self.functions.keys())]) self.button_select_filter.setEnabled(True) self.init_list(self.list_models, [model.name for model in self.models]) self.button_select_model.setEnabled(True) self.load_image("images/chenliru.jpg") try: for cam in self.cameras: cam.stop_show() # stop camera show if there is a camera instance already self.cameras.clear() if self.list_cameras.currentItem() is not None and not name: name = self.list_cameras.currentRow() camera(name) except Exception as e: print(f"No cameras detected {e}.") def stop_camera(self): for cam in self.cameras: cam.stop_show() # stop camera show if there is a camera instance already def select_models(self): """ Slot for selecting one of the available AI models displayed in list widget. """ position = self.list_models.currentRow() ai_model = self.models[position]() for cam in self.cameras: cam.register_models(ai_model) self.button_select_model.setText(f"Select: {ai_model.name}") def select_filter(self): """ Slot for selecting one of the available camera filters displayed in list widget. self.filters = ["log", "gamma", "hist", "yarcb"] """ position = self.list_functions.currentRow() funcs = [*self.functions.keys()] # get keys as list func = funcs[position] for cam in self.cameras: cam.register_filters(rotation, arithmetic, func) self.spinbox_tip_value = [*self.functions.values()][position] # get values as list self.set_spinbox() self.button_select_filter.setText(f"Select: {func.__name__}") def set_spinbox(self): tip = np.array(self.spinbox_tip_value)[:, 0] value = np.array(self.spinbox_tip_value)[:, 1] for i, spinbox in enumerate(self.spin_boxes): spinbox.setValue(int(value[i])) spinbox.setStatusTip(tip[i]) spinbox.setDisabled(True) if tip[i] == "" else spinbox.setEnabled(True) def update_filter_param(self): """ Slot for selecting one of the available camera filters parameters """ # pass for cam in self.cameras: for i in range(5): cam.filter_param[i] = self.spin_boxes[i].value() def update_angle(self, value): """ Slot for selecting one of the available camera installation direction """ for cam in self.cameras: cam.angle = value def update_color_param(self, value): """ Slot for updating camera color parameter. """ for cam in self.cameras: cam.color_param = value def update_color(self): """ Slot for selecting one of the available camera color """ for cam in self.cameras: rgb = list(self.dialog_color.currentColor().getRgb()) cam.color = rgb
class GraphNode(GfxObject, LabeledGfx): DefaultRect = QRectF(-15, -15, 30, 30) DefaultCornerRadius = 7 DefaultInsetPadding = 15 Circle, RoundedRect = range(2) symbolChanged = pyqtSignal(str) def __init__(self, new=True): super().__init__(new) super().__init__(new) self._contextMenu = None self._shape = self.RoundedRect if new: self._insetPadding = self.DefaultInsetPadding self._defaultRect = self.DefaultRect self._cornerRadius = self.DefaultCornerRadius self._arrows = [] self._boundScale = (1.0, 1.0) self._brush = SimpleBrush(Qt.cyan) self._pen = Pen(Qt.yellow, 2.0) self.setupConnections() self.setFiltersChildEvents(True) self._renderHints = QPainter.Antialiasing | QPainter.HighQualityAntialiasing | QPainter.SmoothPixmapTransform self.setAcceptHoverEvents(True) self._hover = False def __setstate__(self, data): super().__setstate__(data) super().__setstate__(data) self._insetPadding = data["inset padding"] self._defaultRect = data["default rect"] self._cornerRadius = data["corner radius"] self._arrows = data["arrows"] self._boundScale = data["bound scale"] self.setupConnections() self.updateArrowsAndClearResidual() def __getstate__(self): data = super().__getstate__() data = {**data, **super().__getstate__()} data["inset padding"] = self._insetPadding data["default rect"] = self._defaultRect data["corner radius"] = self._cornerRadius data["arrows"] = self._arrows data["bound scale"] = self._boundScale return data def __deepcopy__(self, memo): copy = deepcopy(super(), memo) memo[id(self)] = copy copy._shape = self._shape copy._defaultRect = QRectF(self._defaultRect) copy._insetPadding = self._insetPadding copy._cornerRadius = self._cornerRadius copy._arrows = deepcopy(self._arrows, memo) #for arr in copy._arrows: #assert(arr.toNode() is self or arr.fromNode() is self) copy._boundScale = tuple(self._boundScale) copy._brush = deepcopy(self._brush, memo) copy.setupConnections() return copy def hoverEnterEvent(self, event): self._hover = True super().hoverEnterEvent(event) def hoverLeaveEvent(self, event): self._hover = False super().hoverLeaveEvent(event) def sceneEventFilter(self, watched, event): if event.type() == QEvent.GraphicsSceneMouseMove and mag2D( event.scenePos() - event.lastScenePos()) > 1: self.updateArrows() self.scene().update() return False def cornerRadius(self): return self._cornerRadius def setCornerRadius(self, radius): self._cornerRadius = radius self.changed.emit() self.update() def setupConnections(self): self.setFlags(self.ItemIsMovable | self.ItemIsFocusable | self.ItemIsSelectable | self.ItemSendsGeometryChanges) self._brushColorDlg = QColorDialog(self.brush().color()) self._brushColorDlg.setOption(QColorDialog.ShowAlphaChannel, True) self._brushColorDlg.currentColorChanged.connect( lambda col: self.setBrush(SimpleBrush(col))) self._penColorDlg = QColorDialog(self.pen().color()) self._penColorDlg.setOption(QColorDialog.ShowAlphaChannel, True) self._penColorDlg.currentColorChanged.connect( lambda col: self.setPen(setPenColor(self.pen(), col))) def itemChange(self, change, value): if change == self.ItemPositionChange: self.updateArrows() if self.scene(): self.scene().update() return super().itemChange(change, value) def arrows(self): return self._arrows def attachArrow(self, arr): self._arrows.append(arr) self.updateArrows() def detachArrow(self, arr): if arr in self._arrows: self._arrows.remove(arr) self.updateArrows() def boundingRect(self): w = self._insetPadding rect = self.childrenBoundingRect() rect.translate(-rect.center()) rect.adjust(-w, -w, w, w) return rect def setDefaultBoundingRect(self, rect=None): if rect is None: rect = self.DefaultRect self._defaultRect = rect self.changed.emit() self.update() def defaultBoundingRect(self): return self._defaultRect def paint(self, painter, option, widget): if self.scene(): if self.isSelected(): paintSelectionShape(painter, self) painter.setRenderHints(self.renderHints()) painter.setBrush(self.brush()) if self._hover: painter.setPen(self.painterPen()) else: painter.setPen(QPen(Qt.NoPen)) if self._shape == self.RoundedRect: painter.drawRoundedRect(self.boundingRect(), self.cornerRadius(), self.cornerRadius()) elif self._shape == self.Circle: rect = self.boundingRect() if rect.width() > rect.height(): rect.setX(rect.x() - (rect.height() - rect.width()) / 2) rect.setWidth(rect.height()) elif rect.height() > rect.width(): rect.setY(rect.y() - (rect.width() - rect.height()) / 2) rect.setHeight(rect.width()) pen_w = self.pen().width() rect.adjust(pen_w, pen_w, -pen_w, -pen_w) painter.drawEllipse(rect) painter.setPen(QPen(Qt.red, 2.0)) def setRenderHints(self, hints): self._renderHints = hints self.update() def renderHints(self): return self._renderHints def centerChild(self, child): rect = child.boundingRect() center = self.boundingRect().center() delta = center - rect.center() child.setPos(child.pos() + delta) def closestBoundaryPos(self, pos): rect = self.boundingRect() #s = self._boundScale #T = QTransform.fromScale(1/s[0], 1/s[1]) #rect = T.mapRect(rect) if pos.x() < rect.left(): x = rect.left() elif pos.x() > rect.right(): x = rect.right() else: x = pos.x() if pos.y() < rect.top(): y = rect.top() elif pos.y() > rect.bottom(): y = rect.bottom() else: y = pos.y() rect_point = QPointF(x, y) r = self.cornerRadius() poly = None if mag2D(rect_point - rect.bottomRight()) <= r: poly = polygonFromArc(rect.bottomRight() + QPointF(-r, -r), r, 0, 90, seg=30) elif mag2D(rect_point - rect.topRight()) <= r: poly = polygonFromArc(rect.topRight() + QPointF(-r, r), r, 270, 360, seg=30) elif mag2D(rect_point - rect.topLeft()) <= r: poly = polygonFromArc(rect.topLeft() + QPointF(r, r), r, 180, 270, seg=30) elif mag2D(rect_point - rect.bottomLeft()) <= r: poly = polygonFromArc(rect.bottomLeft() + QPointF(r, -r), r, 90, 180, seg=30) if poly is None: return rect_point else: return closestPolyPoint(poly, pos)[0] def updateArrows(self): for arr in self._arrows: arr.updatePosition() def updateArrowsAndClearResidual(self): self.updateArrows() if self.scene(): self.scene().update() def contextMenuEvent(self, event): if self._contextMenu: self._contextMenu.exec_(event.screenPos()) def buildDefaultContextMenu(self, menu=None): if menu is None: menu = QMenu() col_menu = menu.addMenu("Color") col_menu.addAction("Brush").triggered.connect( lambda: self._brushColorDlg.exec_()) col_menu.addAction("Pen").triggered.connect( lambda: self._penColorDlg.exec_()) return menu def setContextMenu(self, menu): self._contextMenu = menu def brush(self): return self._brush def setBrush(self, brush): self._brush = brush self._brushColorDlg.setCurrentColor(brush.color()) self.update() def pen(self): return self._pen def setPen(self, pen): self._pen = pen self._penColorDlg.setCurrentColor(pen.color()) self.update() def saveTextPosition(self): pass def updateTextPosition(self): pass def addLabel(self, label): label = super().addLabel(label) if isinstance(label, TextItem): label.onPositionChanged = self.updateArrowsAndClearResidual return label def updateGraph(self): self.updateArrows() def delete(self, deleted=None): if deleted is None: deleted = {} deleted["arrows"] = [] for arr in self.arrows(): if arr.toNode() is self: arr.setTo(None) deleted["arrows"].append((arr, 1)) else: arr.setFrom(None) deleted["arrows"].append((arr, 0)) super().delete(deleted) return deleted def undelete(self, deleted, emit=True): super().undelete(deleted, emit=False) for arr, isstart in deleted["arrows"]: if isstart == 0: arr.setFrom(self) else: arr.setTo(self) if emit: self.undeleted.emit(self) def setEditable(self, editable): super().setEditable(editable) super().setEditable(editable)
class MainScreen(Screen): colordialog = None colorBox = None html_lbl = None def init(self): self.setWindowTitle('Color Picker!') self.makeMenubar() self.central_widget = self.makeCentralContent() self.setCentralWidget(self.central_widget) self.setWindowIcon( QIcon(os.path.join(Info.IMG_PATH, 'screen-icon.png'))) def makeMenubar(self): exitAction = QAction('Exit', self) exitAction.setShortcut('Ctrl+Q') exitAction.setStatusTip('Exit application') exitAction.triggered.connect(qApp.quit) menubar = self.menuBar() menubar.setNativeMenuBar(False) filemenu = menubar.addMenu('&File') filemenu.addAction(exitAction) menubar.addMenu('&Info') def makeCentralContent(self): wg = QWidget() col = QColor(255, 255, 255) self.colordialog = QColorDialog() self.colorBox = QFrame() self.html_lbl = Label('HTML : ') linedit = QLineEdit() linedit.setReadOnly(True) linedit.setText(col.name()) linedit.mousePressEvent = lambda ev: clipboard.copy(linedit.text()) # self.colordialog.currentColorChanged.connect(self.on_changed_color) self.colordialog.currentColorChanged.connect( lambda: self.on_changed_color(self.colordialog, self.colorBox, linedit)) self.colordialog.setOption(QColorDialog.NoButtons) self.colordialog.setOption(QColorDialog.ShowAlphaChannel) #colordialog.setOption(QColorDialog.DontUseNativeDialog, False) self.colorBox.setStyleSheet('QWidget { background-color: %s }' % col.name()) self.colorBox.setGeometry(0, 0, 100, 100) hbox = QHBoxLayout() hbox.addWidget(self.colordialog) hbox_html = QHBoxLayout() hbox_html.addWidget(self.html_lbl) hbox_html.addWidget(linedit, 1) vbox_colorbox = QVBoxLayout() #vbox_colorbox.addStretch(1) vbox_colorbox.addWidget(self.colorBox, 1) # vbox_colorbox.addStretch(1) vbox_colorbox.addLayout(hbox_html, 1) vbox_colorbox.addStretch(2) hbox.addLayout(vbox_colorbox) vbox = QVBoxLayout() #vbox.addStretch(1) vbox.addLayout(hbox) vbox.addStretch(1) Info.MAIN_SCREEN_WIDTH += self.colordialog.width() Info.MAIN_SCREEN_WIDTH += self.colorBox.width() wg.setLayout(vbox) return wg def on_changed_color(self, dialog, frame, line_edit): color = dialog.currentColor() frame.setStyleSheet('QWidget { background-color: %s }' % color.name()) # print(color.name()) line_edit.setText(color.name())
def createEditor(self, parent: QWidget, option: QStyleOptionViewItem, index: QModelIndex) -> QWidget: color_dialog = QColorDialog()#self.color_by_model_index(index)) color_dialog.setOption(QColorDialog.ShowAlphaChannel) return color_dialog