Exemple #1
0
 def update_ui_settings(self):
     ui = self.canvas.ui
     color = QtGui.QColor(ui['point']['color'][0], ui['point']['color'][1],
                          ui['point']['color'][2])
     self.set_active_point_color(color)
     self.spinBoxPointRadius.setValue(ui['point']['radius'])
     color = QtGui.QColor(ui['grid']['color'][0], ui['grid']['color'][1],
                          ui['grid']['color'][2])
     self.set_grid_color(color)
     self.spinBoxGrid.setValue(ui['grid']['size'])
Exemple #2
0
 def addCanvasPolygon(self,
                      ps,
                      color=(0, 0, 0),
                      fill=True,
                      stroke=False,
                      **kwargs):
     polygon = QtGui.QPolygonF()
     for ver in ps:
         polygon.append(QtCore.QPointF(*ver))
     color = [int(c * 255) for c in color]
     pen = QtGui.QPen(QtGui.QColor(*color), 1, PenStile_DashLine)
     self.painter.setPen(pen)
     self.painter.setBrush(QtGui.QColor(0, 0, 0))
     self.painter.drawPolygon(polygon)
Exemple #3
0
 def change_splash_text(txt):
     if len(txt):
         splash.showMessage(
             f"    {txt} ...",
             QtCore.Qt.AlignmentFlag.AlignLeft,
             QtGui.QColor(0x808000),
         )
Exemple #4
0
    def import_metadata(self, file_name):
        file = open(file_name, 'r')
        data = json.load(file)
        file.close()

        # Backward compat
        if 'custom_fields' in data:
            self.custom_fields = data['custom_fields']
        else:
            self.custom_fields = {'fields': [], 'data': {}}
        if 'ui' in data:
            self.ui = data['ui']
        else:
            self.ui = {
                'grid': {
                    'size': 200,
                    'color': [255, 255, 255]
                },
                'point': {
                    'radius': 25,
                    'color': [255, 255, 0]
                }
            }
        # End Backward compat

        self.colors = data['colors']
        for class_name in data['colors']:
            self.colors[class_name] = QtGui.QColor(self.colors[class_name][0],
                                                   self.colors[class_name][1],
                                                   self.colors[class_name][2])
        self.classes = data['classes']
        self.fields_updated.emit(self.custom_fields['fields'])
        self.points_loaded.emit('')
        self.metadata_imported.emit()
Exemple #5
0
    def undo(self):

        if self.iw.measuring_length:
            self.iw._thispos = self.iw._lastpos
            self.iw.L.downdate()  #remove data
            self.iw.line_count += -1
            self.iw.scene.removeItem(self.iw.scene.realline)  #remove graphic
            self.iw.scene.realline = False

        if self.iw.measuring_area:
            self.iw._thispos = self.iw._lastpos
            self.iw.A.downdate()  #remove data
            self.iw.line_count += -1
            self.iw.scene.removeItem(self.iw.scene.realline)  #remove graphic
            self.iw.scene.realline = False

        if self.iw.measuring_widths:
            self.iw.W.downdate()  #remove data
            self.iw.scene.removeItem(self.iw.scene.ellipseItem)  #remove graphic
            self.iw.scene.ellipseItem = False
            self.iw.d[str(self.iw.k)].setPen(
                QtGui.QPen(QtGui.QColor('black')))  #un-highlight next spine
            self.iw.k += -1  #reduce count

        if self.iw.measuring_angle:
            self.iw.T.downdate()  #remove data
            self.iw._thispos = self.iw_lastpos
            self.iw.scene.removeItem(self.iw.scene.realline)  #remove graphic
            self.iw.scene.realline = False
Exemple #6
0
 def display_points(self):
     self.clear_points()
     if self.current_image_name in self.points:
         display_radius = self.ui['point']['radius']
         active_color = QtGui.QColor(self.ui['point']['color'][0],
                                     self.ui['point']['color'][1],
                                     self.ui['point']['color'][2])
         active_brush = QtGui.QBrush(active_color,
                                     QtCore.Qt.BrushStyle.SolidPattern)
         active_pen = QtGui.QPen(active_brush, 2)
         for class_name in self.points[self.current_image_name]:
             points = self.points[self.current_image_name][class_name]
             brush = QtGui.QBrush(self.colors[class_name],
                                  QtCore.Qt.BrushStyle.SolidPattern)
             pen = QtGui.QPen(brush, 2)
             for point in points:
                 if class_name == self.current_class_name:
                     self.addEllipse(
                         QtCore.QRectF(
                             point.x() - ((display_radius - 1) / 2),
                             point.y() - ((display_radius - 1) / 2),
                             display_radius, display_radius), active_pen,
                         active_brush)
                 else:
                     self.addEllipse(
                         QtCore.QRectF(
                             point.x() - ((display_radius - 1) / 2),
                             point.y() - ((display_radius - 1) / 2),
                             display_radius, display_radius), pen, brush)
Exemple #7
0
    def text_add_shadow(self):
        share_url_shadow = QtWidgets.QGraphicsDropShadowEffect()
        share_url_shadow.setBlurRadius(4)
        share_url_shadow.setColor(QtGui.QColor('red'))
        share_url_shadow.setOffset(0)
        self.label_share_url.setGraphicsEffect(share_url_shadow)

        dl_path_shadow = QtWidgets.QGraphicsDropShadowEffect()
        dl_path_shadow.setBlurRadius(4)
        dl_path_shadow.setColor(QtGui.QColor('green'))
        dl_path_shadow.setOffset(0)
        self.label_dl_path.setGraphicsEffect(dl_path_shadow)

        disk_loc_shadow = QtWidgets.QGraphicsDropShadowEffect()
        disk_loc_shadow.setBlurRadius(5)
        disk_loc_shadow.setColor(QtGui.QColor('white'))
        disk_loc_shadow.setOffset(0)
        self.label_disk_loc.setGraphicsEffect(disk_loc_shadow)
    def generate_table(self):
        a = [i for i in range(1, self.spinBox.value() + 1)]
        Ui_Window_2().__class__.a = a
        a_list = ["a{}".format(i) for i in range(1, self.spinBox.value() + 1)]
        temp_list = []
        for i in a:
            for j in range(i, a[-1] + 1):
                temp_list.append((i, j))
        temp_list_2 = sample(temp_list, randint(1, len(temp_list)))
        temp_list_3 = []
        for i in range(len(temp_list_2)):
            temp_list_3.append(randint(0, 1))
        self.relations_dict = dict(zip(temp_list_2, temp_list_3))
        Ui_Window_2().__class__.relations_dict = self.relations_dict
        print(self.relations_dict)

        self.tableWidget.setRowCount(len(a))
        self.tableWidget.setColumnCount(len(a))
        self.tableWidget.clear()
        for i in range(len(a)):
            self.tableWidget.setRowHeight(i, 25)
            self.tableWidget.setColumnWidth(i, 25)
            self.tableWidget.setHorizontalHeaderLabels(a_list)
            self.tableWidget.setVerticalHeaderLabels(a_list)

        for i in self.relations_dict.keys():
            self.tableWidget.setItem(
                i[0] - 1, i[1] - 1,
                QtWidgets.QTableWidgetItem(str(self.relations_dict[i])))
            self.tableWidget.setItem(
                i[1] - 1, i[0] - 1,
                QtWidgets.QTableWidgetItem(str(self.relations_dict[i])))
            if self.relations_dict[i] == 1:
                self.tableWidget.item(i[0] - 1, i[1] - 1).setBackground(
                    QtGui.QColor(0, 190, 0))
                self.tableWidget.item(i[1] - 1, i[0] - 1).setBackground(
                    QtGui.QColor(0, 190, 0))
            else:
                self.tableWidget.item(i[0] - 1, i[1] - 1).setBackground(
                    QtGui.QColor(255, 255, 255))
                self.tableWidget.item(i[1] - 1, i[0] - 1).setBackground(
                    QtGui.QColor(255, 255, 255))
Exemple #9
0
 def addCanvasLine(self, p1, p2, color=(0, 0, 0), color2=None, **kwargs):
     if 'dash' in kwargs:
         line_type = PenStile_DashLine
     else:
         line_type = PenStile_SolidLine
     qp1 = QtCore.QPointF(*p1)
     qp2 = QtCore.QPointF(*p2)
     qpm = QtCore.QPointF((p1[0] + p2[0]) / 2, (p1[1] + p2[1]) / 2)
     if color2 and color2 != color:
         rgb = [int(c * 255) for c in color]
         pen = QtGui.QPen(QtGui.QColor(*rgb), 1, line_type)
         self.painter.setPen(pen)
         self.painter.drawLine(qp1, qpm)
         rgb2 = [int(c * 255) for c in color2]
         pen.setColor(QtGui.QColor(*rgb2))
         self.painter.setPen(pen)
         self.painter.drawLine(qpm, qp2)
     else:
         rgb = [int(c * 255) for c in color]
         pen = QtGui.QPen(QtGui.QColor(*rgb), 1, line_type)
         self.painter.setPen(pen)
         self.painter.drawLine(qp1, qp2)
