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) + ";")
Exemple #3
0
 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()))
Exemple #4
0
 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)
Exemple #5
0
 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())
Exemple #6
0
    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
Exemple #7
0
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
Exemple #8
0
 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)
Exemple #9
0
 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)
Exemple #10
0
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
Exemple #11
0
    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()
Exemple #12
0
    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()
Exemple #13
0
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()
Exemple #17
0
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
Exemple #18
0
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)
Exemple #19
0
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