Exemple #10
0
    def load_points(self, file_name):
        file = open(file_name, 'r')
        self.directory = os.path.split(file_name)[0]
        self.directory_set.emit(self.directory)
        data = json.load(file)
        file.close()
        survey_id = data['metadata']['survey_id']

        # Backward compat
        if 'custom_fields' in data:
            self.custom_fields = data['custom_fields']
        else:
            self.custom_fields = {'fields': [], 'data': {}}
        if 'ui' in data:
            self.ui = data['ui']
        else:
            self.ui = {
                'grid': {
                    'size': 200,
                    'color': [255, 255, 255]
                },
                'point': {
                    'radius': 25,
                    'color': [255, 255, 0]
                }
            }
        # End Backward compat

        self.colors = data['colors']
        self.classes = data['classes']
        self.coordinates = data['metadata']['coordinates']
        self.points = {}
        if 'points' in data:
            self.points = data['points']

        for image in self.points:
            for class_name in self.points[image]:
                for p in range(len(self.points[image][class_name])):
                    point = self.points[image][class_name][p]
                    self.points[image][class_name][p] = QtCore.QPointF(
                        point['x'], point['y'])
        for class_name in data['colors']:
            self.colors[class_name] = QtGui.QColor(self.colors[class_name][0],
                                                   self.colors[class_name][1],
                                                   self.colors[class_name][2])
        self.points_loaded.emit(survey_id)
        self.fields_updated.emit(self.custom_fields['fields'])
        path = os.path.split(file_name)[0]
        if self.points.keys():
            path = os.path.join(path, list(self.points.keys())[0])
            self.load_image(path)
Exemple #11
0
 def display_grid(self):
     self.clear_grid()
     if self.current_image_name and self.show_grid:
         grid_color = QtGui.QColor(self.ui['grid']['color'][0],
                                   self.ui['grid']['color'][1],
                                   self.ui['grid']['color'][2])
         grid_size = self.ui['grid']['size']
         rect = self.itemsBoundingRect()
         brush = QtGui.QBrush(grid_color, QtCore.Qt.BrushStyle.SolidPattern)
         pen = QtGui.QPen(brush, 1)
         for x in range(grid_size, int(rect.width()), grid_size):
             line = QtCore.QLineF(x, 0.0, x, rect.height())
             self.addLine(line, pen)
         for y in range(grid_size, int(rect.height()), grid_size):
             line = QtCore.QLineF(0.0, y, rect.width(), y)
             self.addLine(line, pen)
Exemple #12
0
    def paintEvent(self, event):
        if (not self.m_displayedWhenStopped) and (not self.isAnimated()):
            return

        width = min(self.width(), self.height())

        painter = QPainter(self)
        painter.setRenderHint(QPainter.RenderHint.Antialiasing)

        outerRadius = (width - 1) * 0.5
        innerRadius = (width - 1) * 0.5 * 0.4375

        capsuleHeight = outerRadius - innerRadius
        capsuleWidth = width * 3 / 32
        capsuleRadius = capsuleWidth / 2

        for i in range(0, 12):
            color = QtGui.QColor(self.m_color)

            if self.isAnimated():
                color.setAlphaF(1.0 - (i / 12.0))
            else:
                color.setAlphaF(0.2)

            painter.setPen(Qt.PenStyle.NoPen)
            painter.setBrush(color)
            painter.save()
            painter.translate(self.rect().center())
            painter.rotate(self.m_angle - (i * 30.0))

            width = -1 * capsuleWidth / 2
            height = -1 * (innerRadius + capsuleHeight)

            painter.drawRoundedRect(
                round(width),
                round(height),
                round(capsuleWidth),
                round(capsuleHeight),
                capsuleRadius,
                capsuleRadius,
            )
            painter.restore()
Exemple #13
0
 def addCanvasDashedWedge(self,
                          p1,
                          p2,
                          p3,
                          dash=(2, 2),
                          color=(0, 0, 0),
                          color2=None,
                          **kwargs):
     rgb = [int(c * 255) for c in color]
     pen = QtGui.QPen(QtGui.QColor(*rgb), 1, PenStile_DashLine)
     self.painter.setPen(pen)
     dash = (4, 4)
     pts1 = self._getLinePoints(p1, p2, dash)
     pts2 = self._getLinePoints(p1, p3, dash)
     if len(pts2) < len(pts1):
         pts2, pts1 = pts1, pts2
     for i in range(len(pts1)):
         qp1 = QtCore.QPointF(pts1[i][0], pts1[i][1])
         qp2 = QtCore.QPointF(pts2[i][0], pts2[i][1])
         self.painter.drawLine(qp1, qp2)
Exemple #14
0
 def polyClose(self): #make into hot key not button
     if self.measuring_area:
         if self.line_count > 2: #cant make polygon w/ two lines
             self.measuring_area = False
             A = self.A.calcArea()
             self.areaValues = np.append(self.areaValues, A) #add area values
             #draw permanent polygon
             points = [ QtCore.QPointF(x,y) for x,y in zip( self.A.x, self.A.y ) ]
             self.scene.polyItem2 = QGraphicsPolygonItem(QtGui.QPolygonF(points))
             self.scene.polyItem2.setBrush( QtGui.QBrush(QtGui.QColor(255,255,255,127)) )
             if self.scene.polyItem:
                 self.scene.removeItem(self.scene.polyItem) #remove mouseover polygon
                 self.scene.polyItem = False #remove mouseover polygon
             self.scene.removeItem(self.scene.testline)
             self.scene.testline = False
             self.scene.addItem(self.scene.polyItem2) #shade in polygon
             self.parent().statusbar.showMessage('Polygon area measurement completed')
             self.parent().areaButton.setChecked(False)
             self.parent().bezier.setEnabled(True) #make bezier fit available again
         else:
             print("cannot draw polygon with fewer than three vertices")
Exemple #15
0
 def add_point(self, point):
     if self.current_image_name is not None and self.current_class_name is not None:
         if self.current_class_name not in self.points[
                 self.current_image_name]:
             self.points[self.current_image_name][
                 self.current_class_name] = []
         display_radius = self.ui['point']['radius']
         active_color = QtGui.QColor(self.ui['point']['color'][0],
                                     self.ui['point']['color'][1],
                                     self.ui['point']['color'][2])
         active_brush = QtGui.QBrush(active_color,
                                     QtCore.Qt.BrushStyle.SolidPattern)
         active_pen = QtGui.QPen(active_brush, 2)
         self.points[self.current_image_name][
             self.current_class_name].append(point)
         self.addEllipse(
             QtCore.QRectF(point.x() - ((display_radius - 1) / 2),
                           point.y() - ((display_radius - 1) / 2),
                           display_radius, display_radius), active_pen,
             active_brush)
         self.update_point_count.emit(
             self.current_image_name, self.current_class_name,
             len(self.points[self.current_image_name][
                 self.current_class_name]))
Exemple #16
0
    def __init__(self, parent = None):
        super().__init__(parent = parent)

        # Container Pixmaps # 

        self.setPixmap(qtg.QPixmap(0, 0))
        
        self._master_pixmap = None
        self._original_pixmap = None

        # Pixmap Attributes # 

        self._opacity = 1
        self._max_pixmap_dimension = None
        self._output_changed = False

        # Widget Attributes # 

        self._last_x = None
        self._last_y = None

        self._scroll_quality = 5
        self._pen_size = 10
        self._pen_color = qtg.QColor(0, 0, 0)
Exemple #17
0
 def add_class(self, class_name):
     if class_name not in self.classes:
         self.classes.append(class_name)
         self.classes.sort()
         self.colors[class_name] = QtGui.QColor(QtCore.Qt.GlobalColor.black)
Exemple #18
0
    def mouseMoveEvent(self, event):
        data = self.mapToScene(event.position().toPoint())
        rules = [self.measuring_length, self.measuring_angle, self.measuring_area]

        modifiers = QApplication.keyboardModifiers()
        if modifiers == QtCore.Qt.KeyboardModifier.ShiftModifier and self.oldPos:
            QApplication.setOverrideCursor(QtCore.Qt.CursorShape.OpenHandCursor)
            self.newPos = data
            delta = self.newPos - self.oldPos
            self.translate(delta.x(), delta.y())
        elif (any(rules) or self.measuring_widths):
            QApplication.setOverrideCursor(QtCore.Qt.CursorShape.CrossCursor)  #change cursor
        else:
            QApplication.setOverrideCursor(QtCore.Qt.CursorShape.ArrowCursor)  #change cursor   

        #dragging line
        if self._thispos and any(rules):
            if self.measuring_length:
                self.parent().statusbar.showMessage(
                    'Click to place next point... double click to finish')
            if self.measuring_area:
                self.parent().statusbar.showMessage(
                    'Click to place next point... close polygon to finish')
            if self.measuring_angle:
                self.parent().statusbar.showMessage(
                    'Click point to define vector')

            end = QtCore.QPointF(data)#self.mapToScene(event.pos()))
            start = self._thispos

            if self.measuring_angle and self._lastpos:
                start = self._thispos

            if self.scene.testline:  #remove old line
                self.scene.removeItem(self.scene.testline)
                self.scene.testline = False

            if self.measuring_area and self.line_count > 2:
                intersect, xi, yi, k = self.A.checkIntersect(data.x(),data.y())
                if self.scene.area_ellipseItem: #remove existing intersect
                    self.scene.removeItem(self.scene.area_ellipseItem)
                    self.scene.area_ellipseItem = False
                if self.scene.polyItem:
                    self.scene.removeItem(self.scene.polyItem)
                    self.scene.polyItem = False
                if intersect:
                    #indicate intersect point
                    p = QtCore.QPointF(xi, yi)
                    self.scene.area_ellipseItem = QGraphicsEllipseItem(0, 0, 10, 10)
                    self.scene.area_ellipseItem.setPos(p.x() - 10 / 2, p.y() - 10 / 2)
                    self.scene.area_ellipseItem.setBrush(
                    QtGui.QBrush(QtCore.QtColor('blue'))) #, style=QtCore.Qt.BrushStyle.SolidPattern))
                    self.scene.area_ellipseItem.setFlag(
                    QGraphicsItem.GraphicsItemFlag.ItemIgnoresTransformations,
                    False)  #size stays small, but doesnt translate if set to false
                    self.scene.addItem(self.scene.area_ellipseItem)
                    #shade polygon region
                    points = [ QtCore.QPointF(x,y) for x,y in zip( self.A.x[k:], self.A.y[k:] ) ]
                    points.append(QtCore.QPointF(xi,yi))
                    self.scene.polyItem = QGraphicsPolygonItem(QtGui.QPolygonF(points))
                    self.scene.polyItem.setBrush( QtGui.QBrush(QtGui.QColor(255,255,255,127)) )
                    self.scene.addItem(self.scene.polyItem)

            self.scene.testline = QGraphicsLineItem(QtCore.QLineF(start, end))
            self.scene.addItem(self.scene.testline)
Exemple #19
0
class QProgressIndicator(QtWidgets.QWidget):
    """
    A macOS style spinning progress indicator. ``QProgressIndicator`` automatically
    detects and adjusts to 'dark mode' appearances.
    """

    m_angle = None
    m_timerId = None
    m_delay = None
    m_displayedWhenStopped = None
    m_color = None
    m_light_color = QtGui.QColor(170, 170, 170)
    m_dark_color = QtGui.QColor(40, 40, 40)

    def __init__(self, parent=None):
        # Call parent class constructor first
        super().__init__(parent)

        # Initialize instance variables
        self.m_angle = 0
        self.m_timerId = -1
        self.m_delay = 5 / 60 * 1000
        self.m_displayedWhenStopped = False
        self.m_color = self.m_dark_color

        self.update_dark_mode()

        # Set size and focus policy
        self.setSizePolicy(
            QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Fixed
        )
        self.setFocusPolicy(Qt.FocusPolicy.NoFocus)

    def animationDelay(self):
        return self.m_delay

    def isAnimated(self):
        return self.m_timerId != -1

    def isDisplayedWhenStopped(self):
        return self.m_displayedWhenStopped

    def getColor(self):
        return self.m_color

    def sizeHint(self):
        return QtCore.QSize(20, 20)

    def startAnimation(self):
        self.m_angle = 0

        if self.m_timerId == -1:
            self.m_timerId = self.startTimer(int(self.m_delay))

    def stopAnimation(self):
        if self.m_timerId != -1:
            self.killTimer(self.m_timerId)

        self.m_timerId = -1
        self.update()

    def setAnimationDelay(self, delay):
        if self.m_timerId != -1:
            self.killTimer(self.m_timerId)

        self.m_delay = delay

        if self.m_timerId != -1:
            self.m_timerId = self.startTimer(self.m_delay)

    def setDisplayedWhenStopped(self, state):
        self.m_displayedWhenStopped = state
        self.update()

    def setColor(self, color):
        self.m_color = color
        self.update()

    def timerEvent(self, event):
        self.m_angle = (self.m_angle + 30) % 360
        self.update()

    def paintEvent(self, event):
        if (not self.m_displayedWhenStopped) and (not self.isAnimated()):
            return

        width = min(self.width(), self.height())

        painter = QPainter(self)
        painter.setRenderHint(QPainter.RenderHint.Antialiasing)

        outerRadius = (width - 1) * 0.5
        innerRadius = (width - 1) * 0.5 * 0.4375

        capsuleHeight = outerRadius - innerRadius
        capsuleWidth = width * 3 / 32
        capsuleRadius = capsuleWidth / 2

        for i in range(0, 12):
            color = QtGui.QColor(self.m_color)

            if self.isAnimated():
                color.setAlphaF(1.0 - (i / 12.0))
            else:
                color.setAlphaF(0.2)

            painter.setPen(Qt.PenStyle.NoPen)
            painter.setBrush(color)
            painter.save()
            painter.translate(self.rect().center())
            painter.rotate(self.m_angle - (i * 30.0))

            width = -1 * capsuleWidth / 2
            height = -1 * (innerRadius + capsuleHeight)

            painter.drawRoundedRect(
                round(width),
                round(height),
                round(capsuleWidth),
                round(capsuleHeight),
                capsuleRadius,
                capsuleRadius,
            )
            painter.restore()

    def changeEvent(self, event):

        if event.type() == QtCore.QEvent.Type.PaletteChange:
            self.update_dark_mode()

    def update_dark_mode(self):
        if is_dark_window():
            self.setColor(self.m_light_color)
        else:
            self.setColor(self.m_dark_color)
Exemple #20
0
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1200, 660)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.tabWidget = QtWidgets.QTabWidget(self.centralwidget)
        self.tabWidget.setGeometry(QtCore.QRect(240, -10, 970, 674))
        self.tabWidget.setMouseTracking(True)
        self.tabWidget.setObjectName("tabWidget")
        self.tab_Home = QtWidgets.QWidget()
        self.tab_Home.setObjectName("tab_Home")
        self.label_Home = QtWidgets.QLabel(self.tab_Home)
        self.label_Home.setGeometry(QtCore.QRect(30, 40, 160, 30))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(18)
        font.setBold(True)
        font.setWeight(75)
        self.label_Home.setFont(font)
        self.label_Home.setStyleSheet("color: rgb(51, 51, 51);")
        self.label_Home.setObjectName("label_Home")
        self.tabWidget.addTab(self.tab_Home, "")
        self.tab_Basic = QtWidgets.QWidget()
        self.tab_Basic.setObjectName("tab_Basic")
        self.label_BasicInfo = QtWidgets.QLabel(self.tab_Basic)
        self.label_BasicInfo.setGeometry(QtCore.QRect(30, 40, 160, 30))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(18)
        font.setBold(True)
        font.setWeight(75)
        self.label_BasicInfo.setFont(font)
        self.label_BasicInfo.setStyleSheet("color: rgb(51, 51, 51);")
        self.label_BasicInfo.setObjectName("label_BasicInfo")
        self.label_Basic_Seperate = QtWidgets.QLabel(self.tab_Basic)
        self.label_Basic_Seperate.setGeometry(QtCore.QRect(30, 110, 140, 30))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(16)
        font.setBold(True)
        font.setWeight(75)
        self.label_Basic_Seperate.setFont(font)
        self.label_Basic_Seperate.setStyleSheet("color: rgb(51, 51, 51);")
        self.label_Basic_Seperate.setObjectName("label_Basic_Seperate")
        self.spinBox_Basic_Seperate = QtWidgets.QSpinBox(self.tab_Basic)
        self.spinBox_Basic_Seperate.setGeometry(QtCore.QRect(
            190, 110, 200, 31))
        self.spinBox_Basic_Seperate.setLayoutDirection(
            QtCore.Qt.LayoutDirection.LeftToRight)
        self.spinBox_Basic_Seperate.setObjectName("spinBox_Basic_Seperate")
        self.label_Basic_Item = QtWidgets.QLabel(self.tab_Basic)
        self.label_Basic_Item.setGeometry(QtCore.QRect(87, 180, 80, 30))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(16)
        font.setBold(True)
        font.setWeight(75)
        self.label_Basic_Item.setFont(font)
        self.label_Basic_Item.setStyleSheet("color: rgb(51, 51, 51);")
        self.label_Basic_Item.setObjectName("label_Basic_Item")
        self.label_Basic_Deadvol = QtWidgets.QLabel(self.tab_Basic)
        self.label_Basic_Deadvol.setGeometry(QtCore.QRect(29, 250, 140, 30))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(16)
        font.setBold(True)
        font.setWeight(75)
        self.label_Basic_Deadvol.setFont(font)
        self.label_Basic_Deadvol.setStyleSheet("color: rgb(51, 51, 51);")
        self.label_Basic_Deadvol.setObjectName("label_Basic_Deadvol")
        self.label_Basic_Control = QtWidgets.QLabel(self.tab_Basic)
        self.label_Basic_Control.setGeometry(QtCore.QRect(46, 320, 120, 30))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(16)
        font.setBold(True)
        font.setWeight(75)
        self.label_Basic_Control.setFont(font)
        self.label_Basic_Control.setStyleSheet("color: rgb(51, 51, 51);")
        self.label_Basic_Control.setObjectName("label_Basic_Control")
        self.lineEdit_Basic_Item = QtWidgets.QLineEdit(self.tab_Basic)
        self.lineEdit_Basic_Item.setGeometry(QtCore.QRect(190, 180, 201, 31))
        self.lineEdit_Basic_Item.setObjectName("lineEdit_Basic_Item")
        self.lineEdit_Basic_Deadvol_ea = QtWidgets.QLineEdit(self.tab_Basic)
        self.lineEdit_Basic_Deadvol_ea.setGeometry(
            QtCore.QRect(190, 250, 61, 31))
        self.lineEdit_Basic_Deadvol_ea.setObjectName(
            "lineEdit_Basic_Deadvol_ea")
        self.label_Basic_Deadvol_ea = QtWidgets.QLabel(self.tab_Basic)
        self.label_Basic_Deadvol_ea.setGeometry(QtCore.QRect(260, 250, 31, 30))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(16)
        font.setBold(False)
        font.setWeight(50)
        self.label_Basic_Deadvol_ea.setFont(font)
        self.label_Basic_Deadvol_ea.setStyleSheet("color: rgb(51, 51, 51);")
        self.label_Basic_Deadvol_ea.setObjectName("label_Basic_Deadvol_ea")
        self.lineEdit_Basic_Deadvol_percent = QtWidgets.QLineEdit(
            self.tab_Basic)
        self.lineEdit_Basic_Deadvol_percent.setGeometry(
            QtCore.QRect(320, 250, 41, 31))
        self.lineEdit_Basic_Deadvol_percent.setObjectName(
            "lineEdit_Basic_Deadvol_percent")
        self.label_Basic_Deadvol_percent = QtWidgets.QLabel(self.tab_Basic)
        self.label_Basic_Deadvol_percent.setGeometry(
            QtCore.QRect(370, 250, 31, 30))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(16)
        font.setBold(False)
        font.setWeight(50)
        self.label_Basic_Deadvol_percent.setFont(font)
        self.label_Basic_Deadvol_percent.setStyleSheet(
            "color: rgb(51, 51, 51);")
        self.label_Basic_Deadvol_percent.setObjectName(
            "label_Basic_Deadvol_percent")
        self.comboBox_Basic_Control = QtWidgets.QComboBox(self.tab_Basic)
        self.comboBox_Basic_Control.setGeometry(QtCore.QRect(
            190, 320, 201, 31))
        self.comboBox_Basic_Control.setStyleSheet(
            "background-color: rgb(255, 255, 255);")
        self.comboBox_Basic_Control.setObjectName("comboBox_Basic_Control")
        self.comboBox_Basic_Control.addItem("")
        self.comboBox_Basic_Control.addItem("")
        self.comboBox_Basic_Control.addItem("")
        self.comboBox_Basic_Control.addItem("")
        self.label_Basic_ItemName = QtWidgets.QLabel(self.tab_Basic)
        self.label_Basic_ItemName.setGeometry(QtCore.QRect(730, 48, 211, 31))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(14)
        font.setBold(False)
        font.setWeight(50)
        self.label_Basic_ItemName.setFont(font)
        self.label_Basic_ItemName.setStyleSheet("color: rgb(51, 51, 51);")
        self.label_Basic_ItemName.setObjectName("label_Basic_ItemName")
        self.label_Basic_AssayItem = QtWidgets.QLabel(self.tab_Basic)
        self.label_Basic_AssayItem.setGeometry(QtCore.QRect(540, 40, 180, 40))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(18)
        font.setBold(True)
        font.setWeight(75)
        self.label_Basic_AssayItem.setFont(font)
        self.label_Basic_AssayItem.setStyleSheet("color: rgb(51, 51, 51);")
        self.label_Basic_AssayItem.setObjectName("label_Basic_AssayItem")
        self.tabWidget.addTab(self.tab_Basic, "")
        self.tab_Reagent = QtWidgets.QWidget()
        self.tab_Reagent.setObjectName("tab_Reagent")
        self.label_ReagentInfo = QtWidgets.QLabel(self.tab_Reagent)
        self.label_ReagentInfo.setGeometry(QtCore.QRect(30, 36, 191, 41))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(18)
        font.setBold(True)
        font.setWeight(75)
        self.label_ReagentInfo.setFont(font)
        self.label_ReagentInfo.setStyleSheet("color: rgb(51, 51, 51);")
        self.label_ReagentInfo.setObjectName("label_ReagentInfo")
        self.label_Reagent_ItemName = QtWidgets.QLabel(self.tab_Reagent)
        self.label_Reagent_ItemName.setGeometry(QtCore.QRect(730, 48, 211, 31))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(14)
        font.setBold(False)
        font.setWeight(50)
        self.label_Reagent_ItemName.setFont(font)
        self.label_Reagent_ItemName.setStyleSheet("color: rgb(51, 51, 51);")
        self.label_Reagent_ItemName.setObjectName("label_Reagent_ItemName")
        self.label_Reagent_AssayItem = QtWidgets.QLabel(self.tab_Reagent)
        self.label_Reagent_AssayItem.setGeometry(QtCore.QRect(
            540, 40, 180, 40))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(18)
        font.setBold(True)
        font.setWeight(75)
        self.label_Reagent_AssayItem.setFont(font)
        self.label_Reagent_AssayItem.setStyleSheet("color: rgb(51, 51, 51);")
        self.label_Reagent_AssayItem.setObjectName("label_Reagent_AssayItem")
        self.tableWidget_Reagent = QtWidgets.QTableWidget(self.tab_Reagent)
        self.tableWidget_Reagent.setGeometry(QtCore.QRect(30, 110, 891, 571))
        self.tableWidget_Reagent.setObjectName("tableWidget_Reagent")
        self.tableWidget_Reagent.setColumnCount(5)
        self.tableWidget_Reagent.setRowCount(0)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_Reagent.setHorizontalHeaderItem(0, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_Reagent.setHorizontalHeaderItem(1, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_Reagent.setHorizontalHeaderItem(2, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_Reagent.setHorizontalHeaderItem(3, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_Reagent.setHorizontalHeaderItem(4, item)
        self.tabWidget.addTab(self.tab_Reagent, "")
        self.tab_Control = QtWidgets.QWidget()
        self.tab_Control.setObjectName("tab_Control")
        self.label_Control_ItemName = QtWidgets.QLabel(self.tab_Control)
        self.label_Control_ItemName.setGeometry(QtCore.QRect(730, 48, 211, 31))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(14)
        font.setBold(False)
        font.setWeight(50)
        self.label_Control_ItemName.setFont(font)
        self.label_Control_ItemName.setStyleSheet("color: rgb(51, 51, 51);")
        self.label_Control_ItemName.setObjectName("label_Control_ItemName")
        self.label_Control_AssayItem = QtWidgets.QLabel(self.tab_Control)
        self.label_Control_AssayItem.setGeometry(QtCore.QRect(
            540, 40, 180, 40))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(18)
        font.setBold(True)
        font.setWeight(75)
        self.label_Control_AssayItem.setFont(font)
        self.label_Control_AssayItem.setStyleSheet("color: rgb(51, 51, 51);")
        self.label_Control_AssayItem.setObjectName("label_Control_AssayItem")
        self.label_ControlInfo_3 = QtWidgets.QLabel(self.tab_Control)
        self.label_ControlInfo_3.setGeometry(QtCore.QRect(30, 36, 191, 41))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(18)
        font.setBold(True)
        font.setWeight(75)
        self.label_ControlInfo_3.setFont(font)
        self.label_ControlInfo_3.setStyleSheet("color: rgb(51, 51, 51);")
        self.label_ControlInfo_3.setObjectName("label_ControlInfo_3")
        self.tableWidget_Control = QtWidgets.QTableWidget(self.tab_Control)
        self.tableWidget_Control.setGeometry(QtCore.QRect(30, 110, 891, 571))
        self.tableWidget_Control.setObjectName("tableWidget_Control")
        self.tableWidget_Control.setColumnCount(5)
        self.tableWidget_Control.setRowCount(0)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_Control.setHorizontalHeaderItem(0, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_Control.setHorizontalHeaderItem(1, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_Control.setHorizontalHeaderItem(2, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_Control.setHorizontalHeaderItem(3, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_Control.setHorizontalHeaderItem(4, item)
        self.tabWidget.addTab(self.tab_Control, "")
        self.tab_Setting = QtWidgets.QWidget()
        self.tab_Setting.setObjectName("tab_Setting")
        self.label_Setting = QtWidgets.QLabel(self.tab_Setting)
        self.label_Setting.setGeometry(QtCore.QRect(30, 36, 160, 41))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(18)
        font.setBold(True)
        font.setWeight(75)
        self.label_Setting.setFont(font)
        self.label_Setting.setStyleSheet("color: rgb(51, 51, 51);")
        self.label_Setting.setObjectName("label_Setting")
        self.tabWidget.addTab(self.tab_Setting, "")
        self.widget_Topbar = QtWidgets.QWidget(self.centralwidget)
        self.widget_Topbar.setGeometry(QtCore.QRect(240, 0, 970, 40))
        self.widget_Topbar.setStyleSheet(
            "background-color: rgb(255, 255, 255);")
        self.widget_Topbar.setObjectName("widget_Topbar")
        self.Topline = QtWidgets.QFrame(self.widget_Topbar)
        self.Topline.setGeometry(QtCore.QRect(0, 35, 970, 10))
        self.Topline.setFrameShape(QtWidgets.QFrame.Shape.HLine)
        self.Topline.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken)
        self.Topline.setObjectName("Topline")
        self.widget_Topbar_button = QtWidgets.QWidget(self.widget_Topbar)
        self.widget_Topbar_button.setGeometry(QtCore.QRect(260, 0, 360, 40))
        self.widget_Topbar_button.setStyleSheet(
            "background-color: rgb(255, 255, 255);")
        self.widget_Topbar_button.setObjectName("widget_Topbar_button")
        self.widget_Topbar_button.setVisible(False)
        self.Topline_3 = QtWidgets.QFrame(self.widget_Topbar_button)
        self.Topline_3.setGeometry(QtCore.QRect(0, 35, 960, 10))
        self.Topline_3.setFrameShape(QtWidgets.QFrame.Shape.HLine)
        self.Topline_3.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken)
        self.Topline_3.setObjectName("Topline_3")

        self.pushButton_Close = QtWidgets.QPushButton(
            self.widget_Topbar_button)
        self.pushButton_Close.setGeometry(QtCore.QRect(260, 4, 70, 30))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(10)
        font.setBold(True)
        font.setWeight(75)
        self.pushButton_Close.setFont(font)
        self.pushButton_Close.setStyleSheet(
            "background-color: rgb(41, 24, 96);\n"
            "color: rgb(255, 255, 255);")
        self.pushButton_Close.setObjectName("pushButton_Close")

        self.pushButton_Add = QtWidgets.QPushButton(self.widget_Topbar_button)
        self.pushButton_Add.setGeometry(QtCore.QRect(20, 4, 70, 30))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(10)
        font.setBold(True)
        font.setWeight(75)
        self.pushButton_Add.setFont(font)
        self.pushButton_Add.setStyleSheet(
            "background-color: rgb(41, 24, 96);\n"
            "color: rgb(255, 255, 255);")
        self.pushButton_Add.setObjectName("pushButton_Add")

        self.pushButton_Save = QtWidgets.QPushButton(self.widget_Topbar_button)
        self.pushButton_Save.setGeometry(QtCore.QRect(180, 4, 70, 30))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(10)
        font.setBold(True)
        font.setWeight(75)
        self.pushButton_Save.setFont(font)
        self.pushButton_Save.setStyleSheet(
            "background-color: rgb(41, 24, 96);\n"
            "color: rgb(255, 255, 255);")
        self.pushButton_Save.setObjectName("pushButton_Save")

        self.pushButton_Delete = QtWidgets.QPushButton(
            self.widget_Topbar_button)
        self.pushButton_Delete.setGeometry(QtCore.QRect(100, 4, 70, 30))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(10)
        font.setBold(True)
        font.setWeight(75)
        self.pushButton_Delete.setFont(font)
        self.pushButton_Delete.setStyleSheet(
            "background-color: rgb(41, 24, 96);\n"
            "color: rgb(255, 255, 255);")
        self.pushButton_Delete.setObjectName("pushButton_Delete")

        self.treeWidget = QtWidgets.QTreeWidget(self.centralwidget)
        self.treeWidget.setGeometry(QtCore.QRect(0, 76, 240, 590))
        self.treeWidget.setStyleSheet("background-color: rgb(108, 92, 161);\n")
        self.treeWidget.setAutoScrollMargin(20)
        self.treeWidget.setEditTriggers(
            QtWidgets.QAbstractItemView.EditTriggers.SelectedClicked)
        self.treeWidget.setDragEnabled(False)
        self.treeWidget.setIconSize(QtCore.QSize(0, 0))
        self.treeWidget.setIndentation(0)
        self.treeWidget.setObjectName("treeWidget")
        font = QtGui.QFont()
        font.setFamily("Arial Black")
        font.setPointSize(14)
        font.setBold(True)
        font.setWeight(75)
        self.treeWidget.headerItem().setFont(0, font)
        self.treeWidget.headerItem().setBackground(0,
                                                   QtGui.QColor(108, 92, 161))
        brush = QtGui.QBrush(QtGui.QColor(0, 0, 0))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        self.treeWidget.headerItem().setForeground(0, brush)
        brush = QtGui.QBrush(QtGui.QColor(108, 92, 161))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        self.treeWidget.headerItem().setBackground(0, brush)

        # PCR Plate 이미지 #######################################################################################
        self.PCRplate = PCRPlate(self.tab_Home)
        self.PCRplate.setGeometry(550, 100, 395, 400)

        plate_pos = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']
        for i in range(len(plate_pos)):
            for j in range(12):
                self.pushButton_plate = Plate_Button(self.tab_Home)
                self.pushButton_plate.setObjectName(
                    f"PCRplate_{plate_pos[i]}{j + 1}")
                self.pushButton_plate.setGeometry(
                    QtCore.QRect(584 + j * 30, 212 + i * 25, 26, 26))

        # Home 버튼
        item_0 = QtWidgets.QTreeWidgetItem(self.treeWidget)
        font = QtGui.QFont()
        font.setFamily("Arial Black")
        font.setPointSize(14)
        font.setBold(True)
        font.setWeight(75)
        item_0.setFont(0, font)
        brush = QtGui.QBrush(QtGui.QColor(41, 24, 96))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        item_0.setBackground(0, brush)
        brush = QtGui.QBrush(QtGui.QColor(255, 255, 255))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        item_0.setForeground(0, brush)

        # Assay Info 버튼
        item_0 = QtWidgets.QTreeWidgetItem(self.treeWidget)
        font = QtGui.QFont()
        font.setFamily("Arial Black")
        font.setPointSize(14)
        font.setBold(True)
        font.setWeight(75)
        item_0.setFont(0, font)
        brush = QtGui.QBrush(QtGui.QColor(41, 24, 96))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        item_0.setBackground(0, brush)
        brush = QtGui.QBrush(QtGui.QColor(255, 255, 255))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        item_0.setForeground(0, brush)

        # Basic Info 버튼
        item_1 = QtWidgets.QTreeWidgetItem(item_0)
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(11)
        font.setBold(True)
        font.setWeight(75)
        item_1.setFont(0, font)
        brush = QtGui.QBrush(QtGui.QColor(108, 92, 161))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        item_1.setBackground(0, brush)
        brush = QtGui.QBrush(QtGui.QColor(255, 255, 255))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        item_1.setForeground(0, brush)

        # Reagent Info 버튼
        item_1 = QtWidgets.QTreeWidgetItem(item_0)
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(11)
        font.setBold(True)
        font.setWeight(75)
        item_1.setFont(0, font)
        brush = QtGui.QBrush(QtGui.QColor(108, 92, 161))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        item_1.setBackground(0, brush)
        brush = QtGui.QBrush(QtGui.QColor(255, 255, 255))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        item_1.setForeground(0, brush)

        # Control Info 버튼
        item_1 = QtWidgets.QTreeWidgetItem(item_0)
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(11)
        font.setBold(True)
        font.setWeight(75)
        item_1.setFont(0, font)
        brush = QtGui.QBrush(QtGui.QColor(108, 92, 161))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        item_1.setBackground(0, brush)
        brush = QtGui.QBrush(QtGui.QColor(255, 255, 255))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        item_1.setForeground(0, brush)

        # Setting 버튼
        item_0 = QtWidgets.QTreeWidgetItem(self.treeWidget)
        font = QtGui.QFont()
        font.setFamily("Arial Black")
        font.setPointSize(14)
        font.setBold(True)
        font.setWeight(75)
        item_0.setFont(0, font)
        brush = QtGui.QBrush(QtGui.QColor(41, 24, 96))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        item_0.setBackground(0, brush)
        brush = QtGui.QBrush(QtGui.QColor(255, 255, 255))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        item_0.setForeground(0, brush)

        self.widget_Menubar = QtWidgets.QWidget(self.centralwidget)
        self.widget_Menubar.setGeometry(QtCore.QRect(0, 2, 240, 111))
        self.widget_Menubar.setStyleSheet(
            "background-color: rgb(108, 92, 161);\n")
        self.widget_Menubar.setObjectName("widget_Menubar")
        self.Label_SL = QtWidgets.QLabel(self.widget_Menubar)
        self.Label_SL.setGeometry(QtCore.QRect(2, 10, 80, 50))
        font = QtGui.QFont()
        font.setFamily("Arial Black")
        font.setPointSize(40)
        font.setBold(True)
        font.setWeight(75)
        self.Label_SL.setFont(font)
        self.Label_SL.setStyleSheet("color: rgb(224, 224, 224);")
        self.Label_SL.setObjectName("Label_SL")
        self.label_SmartLauncher = QtWidgets.QLabel(self.widget_Menubar)
        self.label_SmartLauncher.setGeometry(QtCore.QRect(4, 70, 231, 30))
        font = QtGui.QFont()
        font.setFamily("Arial Black")
        font.setPointSize(18)
        font.setBold(True)
        font.setWeight(75)
        self.label_SmartLauncher.setFont(font)
        self.label_SmartLauncher.setStyleSheet("color: rgb(224, 224, 224);")
        self.label_SmartLauncher.setObjectName("label_SmartLauncher")
        MainWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(MainWindow)
        self.tabWidget.setCurrentIndex(0)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
Exemple #21
0
    def initUI(self):
        self.grid = QGridLayout(self)

        self.file_control_grid = QGridLayout()
        self.file_control_grid.setSpacing(3)
        self.grid.addLayout(self.file_control_grid, 0, 0)

        self.file_tree_grid = QGridLayout()
        self.file_tree_grid.setSpacing(3)
        self.grid.addLayout(self.file_tree_grid, 1, 0)

        self.group_control_grid = QGridLayout()
        self.group_control_grid.setSpacing(3)
        self.grid.addLayout(self.group_control_grid, 0, 1)

        self.attribute_grid = QGridLayout()
        self.attribute_grid.setSpacing(3)
        self.grid.addLayout(self.attribute_grid, 1, 1)

        self.roi_control_grid = QGridLayout()
        self.roi_control_grid.setSpacing(3)
        self.grid.addLayout(self.roi_control_grid, 0, 2)

        self.plot_grid = QGridLayout()
        self.plot_grid.setSpacing(3)
        self.grid.addLayout(self.plot_grid, 1, 2)

        # # # # File control browser: # # # # # # # # (0,0)
        loadButton = QPushButton("Load expt. file", self)
        loadButton.clicked.connect(self.selectDataFile)
        # Label with current expt file
        self.currentExperimentLabel = QLabel('')
        self.file_control_grid.addWidget(loadButton, 0, 0)
        self.file_control_grid.addWidget(self.currentExperimentLabel, 1, 0)

        directoryButton = QPushButton("Select data directory", self)
        directoryButton.clicked.connect(self.selectDataDirectory)
        self.file_control_grid.addWidget(directoryButton, 0, 1)
        self.data_directory_display = QLabel('')
        self.data_directory_display.setFont(QtGui.QFont('SansSerif', 8))
        self.file_control_grid.addWidget(self.data_directory_display, 1, 1)

        # Attach metadata to file
        attachDatabutton = QPushButton("Attach metadata to file", self)
        attachDatabutton.clicked.connect(self.attachData)
        self.file_control_grid.addWidget(attachDatabutton, 2, 0, 1, 2)

        # Select image data file
        selectImageDataFileButton = QPushButton("Select image data file", self)
        selectImageDataFileButton.clicked.connect(self.selectImageDataFile)
        self.file_control_grid.addWidget(selectImageDataFileButton, 3, 0, 1, 2)

        # # # # File tree: # # # # # # # #  (1,0)
        self.groupTree = QTreeWidget(self)
        self.groupTree.setHeaderHidden(True)
        self.groupTree.itemClicked.connect(self.onTreeItemClicked)
        self.file_tree_grid.addWidget(self.groupTree, 3, 0, 2, 7)

        # # # # Group control: # # # # # # # # (0, 1)
        deleteGroupButton = QPushButton("Delete selected group", self)
        deleteGroupButton.clicked.connect(self.deleteSelectedGroup)
        self.group_control_grid.addWidget(deleteGroupButton, 0, 0, 1, 2)

        # File name display
        self.currentImageFileNameLabel = QLabel('')
        self.group_control_grid.addWidget(self.currentImageFileNameLabel, 1, 0)

        # Channel drop down
        ch_label = QLabel('Channel:')
        self.ChannelComboBox = QComboBox(self)
        self.ChannelComboBox.addItem("1")
        self.ChannelComboBox.addItem("0")
        self.ChannelComboBox.activated.connect(self.selectChannel)
        self.group_control_grid.addWidget(ch_label, 2, 0)
        self.group_control_grid.addWidget(self.ChannelComboBox, 2, 1)

        # # # # Attribute table: # # # # # # # # (1, 1)
        self.tableAttributes = QTableWidget()
        self.tableAttributes.setStyleSheet("")
        self.tableAttributes.setColumnCount(2)
        self.tableAttributes.setObjectName("tableAttributes")
        self.tableAttributes.setRowCount(0)
        item = QTableWidgetItem()
        font = QtGui.QFont()
        font.setPointSize(10)
        item.setFont(font)
        item.setBackground(QtGui.QColor(121, 121, 121))
        brush = QtGui.QBrush(QtGui.QColor(91, 91, 91))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        item.setForeground(brush)
        self.tableAttributes.setHorizontalHeaderItem(0, item)
        item = QTableWidgetItem()
        item.setBackground(QtGui.QColor(123, 123, 123))
        brush = QtGui.QBrush(QtGui.QColor(91, 91, 91))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        item.setForeground(brush)
        self.tableAttributes.setHorizontalHeaderItem(1, item)
        self.tableAttributes.horizontalHeader().setCascadingSectionResizes(
            True)
        self.tableAttributes.horizontalHeader().setHighlightSections(False)
        self.tableAttributes.horizontalHeader().setSortIndicatorShown(True)
        self.tableAttributes.horizontalHeader().setStretchLastSection(True)
        self.tableAttributes.verticalHeader().setVisible(False)
        self.tableAttributes.verticalHeader().setHighlightSections(False)
        item = self.tableAttributes.horizontalHeaderItem(0)
        item.setText("Attribute")
        item = self.tableAttributes.horizontalHeaderItem(1)
        item.setText("Value")

        self.tableAttributes.itemChanged.connect(self.update_attrs_to_file)
        self.attribute_grid.addWidget(self.tableAttributes, 3, 0, 1, 8)

        # # # # Roi control # # # # # # # # (0, 2)
        # ROI type drop-down
        self.RoiTypeComboBox = QComboBox(self)
        self.RoiTypeComboBox.addItem("freehand")
        radii = [1, 2, 3, 4, 6, 8]
        for radius in radii:
            self.RoiTypeComboBox.addItem("circle:" + str(radius))
        self.RoiTypeComboBox.activated.connect(self.selectRoiType)
        self.roi_control_grid.addWidget(self.RoiTypeComboBox, 0, 0)

        # Clear all ROIs button
        self.clearROIsButton = QPushButton("Clear ROIs", self)
        self.clearROIsButton.clicked.connect(self.clearRois)
        self.roi_control_grid.addWidget(self.clearROIsButton, 0, 2)

        # Response display type dropdown
        self.RoiResponseTypeComboBox = QComboBox(self)

        self.RoiResponseTypeComboBox.addItem("RawTrace")
        self.RoiResponseTypeComboBox.addItem("TrialAverage")
        self.RoiResponseTypeComboBox.addItem("TrialResponses")
        self.RoiResponseTypeComboBox.addItem("TrialAverageDFF")
        self.roi_control_grid.addWidget(self.RoiResponseTypeComboBox, 2, 2)

        # ROIset file name line edit box
        self.defaultRoiSetName = "roi_set_name"
        self.le_roiSetName = QLineEdit(self.defaultRoiSetName)
        self.roi_control_grid.addWidget(self.le_roiSetName, 1, 1)

        # Save ROIs button
        self.saveROIsButton = QPushButton("Save ROIs", self)
        self.saveROIsButton.clicked.connect(self.saveRois)
        self.roi_control_grid.addWidget(self.saveROIsButton, 1, 0)

        # Load ROI set combobox
        self.loadROIsComboBox = QComboBox(self)
        self.loadROIsComboBox.addItem("(load existing ROI set)")
        self.loadROIsComboBox.activated.connect(self.selectedExistingRoiSet)
        self.roi_control_grid.addWidget(self.loadROIsComboBox, 1, 2)
        self.updateExistingRoiSetList()

        # Delete current roi button
        self.deleteROIButton = QPushButton("Delete ROI", self)
        self.deleteROIButton.clicked.connect(self.deleteRoi)
        self.roi_control_grid.addWidget(self.deleteROIButton, 2, 0)

        # Current roi slider
        self.roiSlider = QSlider(QtCore.Qt.Orientation.Horizontal, self)
        self.roiSlider.setMinimum(0)
        self.roiSlider.setMaximum(self.max_rois)
        self.roiSlider.valueChanged.connect(self.sliderUpdated)
        self.roi_control_grid.addWidget(self.roiSlider, 2, 1, 1, 1)

        ctx = plt.rc_context({
            'xtick.major.size': 1,
            'axes.spines.top': False,
            'axes.spines.right': False,
            'xtick.labelsize': 'xx-small',
            'ytick.labelsize': 'xx-small',
            'xtick.major.size': 1.0,
            'ytick.major.size': 1.0,
            'xtick.major.pad': 1.0,
            'ytick.major.pad': 1.0
        })
        with ctx:
            self.responseFig = plt.figure(frameon=False, layout='constrained')
            self.responsePlot = self.responseFig.add_subplot(111)
            self.responseCanvas = FigureCanvas(self.responseFig)
        self.responseCanvas.draw_idle()
        self.plot_grid.addWidget(self.responseCanvas, 0, 0)

        # # # # Image canvas # # # # # # # # (1, 2)
        self.roi_fig = plt.figure()
        self.roi_ax = self.roi_fig.add_subplot(111)
        self.roi_canvas = FigureCanvas(self.roi_fig)
        self.toolbar = NavigationToolbar(self.roi_canvas, self)
        self.roi_ax.set_aspect('equal')
        self.roi_ax.set_axis_off()
        self.plot_grid.addWidget(self.toolbar, 1, 0)
        self.plot_grid.addWidget(self.roi_canvas, 2, 0)
        self.plot_grid.setRowStretch(0, 1)
        self.plot_grid.setRowStretch(1, 3)
        self.plot_grid.setRowStretch(2, 3)

        # Current z slice slider
        self.zSlider = QSlider(QtCore.Qt.Orientation.Horizontal, self)
        self.zSlider.setMinimum(0)
        self.zSlider.setMaximum(50)
        self.zSlider.setValue(0)
        self.zSlider.valueChanged.connect(self.zSliderUpdated)
        self.plot_grid.addWidget(self.zSlider, 3, 0)

        self.roi_fig.tight_layout()

        self.setWindowTitle('Visanalysis')
        self.setGeometry(200, 200, 1200, 600)
        self.show()
    def setupUi(self, SyncEventWidget):
        SyncEventWidget.setObjectName("SyncEventWidget")
        SyncEventWidget.resize(400, 62)
        sizePolicy = QtWidgets.QSizePolicy(
            QtWidgets.QSizePolicy.Policy.Expanding,
            QtWidgets.QSizePolicy.Policy.Maximum)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            SyncEventWidget.sizePolicy().hasHeightForWidth())
        SyncEventWidget.setSizePolicy(sizePolicy)
        SyncEventWidget.setMinimumSize(QtCore.QSize(400, 0))
        self.verticalLayout = QtWidgets.QVBoxLayout(SyncEventWidget)
        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout.setObjectName("verticalLayout")
        self.frame = QtWidgets.QFrame(SyncEventWidget)
        sizePolicy = QtWidgets.QSizePolicy(
            QtWidgets.QSizePolicy.Policy.Expanding,
            QtWidgets.QSizePolicy.Policy.Maximum)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.frame.sizePolicy().hasHeightForWidth())
        self.frame.setSizePolicy(sizePolicy)
        self.frame.setStyleSheet(".QFrame {\n"
                                 "border: 1px solid rgb(205, 203, 205);\n"
                                 "background-color: rgb(255, 255, 255);\n"
                                 "border-radius: 7px;\n"
                                 "}")
        self.frame.setFrameShape(QtWidgets.QFrame.Shape.Box)
        self.frame.setFrameShadow(QtWidgets.QFrame.Shadow.Plain)
        self.frame.setObjectName("frame")
        self.gridLayout = QtWidgets.QGridLayout(self.frame)
        self.gridLayout.setContentsMargins(7, 10, 12, 10)
        self.gridLayout.setObjectName("gridLayout")
        self.infoLabel = QtWidgets.QLabel(self.frame)
        sizePolicy = QtWidgets.QSizePolicy(
            QtWidgets.QSizePolicy.Policy.Preferred,
            QtWidgets.QSizePolicy.Policy.MinimumExpanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.infoLabel.sizePolicy().hasHeightForWidth())
        self.infoLabel.setSizePolicy(sizePolicy)
        palette = QtGui.QPalette()
        brush = QtGui.QBrush(QtGui.QColor(109, 109, 109))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        palette.setBrush(QtGui.QPalette.ColorGroup.Active,
                         QtGui.QPalette.ColorRole.WindowText, brush)
        brush = QtGui.QBrush(QtGui.QColor(109, 109, 109))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        palette.setBrush(QtGui.QPalette.ColorGroup.Inactive,
                         QtGui.QPalette.ColorRole.WindowText, brush)
        brush = QtGui.QBrush(QtGui.QColor(127, 127, 127))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        palette.setBrush(QtGui.QPalette.ColorGroup.Disabled,
                         QtGui.QPalette.ColorRole.WindowText, brush)
        self.infoLabel.setPalette(palette)
        self.infoLabel.setObjectName("infoLabel")
        self.gridLayout.addWidget(self.infoLabel, 1, 1, 1, 1)
        self.filenameLabel = QElidedLabel(self.frame)
        self.filenameLabel.setObjectName("filenameLabel")
        self.gridLayout.addWidget(self.filenameLabel, 0, 1, 1, 1)
        self.iconLabel = QtWidgets.QLabel(self.frame)
        self.iconLabel.setMinimumSize(QtCore.QSize(32, 32))
        self.iconLabel.setMaximumSize(QtCore.QSize(32, 32))
        self.iconLabel.setText("")
        self.iconLabel.setObjectName("iconLabel")
        self.gridLayout.addWidget(self.iconLabel, 0, 0, 2, 1,
                                  QtCore.Qt.AlignmentFlag.AlignHCenter)
        self.actionButton = QtWidgets.QPushButton(self.frame)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed,
                                           QtWidgets.QSizePolicy.Policy.Fixed)
        sizePolicy.setHorizontalStretch(30)
        sizePolicy.setVerticalStretch(30)
        sizePolicy.setHeightForWidth(
            self.actionButton.sizePolicy().hasHeightForWidth())
        self.actionButton.setSizePolicy(sizePolicy)
        self.actionButton.setMinimumSize(QtCore.QSize(30, 30))
        self.actionButton.setStyleSheet("QPushButton {\n"
                                        "    border: none;\n"
                                        "    background-color: none;\n"
                                        "    color: rgb(68,133,243);\n"
                                        "    font: bold\n"
                                        "}")
        self.actionButton.setObjectName("actionButton")
        self.gridLayout.addWidget(self.actionButton, 0, 3, 2, 1)
        spacerItem = QtWidgets.QSpacerItem(
            0, 0, QtWidgets.QSizePolicy.Policy.Expanding,
            QtWidgets.QSizePolicy.Policy.Minimum)
        self.gridLayout.addItem(spacerItem, 0, 2, 2, 1)
        self.verticalLayout.addWidget(self.frame)

        self.retranslateUi(SyncEventWidget)
        QtCore.QMetaObject.connectSlotsByName(SyncEventWidget)
Exemple #23
0
    def generate_matrix(self):
        self.radioButton_from_matrix.setEnabled(True)
        nodes = [i for i in range(1, self.spinBox.value() + 1)]
        Ui_MainWindow().__class__.nodes = nodes
        a_list = ["a{}".format(i) for i in range(1, self.spinBox.value() + 1)]
        temp_list = []
        for i in nodes:
            for j in range(i, nodes[-1] + 1):
                temp_list.append((i, j))
        temp_list_2 = sample(temp_list, randint(1, len(temp_list)))
        temp_list_3 = []
        for i in range(len(temp_list_2)):
            temp_list_3.append(randint(0, 1))
        self.relations_dict = dict(zip(temp_list_2, temp_list_3))
        print(self.relations_dict)
        temp_list_4 = []
        for i in self.relations_dict.keys():
            if i[0] == i[1] and self.relations_dict[i] == 1:
                temp_list_4.append(i)
        for i in temp_list_4:
            self.relations_dict.pop(i)
        print(self.relations_dict)
        self.tableWidget.setRowCount(len(nodes))
        self.tableWidget.setColumnCount(len(nodes))
        self.tableWidget.clear()
        for i in range(len(nodes)):
            self.tableWidget.setRowHeight(i, 25)
            self.tableWidget.setColumnWidth(i, 25)
            self.tableWidget.setHorizontalHeaderLabels(a_list)
            self.tableWidget.setVerticalHeaderLabels(a_list)

        for i in self.relations_dict.keys():
            self.tableWidget.setItem(i[0] - 1, i[1] - 1, QtWidgets.QTableWidgetItem(str(self.relations_dict[i])))
            self.tableWidget.setItem(i[1] - 1, i[0] - 1, QtWidgets.QTableWidgetItem(str(self.relations_dict[i])))
            if self.relations_dict[i] == 1:
                self.tableWidget.item(i[0] - 1, i[1] - 1).setBackground(QtGui.QColor(0, 190, 0))
                self.tableWidget.item(i[1] - 1, i[0] - 1).setBackground(QtGui.QColor(0, 190, 0))
            else:
                self.tableWidget.item(i[0] - 1, i[1] - 1).setBackground(QtGui.QColor(255, 255, 255))
                self.tableWidget.item(i[1] - 1, i[0] - 1).setBackground(QtGui.QColor(255, 255, 255))

        temp_list_4.clear()
        for i in self.relations_dict.keys():
            if self.relations_dict[i] == 0:
                temp_list_4.append(i)
        for i in temp_list_4:
            self.relations_dict.pop(i)
        rowCount = self.tableWidget.rowCount()
        colCount = self.tableWidget.columnCount()

        self.created_matrix = np.arange(rowCount * colCount).reshape(rowCount, colCount)

        def getItem(row, col):
            try:
                return self.tableWidget.item(row, col).text()
            except:
                return 0

        for row in range(rowCount):
            for col in range(colCount):
                self.created_matrix[row][col] = getItem(row, col)
Exemple #24
0
    def measure_widths(self):

        def qpt2pt(x, y):
            Q = self.mapFromScene( self.mapToScene( int(x), int(y)) )
            return Q.x(), Q.y()

        self.measuring_widths = True
        self.parent().widthsButton.setChecked(True)
        self.k = 0
        self.W = posData(
            np.empty(shape=(0, 0)),
            np.empty(shape=(0, 0)))  #preallocate custom widths
        #number of possible measurements per segment (length + #widths)
        #self.measurements = np.empty((0, self.iw.nm + 1), int) * np.nan
        self.numwidths = int(self.parent().subWin.numwidths.text())
        #self.measurements[-1] = np.append( self.l[-1], np.zeros(self.numwidths-1)*np.nan ) #preallocate measurements
        self.widths[-1] = np.empty(self.numwidths-1, dtype='float') #preallocate measurements
        self.widthNames[-1] = [
            '{0:2.2f}% Width'.format(100 * f / self.numwidths)
            for f in np.arange(1, self.numwidths)
        ]

        self.nspines = 2 * (self.numwidths - 1)
        self.parent().statusbar.showMessage(
            'Click point along spines to make width measurements perpindicular to the length segment'
        )

        #get pts for width drawing
        bins = np.linspace(0, self.l[-1], self.numwidths + 1)
        inds = np.digitize(self.l, bins)
        __, self.inddec = np.unique(inds, return_index = True)

        pts = np.array(list(map(qpt2pt, self.xs, self.ys)))
        x, y = pts[:, 0], pts[:, 1]
        self.xp, self.yp = x[self.inddec], y[self.inddec]
        self.slopes = self.m[:,self.inddec]
        
        #Identify width spine points
        self.xsw = x[inds]
        self.ysw = y[inds]

        #Draw Widths
        for k,(x,y) in enumerate(zip(self.xp[1:-1], self.yp[1:-1])):

            x1, y1 = x,y
            L = self.pixmap_fit.width()
            H = self.pixmap_fit.height()
            v = self.slopes[:,k+1]
            vx =  v[1]
            vy = -v[0]
            t0 = np.hypot(L,H)
            t2 = 0

            #intersect: rectangle
            for offset in ([0,0],[L,H]):
                for ev in ([1,0],[0,1]):
                    A = np.matrix([ [vx, ev[0]] , [vy, ev[1]] ])
                    b = np.array([offset[0] - x1, offset[1] - y1])
                    T = np.linalg.solve(A,b)[0]
                    t0 = min(T, t0, key=abs) #find nearest intersection to bounds

            #Find 2nd furthest intersection within bounds
            bounds = np.array( [(L - x1)/vx, (H - y1)/vy, -x1/vx, -y1/vy] )
            t2 = max(-t0, np.sign(-t0)* np.partition(bounds,-2)[-2], key=abs)

            x0 = x1 + t0*vx
            y0 = y1 + t0*vy
            x2 = x1 + t2*vx
            y2 = y1 + t2*vy

            for l, (x, y) in enumerate(zip([x0, x2], [y0, y2])):
                start = QtCore.QPointF(x1, y1)
                end = QtCore.QPointF(x, y)
                self.scene.interpLine = QGraphicsLineItem(
                    QtCore.QLineF(start, end))
                self.d["{}".format(2 * k + l)] = self.scene.interpLine
                self.scene.addItem(self.scene.interpLine)
                if k == 0 and l == 0:
                    self.scene.interpLine.setPen(
                        QtGui.QPen(QtGui.QColor('yellow')))
Exemple #25
0
    def mousePressEvent(self, event):
        #http://pyqt.sourceforge.net/Docs/PyQt4/qgraphicsscenemouseevent.html
        #https://stackoverflow.com/questions/21197658/how-to-get-pixel-on-qgraphicspixmapitem-on-a-qgraphicsview-from-a-mouse-click
        data = self.mapToScene(event.pos())

        #draw piecewise lines for non-width measurements
        rules = [self.measuring_length, self.measuring_angle, self.measuring_area]

        if self.scene.testline and self._thispos and any(rules):
            start = self._thispos
            end = QtCore.QPointF(data)

            if self._lastpos and self.measuring_angle:

                a = self._lastpos - self._thispos
                b = data - self._thispos
                a = np.array([a.x(), a.y()])
                b = np.array([b.x(), b.y()])
                self.measuring_angle = False
                t = np.arccos(np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b)))
                t *= 180 / np.pi  #convert to degrees
                self.T.update(t)
                self.angleValues = np.append(self.angleValues,t)
                self.parent().statusbar.showMessage('Angle measurement complete')
                self.parent().angleButton.setChecked(False)
                self.parent().bezier.setEnabled(True)

            self.scene.realline = QGraphicsLineItem(QtCore.QLineF(start, end))
            self.scene.addItem(self.scene.realline)

        #Collect piecewise line start/end points
        self._lastpos = self._thispos  # save old position value
        self._thispos = QtCore.QPointF(data)  # update current position

        if self.measuring_length:
            self.L.update(data.x(), data.y())  # update total length
            self.line_count += 1

        elif self.measuring_area:
            self.line_count += 1
            intersect = False
            if self.line_count > 2: #cant make polygon w/ two lines
                intersect, xi, yi, k = self.A.checkIntersect(data.x(),data.y())
                self.parent().areaButton.setEnabled(True)
            if intersect:
                self.measuring_area = False
                self.A.update(xi,yi) #update with intersect point
                self.A.x, self.A.y = self.A.x[k:], self.A.y[k:] #only use points after intersection
                A = self.A.calcArea()
                self.areaValues = np.append(self.areaValues, A) #add area values
                #draw permanent polygon
                points = [ QtCore.QPointF(x,y) for x,y in zip( self.A.x, self.A.y ) ]
                self.scene.polyItem2 = QGraphicsPolygonItem(QtGui.QPolygonF(points))
                self.scene.polyItem2.setBrush( QtGui.QBrush(QtGui.QColor(255,255,255,127)) )
                self.scene.removeItem(self.scene.polyItem) #remove mouseover polygon
                self.scene.polyItem = False #remove mouseover polygon
                self.scene.addItem(self.scene.polyItem2) #shade in polygon
                self.parent().statusbar.showMessage('Polygon area measurement completed')
                self.parent().areaButton.setChecked(False)
                self.parent().bezier.setEnabled(True) #make bezier fit available again
                QApplication.setOverrideCursor(QtCore.Qt.ArrowCursor)  #change cursor
            else:
                self.A.update(data.x(),data.y()) #update with click point

        #https://stackoverflow.com/questions/30898846/qgraphicsview-items-not-being-placed-where-they-should-be
        if self.measuring_widths:  #measure widths, snap to spines

            k = int(self.k / 2) + 1  #same origin for spine on either side
            x0, y0 = self.xp[k], self.yp[k]
            x1, y1 = data.x(), data.y()

            #perpindicular slopes
            vx = self.slopes[:,k][1]
            vy = -self.slopes[:,k][0]

            A = np.matrix([[vx, -vy], [vy, vx]])
            b = np.array([x1 - x0, y1 - y0])
            t = np.linalg.solve(A,b)

            xi = x0 + t[0]*vx
            yi = y0 + t[0]*vy

            self.W.update(xi,yi)
            p = QtCore.QPointF(xi, yi)

            s = 10  #dot size
            self.scene.ellipseItem = QGraphicsEllipseItem(0, 0, s, s)
            self.scene.ellipseItem.setPos(p.x() - s / 2, p.y() - s / 2)
            qb = QtGui.QBrush()
            qb.setColor(QtGui.QColor('red'))
            self.scene.ellipseItem.setBrush(qb)
            self.scene.ellipseItem.setFlag(
                QGraphicsItem.GraphicsItemFlag.ItemIgnoresTransformations,
                False)  #size stays small, but doesnt translate if false
            self.scene.addItem(self.scene.ellipseItem)
            self.k += 1

            if self.k < self.nspines:
                self.d[str(self.k)].setPen(QtGui.QPen(
                    QtGui.QColor('yellow'))) #Highlight next spine
                    
            if self.k == self.nspines:
                self.parent().statusbar.showMessage('Width measurements complete')
                self.measuring_widths = False
                self.parent().widthsButton.setEnabled(False)
                self.parent().widthsButton.setChecked(False)
                self.parent().bezier.setEnabled(True)
                width = np.sqrt(
                    (self.W.x[1::2] - self.W.x[0::2])**2 +
                    (self.W.y[1::2] - self.W.y[0::2])**2)  #calculate widths
                self.widths[-1] = width