Ejemplo n.º 1
0
    def __init__(self, pickerView):
        scene = QGraphicsScene()
        scene.addText(
            "QGraphicsItem in QGraphicsView.  Press mouse to mock pick, key to open dialog."
        )
        QGraphicsView.__init__(self, scene)

        # Accept touch on both this widget and viewport (abstract scroll area)
        # Touch engenders LMB mouse press event since app attribute for that is set.
        self.setAttribute(Qt.WA_AcceptTouchEvents)
        self.viewport().setAttribute(Qt.WA_AcceptTouchEvents)

        self.qmlMaster = QmlMaster()
        '''
    See the QML, created there?
    
    " A Person model which is mock-picked"
    self.model = Person()
    '''
        if pickerView is not None:
            self.pickerView = pickerView

            self.pickDelegate = self.qmlMaster.findComponent(
                self.pickerView,
                className=model.person.Person,
                objectName="person")

            self.dialogDelegate = self.qmlMaster.findComponent(
                self.pickerView,
                className=model.qmlDelegate.QmlDelegate,
                objectName="dialogDelegate")
        else:
            self.pickDelegate = None
            self.dialogDelegate = None
Ejemplo n.º 2
0
    def __init__(self, pickerView):
        scene = QGraphicsScene()
        scene.addText(
            "QGraphicsItem in QGraphicsView.  Press mouse to mock pick, key to open dialog."
        )
        QGraphicsView.__init__(self, scene)
        self.qmlMaster = QmlMaster()
        '''
    See the QML, created there?
    
    " A Person model which is mock-picked"
    self.model = Person()
    '''
        if pickerView is not None:
            self.pickerView = pickerView

            self.pickDelegate = self.qmlMaster.findComponent(
                self.pickerView,
                className=model.person.Person,
                objectName="person")

            self.dialogDelegate = self.qmlMaster.findComponent(
                self.pickerView,
                className=model.qmlDelegate.QmlDelegate,
                objectName="dialogDelegate")
        else:
            self.pickDelegate = None
            self.dialogDelegate = None
Ejemplo n.º 3
0
 def on_imagesTree_currentItemChanged(self, current, previous):
     """
     Private slot to show a preview of the selected image.
     
     @param current current image entry (QTreeWidgetItem)
     @param previous old current entry (QTreeWidgetItem)
     """
     if current is None:
         return
     
     imageUrl = QUrl(current.text(1))
     if not imageUrl.host():
         imageUrl.setHost(QUrl(self.siteAddressLabel.text()).host())
         imageUrl.setScheme(QUrl(self.siteAddressLabel.text()).scheme())
     
     import Helpviewer.HelpWindow
     cache = Helpviewer.HelpWindow.HelpWindow.networkAccessManager().cache()
     if cache:
         cacheData = cache.data(imageUrl)
     else:
         cacheData = None
     pixmap = QPixmap()
     invalidPixmap = False
     scene = QGraphicsScene(self.imagePreview)
     if not cacheData:
         invalidPixmap = True
     else:
         pixmap.loadFromData(cacheData.readAll())
         if pixmap.isNull():
             invalidPixmap = True
     if invalidPixmap:
         scene.addText(self.tr("Preview not available."))
     else:
         scene.addPixmap(pixmap)
     self.imagePreview.setScene(scene)
Ejemplo n.º 4
0
    def on_imagesTree_currentItemChanged(self, current, previous):
        """
        Private slot to show a preview of the selected image.
        
        @param current current image entry (QTreeWidgetItem)
        @param previous old current entry (QTreeWidgetItem)
        """
        if current is None:
            return

        imageUrl = QUrl(current.text(1))
        if not imageUrl.host():
            imageUrl.setHost(QUrl(self.siteAddressLabel.text()).host())
            imageUrl.setScheme(QUrl(self.siteAddressLabel.text()).scheme())

        import Helpviewer.HelpWindow
        cache = Helpviewer.HelpWindow.HelpWindow.networkAccessManager().cache()
        if cache:
            cacheData = cache.data(imageUrl)
        else:
            cacheData = None
        pixmap = QPixmap()
        invalidPixmap = False
        scene = QGraphicsScene(self.imagePreview)
        if not cacheData:
            invalidPixmap = True
        else:
            pixmap.loadFromData(cacheData.readAll())
            if pixmap.isNull():
                invalidPixmap = True
        if invalidPixmap:
            scene.addText(self.tr("Preview not available."))
        else:
            scene.addPixmap(pixmap)
        self.imagePreview.setScene(scene)
Ejemplo n.º 5
0
    def set_signal(self):
        indx = self.ui.combobox_signals.currentIndex()
        if indx != 0:
            self.ui.inpt.setReadOnly(True)
        else:
            self.ui.inpt.setReadOnly(False)
            self.ui.inpt.setText("10010110")
            self.decoder_update()
            return

        signal = self.signals[indx - 1]
        pa = ProtocolAnalyzer(signal)
        pa.get_protocol_from_signal()
        self.ui.inpt.setText("".join(pa.decoded_proto_bits_str))

        tmp_scene = QGraphicsScene()
        tmp_scene.addText(self.tr("Loading Signal..."))
        QApplication.setOverrideCursor(Qt.WaitCursor)
        self.ui.graphicsView_signal.setScene(tmp_scene)
        QApplication.processEvents()

        if signal is not None:
            last_message = pa.messages[-1]
            lookup = {
                i: msg.bit_sample_pos
                for i, msg in enumerate(pa.messages)
            }

            plot_data = signal.qad[lookup[0][0]:lookup[pa.num_messages -
                                                       1][len(last_message) -
                                                          1]]
            self.ui.graphicsView_signal.plot_data(plot_data)

        self.ui.graphicsView_signal.centerOn(0, 0)
        QApplication.restoreOverrideCursor()
Ejemplo n.º 6
0
    def __init__(self, pickerView):
        scene = QGraphicsScene()
        scene.addText("QGraphicsItem in QGraphicsView.  Press mouse to mock pick, key to open dialog.")
        QGraphicsView.__init__(self, scene)

        # Accept touch on both this widget and viewport (abstract scroll area)
        # Touch engenders LMB mouse press event since app attribute for that is set.
        self.setAttribute(Qt.WA_AcceptTouchEvents)
        self.viewport().setAttribute(Qt.WA_AcceptTouchEvents)

        self.qmlMaster = QmlMaster()

        """
    See the QML, created there?
    
    " A Person model which is mock-picked"
    self.model = Person()
    """
        if pickerView is not None:
            self.pickerView = pickerView

            self.pickDelegate = self.qmlMaster.findComponent(
                self.pickerView, className=model.person.Person, objectName="person"
            )

            self.dialogDelegate = self.qmlMaster.findComponent(
                self.pickerView, className=model.qmlDelegate.QmlDelegate, objectName="dialogDelegate"
            )
        else:
            self.pickDelegate = None
            self.dialogDelegate = None
Ejemplo n.º 7
0
    def set_signal(self):
        indx = self.ui.combobox_signals.currentIndex()
        if indx != 0:
            self.ui.inpt.setReadOnly(True)
        else:
            self.ui.inpt.setReadOnly(False)
            self.ui.inpt.setText("10010110")
            self.decoder_update()
            return

        signal = self.signals[indx - 1]
        pa = ProtocolAnalyzer(signal)
        pa.get_protocol_from_signal()
        self.ui.inpt.setText("".join(pa.decoded_proto_bits_str))

        tmp_scene = QGraphicsScene()
        tmp_scene.addText(self.tr("Loading Signal..."))
        QApplication.instance().setOverrideCursor(Qt.WaitCursor)
        self.ui.graphicsView_signal.setScene(tmp_scene)

        if signal is not None:
            last_message = pa.messages[-1]
            lookup = {i: msg.bit_sample_pos for i, msg in enumerate(pa.messages)}

            plot_data = signal.qad[lookup[0][0]:lookup[pa.num_messages - 1][len(last_message) - 1]]
            self.ui.graphicsView_signal.plot_data(plot_data)

        self.ui.graphicsView_signal.centerOn(0, 0)
        QApplication.instance().restoreOverrideCursor()
Ejemplo n.º 8
0
    def initUI(self):
        # self.setGeometry(400, 200, 1000, 700)
        # self.setWindowTitle("Circles")

        scene = QGraphicsScene()
        scene.addText("Hello, world!")

        view = QGraphicsView(scene)
Ejemplo n.º 9
0
    def __init__(self, parent=None):
        super().__init__()

        scene = QGraphicsScene()
        scene.addText("Hello, world!")

        view = QGraphicsView(scene)
        view.show()
Ejemplo n.º 10
0
class MainWindow(QGraphicsView):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        #创建场景
        self.scene = QGraphicsScene()
        #在场景中添加文字
        self.scene.addText("Hello, world!")
        #将场景加载到窗口
        self.setScene(self.scene)
Ejemplo n.º 11
0
 def __showLoadingText(self):
     """
     Private method to show some text while loading an image.
     """
     self.imagePreview.setBackgroundBrush(
         self.__imagePreviewStandardBackground)
     scene = QGraphicsScene(self.imagePreview)
     scene.addText(self.tr("Loading..."))
     self.imagePreview.setScene(scene)
Ejemplo n.º 12
0
 def iterator_done(self):
     view = self.findChild(QGraphicsView, "graphicsView")
     scene = QGraphicsScene()
     scene.addText("All data processing complete")
     view.setScene(scene)
     h_layout = self.findChild(QHBoxLayout, "horizontalLayout")
     for i in reversed(range(h_layout.count())):
         h_layout.itemAt(i).widget().deleteLater()
     close_button = QPushButton("Close")
     close_button.clicked.connect(lambda: self.close())
     h_layout.addWidget(close_button)
Ejemplo n.º 13
0
    def init_ui(self):

        scene = QGraphicsScene()
        scene.setBackgroundBrush(QColor(255, 255, 255))
        scene.setItemIndexMethod(QGraphicsScene.BspTreeIndex)
        scene.setSceneRect(scene.itemsBoundingRect())

        self.setDragMode(QGraphicsView.RubberBandDrag)
        self.setViewportUpdateMode(QGraphicsView.FullViewportUpdate)
        self.setRenderHints(QPainter.Antialiasing | QPainter.TextAntialiasing)
        self.frame_item = QGraphicsPixmapItem()
        scene.addItem(self.frame_item)
        scene.addText("hello world!")
        self.setScene(scene)
Ejemplo n.º 14
0
class Example(QGraphicsView):
    def __init__(self):
        super().__init__()

        self.setGeometry(300, 300, 250, 150)
        self.setWindowTitle("Simple")

        self.init()

    def init(self):

        self.scene = QGraphicsScene()
        self.scene.addText("ZetCode")
        self.setScene(self.scene)
Ejemplo n.º 15
0
class View(QGraphicsView):
    def __init__(self, parent=None):
        QGraphicsView.__init__(self, parent)

        self.scene = QGraphicsScene(self)
        self.scene.setBackgroundBrush(Qt.yellow)
        self.setScene(self.scene)

        center_rect = QGraphicsRectItem(-10, -10, 20, 20)
        self.scene.addItem(center_rect)

        rect = QGraphicsRectItem(0, 0, 100, 100)
        rect.setPos(-100, -100)
        self.scene.addItem(rect)

        rect2 = QGraphicsRectItem(0, 0, 100, 100)
        self.scene.addItem(rect2)

        text = self.scene.addText("Hello WOrld")

        # self.scene.addLine(QLineF(0, 10, -20, -20), QPen(Qt.black))

        rect2.moveBy(50, 50)
        rect2.setRotation(50)
        rect2.moveBy(-50, -50)

        print(self.scene.width(), self.scene.height())

        self.resize(400, 400)
Ejemplo n.º 16
0
 def __showPixmap(self, pixmap):
     """
     Private method to show a pixmap in the preview pane.
     
     @param pixmap pixmap to be shown
     @type QPixmap
     """
     scene = QGraphicsScene(self.imagePreview)
     if pixmap.isNull():
         self.imagePreview.setBackgroundBrush(
             self.__imagePreviewStandardBackground)
         scene.addText(self.tr("Preview not available."))
     else:
         self.imagePreview.setBackgroundBrush(QBrush(self.__tilePixmap))
         scene.addPixmap(pixmap)
     self.imagePreview.setScene(scene)
Ejemplo n.º 17
0
    def __init__(self, parent=None):
        QGraphicsView.__init__(self, parent)
        self.setFixedWidth(56)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

        # self.setFrameStyle(QFrame.NoFrame)
        # self.setStyleSheet("""
        #     QGraphicsView { border: 1px solid black }
        # """)

        scene = QGraphicsScene()
        scene.addSimpleText('nice!!')
        self.text = scene.addText('hello')

        scene.addText('world')
        self.setScene(scene)
Ejemplo n.º 18
0
class Altimeter_Tape(QGraphicsView):
    def __init__(self, parent=None):
        super(Altimeter_Tape, self).__init__(parent)
        self.setStyleSheet("border: 0px")
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setRenderHint(QPainter.Antialiasing)
        self.setFocusPolicy(Qt.NoFocus)
        self._altimeter = 0

    def resizeEvent(self, event):
        w = self.width()
        h = self.height()
        self.pph = 0.5
        f = QFont()
        f.setPixelSize(20)
        fontMetrics = QFontMetricsF(f)
        height_pixel = 5000 + h

        dialPen = QPen(QColor(Qt.white))
        dialPen.setWidth(2)

        self.scene = QGraphicsScene(0, 0, w, height_pixel)
        self.scene.addRect(0, 0, w, height_pixel, QPen(QColor(Qt.black)),
                           QBrush(QColor(Qt.black)))

        for i in range(100, -1, -1):
            if i % 2 == 0:
                self.scene.addLine(w / 2 + 15, (-i * 50) + 5000 + h / 2, w,
                                   (-i * 50) + 5000 + h / 2, dialPen)
                t = self.scene.addText(str(i * 100))
                t.setFont(f)
                self.scene.setFont(f)
                t.setDefaultTextColor(QColor(Qt.white))
                t.setX(0)
                t.setY(((-i * 50) + 5000 + h / 2) -
                       t.boundingRect().height() / 2)
            else:
                self.scene.addLine(w / 2 + 30, (-i * 50) + 5000 + h / 2, w,
                                   (-i * 50) + 5000 + h / 2, dialPen)
        self.setScene(self.scene)

    def redraw(self):
        self.resetTransform()
        self.centerOn(self.scene.width() / 2,
                      -self._altimeter * self.pph + 5000 + self.height() / 2)

    def getAltimeter(self):
        return self._altimeter

    def setAltimeter(self, altimeter):
        print(altimeter)
        if altimeter != self._altimeter:
            self._altimeter = altimeter
            self.redraw()

    altimeter = property(getAltimeter, setAltimeter)
Ejemplo n.º 19
0
    class MyGraphicsView(QGraphicsView):
        zoom_signal = pyqtSignal(bool)

        def __init__(self, parent=None):
            super().__init__(parent)

            self._scene = QGraphicsScene(backgroundBrush=Qt.gray)
            self._zoom = 0

            self.setScene(self._scene)
            self.setTransformationAnchor(QGraphicsView.NoAnchor)
            #self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)
            self.setResizeAnchor(QGraphicsView.AnchorUnderMouse)
            self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
            self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
            self.setBackgroundBrush(QBrush(QColor(30, 30, 30)))
            self.setFrameShape(QFrame.NoFrame)
            self.setSizePolicy(
                QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding))

            button = MyGraphicsButtonItem()
            self._scene.addItem(button)

            text = self._scene.addText('Hello, World!', QFont('Arial', 20))
            text.setDefaultTextColor(Qt.white)
            text.setFlag(QGraphicsItem.ItemIsMovable)  # Movable text.

            self.startPos = None

        def mousePressEvent(self, event):
            if event.modifiers() & Qt.ControlModifier and event.button(
            ) == Qt.LeftButton:
                self.startPos = event.pos()
            else:
                super().mousePressEvent(event)

        def mouseMoveEvent(self, event):
            if self.startPos is not None:
                delta = self.startPos - event.pos()

                # Get the current transformation (which is a matrix that includes the scaling ratios m11 refers to the horizontal scale, m22 to the vertical scale).
                transform = self.transform()

                # Divide the delta by their corresponding ratio.
                deltaX = delta.x() / transform.m11()
                deltaY = delta.y() / transform.m22()

                # Translate the current sceneRect by the delta.
                self.setSceneRect(self.sceneRect().translated(deltaX, deltaY))

                self.startPos = event.pos()
            else:
                super().mouseMoveEvent(event)

        def mouseReleaseEvent(self, event):
            self.startPos = None
            super().mouseReleaseEvent(event)
Ejemplo n.º 20
0
    def set_signal(self):
        indx = self.ui.combobox_signals.currentIndex()
        if indx != 0:
            self.ui.inpt.setReadOnly(True)
        else:
            self.ui.inpt.setReadOnly(False)
            self.ui.inpt.setText("10010110")
            self.decoder_update()
            return

        signal = self.signals[indx - 1]
        pa = ProtocolAnalyzer(signal)
        pa.get_protocol_from_signal()
        self.ui.inpt.setText("".join(pa.decoded_proto_bits_str))

        tmp_scene = QGraphicsScene()
        tmp_scene.addText(self.tr("Loading Signal..."))
        QApplication.setOverrideCursor(Qt.WaitCursor)
        self.ui.graphicsView_signal.setScene(tmp_scene)
        QApplication.processEvents()

        # scene = ZoomableScene()
        if signal is not None:
            last_block = pa.blocks[-1]
            lookup = pa.bit_sample_pos
            plot_data = signal.qad[lookup[0][0]:lookup[pa.num_blocks -
                                                       1][len(last_block) - 1]]
            self.ui.graphicsView_signal.plot_data(plot_data)
            # num_samples = len(plot_data)
            # minimum = -numpy.max(plot_data)
            # maximum = -numpy.min(plot_data)
            # scene.setSceneRect(0, minimum, num_samples, maximum - minimum)
            # scene.setBackgroundBrush(constants.BGCOLOR)
            # scene.addLine(0, 0, num_samples, 0, constants.AXISCOLOR)
            # precise_path = path_creator.create_precise_path(plot_data)
            # for subpath in precise_path:
            #     scene.addPath(subpath, constants.LINECOLOR)

        # self.ui.graphicsView_signal.setScene(scene)
        # self.ui.graphicsView_signal.update()
        # self.ui.graphicsView_signal.scale(1, 1)
        self.ui.graphicsView_signal.centerOn(0, 0)
        QApplication.restoreOverrideCursor()
Ejemplo n.º 21
0
def main(argv):
    signal.signal(signal.SIGINT, signal.SIG_DFL)

    app = QApplication([])
    scene = QGraphicsScene()
    view = QGraphicsView()

    thumbnails = []
    for filename in os.listdir(argv[1]):
        filename = os.path.join(argv[1], filename)
        print(filename)
        thumbnails.append(DBusThumbnailer.thumbnail_from_filename(filename, "large"))

    count = 0
    items = []
    for y in range(0, 100000, 150):
        for x in range(0, 2500, 150):
            scene.addRect(x, y, 128, 128)

            # image = QImage(128, 128, QImage.Format_RGB32)
            if count < len(thumbnails):
                print(thumbnails[count])
                image = QImage(thumbnails[count])
            else:
                arr = numpy.random.randint(0, 2**32, (128, 128), dtype=numpy.uint32)
                image = QImage(arr, 128, 128, 128 * 4, QImage.Format_ARGB32)
            pixmap = QPixmap.fromImage(image)

            item = QGraphicsPixmapItem(pixmap)
            scene.addItem(item)

            text = scene.addText("Test Textual: {}".format(count))
            item.setPos(x, y)
            text.setPos(x, y + 128)
            count += 1

            item.setFlags(QGraphicsItem.ItemIsSelectable)
            item.setAcceptHoverEvents(True)

            items.append([item, text])
    print(count)

    if False:
        random.shuffle(items)
        i = 0
        for y in range(0, 100000, 150):
            for x in range(0, 2500, 150):
                for item in items[i]:
                        item.setPos(x, y)
                i += 1

    view.setScene(scene)
    view.resize(800, 600)
    view.show()
    app.exec()
Ejemplo n.º 22
0
    def ItemsInit(self, scene: QGraphicsScene):
        ic = len(self.Inputs())
        oc = len(self.Outputs())
        m = max(ic, oc) * 10
        self.windowRect.setHeight(m * 2 + 20)
        ins = self.Inputs()
        ino = 20 + m - ic * 10
        ouo = 20 + m - oc * 10

        pix = scene.addPixmap(self.icon)
        pix.setPos(
            (self.windowRect.width() - self.icon.width()) * 0.5,
            20 + (self.windowRect.height() - 20 - self.icon.height()) * 0.5)
        pix.setParentItem(self.item)

        for i in range(0, ic):
            ti = scene.addText(ins[i])
            ti.setPos(0, i * 20 + ino)
            ti.setParentItem(self.item)
            ie = scene.addEllipse(
                QRectF(QPointF(-5, i * 20 + 5 + ino), QSizeF(10, 10)))
            ie.setParentItem(self.item)
            ie.setFlag(QGraphicsItem.ItemNegativeZStacksBehindParent)
            ie.setZValue(-1)

        ins = self.Outputs()
        for i in range(0, oc):
            ti = scene.addText(ins[i])
            ti.setPos(
                QPointF(self.windowRect.width() - ti.boundingRect().width(),
                        i * 20 + ouo))
            ti.setParentItem(self.item)
            ie = scene.addEllipse(
                QRectF(QPointF(self.windowRect.width() - 5, i * 20 + 5 + ouo),
                       QSizeF(10, 10)))
            ie.setParentItem(self.item)
            ie.setFlag(QGraphicsItem.ItemNegativeZStacksBehindParent)
            ie.setZValue(-1)

        self.inputs = []
        for i in range(0, ic):
            self.inputs.append(NodeConnector())
Ejemplo n.º 23
0
    def update_pics_with_path(self):

        self.lineDic.setText(self.FolderPath)
        self.picsPaths=self.filterImgs(self.picsPaths)

        widget=QWidget()
        layout = QGridLayout()
        widget.setLayout(layout)
    
        
        rows = int((len(self.picsPaths)/3))
        if (len(self.picsPaths)%3) > 0:
            rows+=1
        posis = [(j,k) for k in range(3) for j in range(rows)]

        for pos,picPath,i in zip(posis,self.picsPaths,range(len(self.picsPaths))):
            #print()
            picView = QGraphicsView(objectName = "img"+str(i))
            picView.setToolTip(self.FolderPath+"/"+picPath)
            layout.addWidget(picView,*pos)
            scene = QGraphicsScene()

            if QPixmap(self.FolderPath+"/"+picPath).isNull() != True:
                scene.addPixmap(QPixmap(self.FolderPath+"/"+picPath).scaled(140, 140, Qt.KeepAspectRatio))
            else:
                print(picPath)
                scene.addText("Bild konnte nicht\ngeladen werden",QFont("Times", 10)) 

            picView.setScene(scene)
            picView.setFixedSize(150,150)

        
        layout.setVerticalSpacing(10)
        self.scroll.setWidget(widget)
        
        i = 0
        while self.scroll.findChild(QGraphicsView,"img"+str(i)) != None:
            self.scroll.findChild(QGraphicsView,"img"+str(i)).mouseReleaseEvent=functools.partial(self.buttonReleased,i)
            i +=1
Ejemplo n.º 24
0
class Cad2dMainWindow(QMainWindow, Ui_MainWindow):
    """
    Class documentation goes here.
    """
    def __init__(self, parent=None):
        """
        Constructor
        
        @param parent reference to the parent widget
        @type QWidget
        """
        super(Cad2dMainWindow, self).__init__(parent)
        self.setupUi(self)
        # 透過繼承 ui_MainWindow 物件, 已經擁有 self.graphicsView 成員物件
        self.scene = QGraphicsScene()
        # 在 scene 中加入繪圖元件
        # 字串
        '''
        self.scene.addText("Hello, world!")
        # 矩形
        self.scene.addRect(QRectF(0, 0, 100, 100))
        # 畫直線
        self.scene.addItem(
            QGraphicsLineItem(QLineF(100,  100,  200,  300)))
        '''
        # 將畫面設定在視圖中
        self.graphicsView.setScene(self.scene)

    def mousePressEvent(self, event):
        self._start = event.pos()
        self.update()
        if event.button()==Qt.LeftButton:
            point=QPointF(event.pos().x(), event.pos().y())
            self.scene.addText(str(event.pos().x())+","+str(event.pos().y())).setPos(point)
        super(Cad2dMainWindow, self).mousePressEvent(event)
        
    def mouseReleaseEvent(self, event):
        print("mouse release event")
Ejemplo n.º 25
0
    def mostrar(self, raiz):
        scene = QGraphicsScene()

        elipse = scene.addEllipse(0, 0, 100, 50)
        elipse.setBrush(QColor(245, 235, 255))

        text = scene.addText(raiz.getRaiz())

        text1 = scene.addText("RAIZ")

        self.raiz = Nodo(elipse, [text, text1])

        self.conteo = np.zeros(self.controlador.getNAtributos() + 1)
        self.conteo[0] = 2

        if (raiz.getHijos()):
            self.recurrir(raiz.getHijos(), 0, scene, self.raiz)
            self.redim(self.raiz, 0, scene)
            self.unir(self.raiz, scene)

        self.ui.viewer.setScene(scene)
        self.ui.viewer.show()
        self.ui.viewer.verticalScrollBar().setValue(self.ui.viewer.verticalScrollBar().minimum())
        self.ui.viewer.horizontalScrollBar().setValue(int(self.ui.viewer.horizontalScrollBar().maximum() / 2))
Ejemplo n.º 26
0
class RecordsetWindow(QWidget):

    dataDisplayRequest = pyqtSignal(str, int)
    dataUpdateRequest = pyqtSignal(str, Base)

    # sensorsColor = ['e0c31e', '14148c', '006325', '6400aa', '14aaff', 'ae32a0', '80c342', '868482']

    def __init__(self, manager, recordset: list, parent=None):
        super(QWidget, self).__init__(parent=parent)
        self.UI = Ui_frmRecordsets()
        self.UI.setupUi(self)

        self.sensors = {}
        self.sensors_items = {}
        self.sensors_graphs = {}

        self.time_pixmap = False

        self.time_bar = None

        self.dbMan = manager
        self.recordsets = recordset

        # Init temporal browser
        self.timeScene = QGraphicsScene()
        self.UI.graphTimeline.setScene(self.timeScene)
        self.UI.graphTimeline.fitInView(self.timeScene.sceneRect(),
                                        Qt.KeepAspectRatio)
        self.UI.graphTimeline.time_clicked.connect(self.timeview_clicked)

        # Update general informations about recordsets
        self.update_recordset_infos()

        # Load sensors for that recordset
        self.load_sensors()

        self.UI.lstSensors.itemChanged.connect(self.sensor_current_changed)

        # self.UI.frmSensors.setFixedHeight(self.height()-50)

    def paintEvent(self, paint_event):
        if not self.time_pixmap:
            self.draw_recordsets()
            self.draw_sensors()
            self.draw_dates()
            self.draw_timebar()
            self.time_pixmap = True

    def resizeEvent(self, resize_event):

        self.draw_recordsets()
        self.draw_sensors()
        self.draw_dates()
        self.draw_timebar()

    def load_sensors(self):
        self.UI.lstSensors.clear()
        self.sensors = {}
        self.sensors_items = {}

        # Create sensor colors
        # colors = QColor.colorNames()
        colors = [
            'darkblue', 'darkviolet', 'darkgreen', 'darkorange', 'darkred',
            'darkslategray', 'darkturquoise', 'darkolivegreen', 'darkseagreen',
            'darkmagenta', 'darkkhaki', 'darkslateblue', 'darksalmon',
            'darkorchid', 'darkcyan'
        ]

        # Filter "bad" colors for sensors
        """colors.remove("white")
        colors.remove("black")
        colors.remove("transparent")
        colors.remove("red")
        colors.remove("green")"""

        # shuffle(colors)
        color_index = 0

        if len(self.recordsets) > 0:
            for sensor in self.dbMan.get_sensors(self.recordsets[0]):
                self.sensors[sensor.id_sensor] = sensor

        for sensor in self.sensors.values():
            index = -1
            location_item = self.UI.lstSensors.findItems(
                sensor.location, Qt.MatchExactly)
            if len(location_item) == 0:
                item = QListWidgetItem(sensor.location)
                item.setFlags(Qt.NoItemFlags)
                item.setForeground(QBrush(Qt.black))

                self.UI.lstSensors.addItem(item)
            else:
                index = self.UI.lstSensors.indexFromItem(
                    location_item[0]).row()

            # Check if sensor is already there under that location item
            sensor_name = sensor.name + " (" + sensor.hw_name + ")"
            present = False
            if index != -1:
                for i in range(index, self.UI.lstSensors.count()):
                    if self.UI.lstSensors.item(i).text() == sensor_name:
                        present = True
                        break

            if not present:
                item = QListWidgetItem(QIcon(':/OpenIMU/icons/sensor.png'),
                                       sensor_name)
                item.setCheckState(Qt.Unchecked)
                item.setForeground(QColor(colors[color_index]))
                item.setData(Qt.UserRole, sensor.id_sensor)
                # self.sensors_colors.append(colors[color_index])
                self.sensors_items[sensor.id_sensor] = item
                color_index += 1
                if color_index >= len(colors):
                    color_index = 0

                if index == -1:
                    self.UI.lstSensors.addItem(item)
                else:
                    self.UI.lstSensors.insertItem(index + 2, item)

    def update_recordset_infos(self):
        if len(self.recordsets) == 0:
            self.UI.lblTotalValue.setText("Aucune donnée.")
            self.UI.lblDurationValue.setText("Aucune donnée.")
            return

        start_time = self.recordsets[0].start_timestamp
        end_time = self.recordsets[len(self.recordsets) - 1].end_timestamp

        # Coverage
        self.UI.lblTotalValue.setText(
            start_time.strftime('%d-%m-%Y %H:%M:%S') + " @ " +
            end_time.strftime('%d-%m-%Y %H:%M:%S'))

        # Duration
        self.UI.lblDurationValue.setText(str(end_time - start_time))

        self.UI.lblCursorTime.setText(start_time.strftime('%d-%m-%Y %H:%M:%S'))

    def get_relative_timeview_pos(self, current_time):
        start_time = self.recordsets[0].start_timestamp.timestamp()
        end_time = self.recordsets[len(self.recordsets) -
                                   1].end_timestamp.timestamp()
        time_span = (end_time - start_time
                     )  # Total number of seconds in recordsets
        if type(current_time) is datetime:
            current_time = current_time.timestamp()

        if time_span > 0:
            return ((current_time - start_time) /
                    time_span) * self.UI.graphTimeline.width()
        else:
            return 0

    def draw_dates(self):
        if len(self.recordsets) == 0:
            return

        # Computations
        start_time = self.recordsets[0].start_timestamp
        end_time = self.recordsets[len(self.recordsets) - 1].end_timestamp
        # time_span = (end_time - start_time).total_seconds()  # Total number of seconds in recordsets
        current_time = (datetime(start_time.year, start_time.month,
                                 start_time.day, 0, 0, 0) + timedelta(days=1))

        # Drawing tools
        whitePen = QPen(Qt.white)
        blackPen = QPen(Qt.black)
        blackBrush = QBrush(Qt.black)

        # Date background rectangle
        self.timeScene.addRect(0, 0, self.UI.graphTimeline.width(),
                               self.UI.graphTimeline.height() / 4, blackPen,
                               blackBrush)

        # First date
        date_text = self.timeScene.addText(start_time.strftime("%d-%m-%Y"))
        date_text.setPos(0, -5)
        date_text.setDefaultTextColor(Qt.white)
        self.timeScene.addLine(0, 0, 0, self.UI.graphTimeline.height(),
                               whitePen)

        # Date separators
        while current_time <= end_time:
            pos = self.get_relative_timeview_pos(current_time)
            self.timeScene.addLine(pos, 0, pos, self.UI.graphTimeline.height(),
                                   whitePen)
            date_text = self.timeScene.addText(
                current_time.strftime("%d-%m-%Y"))
            date_text.setPos(pos, -5)
            date_text.setDefaultTextColor(Qt.white)
            current_time += timedelta(days=1)

    def draw_recordsets(self):
        greenBrush = QBrush(QColor(212, 247, 192))
        transPen = QPen(Qt.transparent)

        # Empty rectangle (background)
        self.timeScene.addRect(0, 0, self.UI.graphTimeline.width(),
                               self.UI.graphTimeline.height(), transPen,
                               QBrush(Qt.red))
        self.timeScene.setBackgroundBrush(QBrush(Qt.black))

        # Recording length
        for record in self.recordsets:
            start_pos = self.get_relative_timeview_pos(record.start_timestamp)
            end_pos = self.get_relative_timeview_pos(record.end_timestamp)
            span = end_pos - start_pos
            # print (str(span))
            self.timeScene.addRect(start_pos, 0, span,
                                   self.UI.graphTimeline.height(), transPen,
                                   greenBrush)

        self.UI.graphTimeline.update()

    def draw_sensors(self):
        if len(self.sensors) == 0:
            return

        bar_height = (3 *
                      (self.UI.graphTimeline.height() / 4)) / len(self.sensors)
        # for sensor in self.sensors:
        i = 0
        for sensor in self.sensors.values():
            sensorBrush = QBrush(
                self.sensors_items[sensor.id_sensor].foreground())
            sensorPen = QPen(Qt.transparent)
            for record in self.recordsets:
                datas = self.dbMan.get_all_sensor_data(
                    sensor=sensor,
                    recordset=record,
                    channel=sensor.channels[0])
                for data in datas:
                    start_pos = self.get_relative_timeview_pos(
                        data.timestamps.start_timestamp)
                    end_pos = self.get_relative_timeview_pos(
                        data.timestamps.end_timestamp)
                    span = max(end_pos - start_pos, 1)
                    self.timeScene.addRect(
                        start_pos,
                        i * bar_height + (self.UI.graphTimeline.height() / 4),
                        span, bar_height, sensorPen, sensorBrush)
            i += 1

    def draw_timebar(self):
        self.time_bar = self.timeScene.addLine(0, 0, 0,
                                               self.timeScene.height(),
                                               QPen(Qt.cyan))

    @pyqtSlot(QListWidgetItem)
    def sensor_current_changed(self, item):
        sensor = self.sensors[item.data(Qt.UserRole)]
        timeseries = []
        # Color map
        colors = [Qt.red, Qt.green, Qt.yellow, Qt.cyan]

        if item.checkState() == Qt.Checked:
            # Choose the correct display for each sensor
            graph = None
            channels = self.dbMan.get_all_channels(sensor=sensor)
            for channel in channels:
                # Will get all data (converted to floats)
                channel_data = []
                for record in self.recordsets:
                    channel_data += self.dbMan.get_all_sensor_data(
                        recordset=record,
                        convert=True,
                        sensor=sensor,
                        channel=channel)
                timeseries.append(self.create_data_timeseries(channel_data))
                timeseries[-1]['label'] = channel.label

            if sensor.id_sensor_type == SensorType.ACCELEROMETER \
                    or sensor.id_sensor_type == SensorType.GYROMETER \
                    or sensor.id_sensor_type == SensorType.BATTERY \
                    or sensor.id_sensor_type == SensorType.LUX \
                    or sensor.id_sensor_type == SensorType.CURRENT \
                    or sensor.id_sensor_type == SensorType.BAROMETER \
                    or sensor.id_sensor_type == SensorType.MAGNETOMETER \
                    or sensor.id_sensor_type == SensorType.TEMPERATURE \
                    or sensor.id_sensor_type == SensorType.HEARTRATE \
                    or sensor.id_sensor_type == SensorType.ORIENTATION \
                    or sensor.id_sensor_type == SensorType.FSR:

                #graph = IMUChartView(self.UI.displayContents)
                graph = IMUChartView(self.UI.mdiArea)
                # graph.add_test_data()
                # Add series
                for series in timeseries:
                    graph.add_data(series['x'],
                                   series['y'],
                                   color=colors.pop(),
                                   legend_text=series['label'])

                graph.set_title(item.text())

            if sensor.id_sensor_type == SensorType.GPS:
                # graph = GPSView(self.UI.mdiArea)
                """base_widget = QWidget(self.UI.displayContents)
                base_widget.setFixedHeight(400)
                base_widget.setMaximumHeight(400)"""
                base_widget = self.UI.mdiArea
                graph = GPSView(base_widget)

                for data in channel_data:
                    gps = GPSGeodetic()
                    gps.from_bytes(data.data)
                    if gps.latitude != 0 and gps.longitude != 0:
                        graph.addPosition(data.timestamps.start_timestamp,
                                          gps.latitude / 1e7,
                                          gps.longitude / 1e7)
                        graph.setCursorPositionFromTime(
                            data.timestamps.start_timestamp)
                    # print (gps)

            if graph is not None:
                self.UI.mdiArea.addSubWindow(graph).setWindowTitle(item.text())
                self.sensors_graphs[sensor.id_sensor] = graph
                #self.UI.displayContents.layout().insertWidget(0,graph)

                graph.show()
                QApplication.instance().processEvents()

                graph.aboutToClose.connect(self.graph_was_closed)
                graph.cursorMoved.connect(self.graph_cursor_changed)

                #self.UI.displayArea.ensureWidgetVisible(graph)
                # self.UI.displayArea.verticalScrollBar().setSliderPosition(self.UI.displayArea.verticalScrollBar().maximum())
                # self.tile_graphs_vertically()
                self.UI.mdiArea.tileSubWindows()

        else:
            # Remove from display
            try:
                if self.sensors_graphs[sensor.id_sensor] is not None:
                    self.UI.mdiArea.removeSubWindow(
                        self.sensors_graphs[sensor.id_sensor].parent())
                    self.sensors_graphs[sensor.id_sensor].hide()
                    self.sensors_graphs[sensor.id_sensor] = None
                    # self.tile_graphs_vertically()
                    self.UI.mdiArea.tileSubWindows()
            except KeyError:
                pass

    @pyqtSlot(QObject)
    def graph_was_closed(self, graph):
        for sensor_id, sensor_graph in self.sensors_graphs.items():
            if sensor_graph == graph:
                self.sensors_graphs[sensor_id] = None
                self.sensors_items[sensor_id].setCheckState(Qt.Unchecked)
                break

        # self.tile_graphs_vertically()
        self.UI.mdiArea.tileSubWindows()

    @pyqtSlot(float)
    def graph_cursor_changed(self, timestamp):
        for graph in self.sensors_graphs.values():
            if graph is not None:
                graph.setCursorPositionFromTime(timestamp / 1000, False)

        pos = self.get_relative_timeview_pos(timestamp / 1000)
        self.time_bar.setPos(pos, 0)

        self.UI.lblCursorTime.setText(
            datetime.fromtimestamp(timestamp /
                                   1000).strftime('%d-%m-%Y %H:%M:%S'))

    @pyqtSlot(int)
    def timeview_clicked(self, x):
        self.time_bar.setPos(x, 0)

        # Find time corresponding to that position
        timestamp = (x / self.UI.graphTimeline.width()) * (
            self.recordsets[len(self.recordsets) - 1].end_timestamp - self.
            recordsets[0].start_timestamp) + self.recordsets[0].start_timestamp
        self.UI.lblCursorTime.setText(timestamp.strftime('%d-%m-%Y %H:%M:%S'))

        for graph in self.sensors_graphs.values():
            if graph is not None:
                # try:
                graph.setCursorPositionFromTime(timestamp, True)
            # except AttributeError:
            #    continue

    @timing
    def create_data_timeseries(self, sensor_data_list: list):

        time_values = []
        data_values = []

        for sensor_data in sensor_data_list:
            # print('sensor_data', sensor_data)
            # Will get a dict with keys:  time, values
            vals = sensor_data.to_time_series()
            # print('vals is length', len(vals))
            time_values.append(vals['time'])
            data_values.append(vals['values'])

        # print('time_values length', len(time_values))
        # print('data_values length', len(data_values))

        # Concat vectors
        time_array = np.concatenate(time_values)
        data_array = np.concatenate(data_values)

        # Test, remove first time
        # time_array = time_array - time_array[0]

        # print('time_array_shape, data_array_shape', time_array.shape, data_array.shape)
        # return data
        return {'x': time_array, 'y': data_array}

    @pyqtSlot()
    def on_process_recordset(self):
        # Display Process Window
        window = ProcessSelectWindow(self.dbMan, self.recordsets)
        window.setStyleSheet(self.styleSheet())

        if window.exec() == QDialog.Accepted:
            self.dataUpdateRequest.emit("result", window.processed_data)
            self.dataDisplayRequest.emit(
                "result", window.processed_data.id_processed_data)

    def tile_graphs_horizontally(self):

        if self.UI.mdiArea.subWindowList() is None:
            return

        position = QPoint(0, 0)

        for window in self.UI.mdiArea.subWindowList():
            rect = QRect(
                0, 0,
                self.UI.mdiArea.width() / len(self.UI.mdiArea.subWindowList()),
                self.UI.mdiArea.height())
            window.setGeometry(rect)
            window.move(position)
            position.setX(position.x() + window.width())

    def tile_graphs_vertically(self):

        if self.UI.mdiArea.subWindowList() is None:
            return

        position = QPoint(0, 0)

        for window in self.UI.mdiArea.subWindowList():
            rect = QRect(
                0, 0, self.UI.mdiArea.width(),
                self.UI.mdiArea.height() /
                len(self.UI.mdiArea.subWindowList()))
            window.setGeometry(rect)
            window.move(position)
            position.setY(position.y() + window.height())
Ejemplo n.º 27
0
class MonitorGraphicsView(QGraphicsView, AllowDrop):
    monitorWin = None

    SIZE = (50.0, 50.0)
    FULLSPEED = 512 * 1024 # 512 in kb/s

    _progressText = None
    _speedsPolygon = None
    _speedsPen = None
    _speedsBrush = None

    def __init__(self, parent = None):
        super().__init__(parent)
        self.monitorWin = parent
        if self.monitorWin:
            self.monitorWin.sigTaskUpdating.connect(self.slotTaskUpdate)

        self.scene = QGraphicsScene(self)
        self.scene.setSceneRect(0, 0, self.SIZE[0], self.SIZE[1])
        self.setScene(self.scene)

        self._speedsPen = QPen(Qt.white)

        gradient = QLinearGradient(0, 0, self.SIZE[0], self.SIZE[1])
        gradient.setColorAt(0.0, Qt.darkGreen)
        gradient.setColorAt(1.0, Qt.yellow)
        self._speedsBrush = QBrush(gradient)

        # add elements to the scene
        self._speedsPolygon = self.scene.addPolygon(QPolygonF(),
                                                    self._speedsPen,
                                                    self._speedsBrush)
        self._progressText = self.scene.addText("")
        self._progressText.setPos(10, 0)

        self.setupDropSupport()

    def mousePressEvent(self, qMouseEvent):
        self.monitorWin.mousePressEvent(qMouseEvent)

    def mouseMoveEvent(self, qMouseEvent):
        self.monitorWin.mouseMoveEvent(qMouseEvent)

    def mouseReleaseEvent(self, qMouseEvent):
        self.monitorWin.mouseReleaseEvent(qMouseEvent)

    def _setSpeeds(self, speeds):
        polygon = QPolygonF()
        polygon.append(QPointF(0, self.SIZE[1])) # start the polygon

        nSamples = len(speeds)
        xPerSample = self.SIZE[0] / nSamples

        for i, speed in enumerate(speeds):
            y = self._translateSpeedToPosY(speed)
            polygon.append(QPointF(xPerSample * i, y))
            polygon.append(QPointF(xPerSample * (i+1), y))
        polygon.append(QPointF(*self.SIZE)) # close the polygon

        self._speedsPolygon.setPolygon(polygon)

    def _setProgress(self, process): # 10000 means 100%
        if process is None:
            self._progressText.setPlainText("")
        else:
            self._progressText.setPlainText("{:.1f}%".format(process / 100))

    def _translateSpeedToPosY(self, speed):
        return self.SIZE[1] * (1.0 - speed / self.FULLSPEED)

    @pyqtSlot(dict)
    def slotTaskUpdate(self, task):
        if task:
            self._setProgress(task["progress"])
            self._setSpeeds(task["speeds"])
        else:
            self._setProgress(None)
            self._setSpeeds([0.0])
Ejemplo n.º 28
0
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        self.newDetectionAvailable = False
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(820, 620)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")

        self.dropdown_menu = QComboBox(self.centralwidget)
        font = QtGui.QFont()
        font.setPointSize(20)
        self.dropdown_menu.setFont(font)
        self.dropdown_menu.setGeometry(QtCore.QRect(540, 540, 240, 50))
        self.robot_index = 0
        for name_ip in NAME_IP_LIST:
            text = name_ip[0] + ': ' + name_ip[1]
            self.dropdown_menu.addItem(text)
        self.ip_addr = NAME_IP_LIST[0][1]

        self.server_running = True
        self.server_thread = threading.Thread(target=self.server)
        self.server_thread.start()

        font = QtGui.QFont()
        font.setPointSize(20)
        self.graphicsView = QtWidgets.QGraphicsView(self.centralwidget)
        self.graphicsView.setGeometry(QtCore.QRect(10, 10, 800, 431))
        self.graphicsView.setObjectName("graphicsView")
        self.StandardButton = QtWidgets.QPushButton(self.centralwidget)
        self.StandardButton.setGeometry(QtCore.QRect(60, 470, 170, 60))
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum,
                                           QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.StandardButton.sizePolicy().hasHeightForWidth())
        self.StandardButton.setSizePolicy(sizePolicy)
        font = QtGui.QFont()
        font.setPointSize(20)
        self.StandardButton.setFont(font)
        self.StandardButton.setObjectName("StandardButton")
        self.AdvancedButton = QtWidgets.QPushButton(self.centralwidget)
        self.AdvancedButton.setGeometry(QtCore.QRect(570, 470, 170, 60))
        font = QtGui.QFont()
        font.setPointSize(20)
        self.AdvancedButton.setFont(font)
        self.AdvancedButton.setObjectName("AdvancedButton")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 22))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        self.LCD = QLCDNumber(self.centralwidget)
        self.LCD.setGeometry(QtCore.QRect(350, 480, 100, 40))
        self.LCD.display(0)
        self.LCD.setStyleSheet(
            'QLCDNumber {background-color: green; color: red;}')

        self.clockLCD = QLCDNumber(self.centralwidget)
        self.clockLCD.setGeometry(QtCore.QRect(350, 540, 100, 40))
        self.clockLCD.display('3:00')
        self.clockLCD.setStyleSheet(
            'QLCDNumber {background-color: yellow; color: red;}')

        self.scene = QGraphicsScene()
        self.graphicsView.setScene(self.scene)
        greenBrush = QBrush(Qt.green)  #2 single healthy
        yellowBrush = QBrush(Qt.yellow)  #1 single stressed
        whiteBrush = QBrush(Qt.white)  #0 empty
        blueBrush = QBrush(Qt.blue)  #3 double
        pinkBrush = QBrush(Qt.magenta)  #4 tiller
        self.blackPen = QPen(Qt.black)
        self.BrushList = [
            whiteBrush, yellowBrush, greenBrush, blueBrush, pinkBrush,
            QBrush(Qt.black)
        ]
        self.colorNames = [
            'Empty', 'Stressed', 'Healthy', 'Double', 'Tiller', 'Detection'
        ]

        self.level = 0  #standard
        self.newDetectionAvailable = False
        self.detectedFieldConfig = 5 * np.ones((4, 16), dtype=np.int8)
        self.fieldConfig = self.randFieldConfig()

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
        self.AdvancedButton.clicked.connect(self.AdvBtnClickedSlot)
        self.StandardButton.clicked.connect(self.StdBtnClickedSlot)
        self.StdBtnClickedSlot()
        self.drawPlants()

        self.drawing_timer = QTimer()
        self.drawing_timer.setInterval(50)
        self.drawing_timer.timeout.connect(self.updateDetectionResult)
        self.drawing_timer.start()

        self.clock_seconds = 0
        self.timestamp = '0:00'
        self.clock_timer = QTimer()
        self.clock_timer.setInterval(1000)
        self.clock_timer.timeout.connect(self.updateClock)
        self.clock_timer.start()
        self.time_is_up = False
        app.aboutToQuit.connect(self.closeEvent)

    def updateClock(self):
        if self.clock_seconds >= 300:
            if self.clock_seconds % 2 == 0:
                self.clockLCD.setStyleSheet(
                    'QLCDNumber {background-color: yellow; color: red;}')
            else:
                self.clockLCD.setStyleSheet(
                    'QLCDNumber {background-color: white; color: red;}')
            self.clockLCD.display('5:00')
            self.time_is_up = True
        else:
            self.timestamp = str(self.clock_seconds // 60) + ':'
            sec = self.clock_seconds % 60
            self.timestamp += '0' + str(sec) if sec < 10 else str(sec)
            self.clockLCD.display(self.timestamp)
        self.clock_seconds += 1

    def updateDetectionResult(self):
        if self.newDetectionAvailable:
            self.drawPlants()
            self.newDetectionAvailable = False

    def closeEvent(self):
        self.server_running = False
        self.server_thread.join()

    def server(self):
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
            s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            s.bind(('', PORT))
            while self.server_running:
                try:
                    s.settimeout(1)
                    s.listen(1)
                    c, addr = s.accept()
                    if addr[0] != self.ip_addr:
                        c.close()
                        continue
                    with c:
                        while self.server_running:
                            try:
                                c.settimeout(5)
                                msg = c.recv(1024)
                                if len(msg) != 64:
                                    c.close()
                                    print('invalid msg')
                                    break
                                if not self.time_is_up:
                                    text = msg.decode('utf-8')
                                    self.detectedFieldConfig = np.reshape(
                                        np.array(list(text), dtype=np.int8),
                                        (4, 16))
                                    upper_limit = 3 if self.level == 0 else 5
                                    self.detectedFieldConfig[
                                        (self.detectedFieldConfig < 0) |
                                        (self.detectedFieldConfig >=
                                         upper_limit)] = 5
                                    self.newDetectionAvailable = True
                                    #f = open("log.txt", "a")
                                    #f.write(self.ip_addr+','+self.timestamp+','+msg)
                                    #f.close()
                            except socket.timeout:
                                print('client stopped sending updates')
                                c.close()
                                break
                            except socket.error as exc:
                                print(exc)
                                c.close()
                                break
                except socket.timeout:
                    pass
            s.close()

    def drawPlants(self):
        size = 20
        hor_space = 40
        ver_space = 100
        self.scene.clear()
        for y in range(4):
            for x in range(16):
                plant_type = self.fieldConfig.item((y, x))
                r = QtCore.QRectF(QtCore.QPointF(x * hor_space, y * ver_space),
                                  QtCore.QSizeF(size, size))
                self.scene.addRect(r, self.blackPen,
                                   self.BrushList[plant_type])
                detected_plant_type = self.detectedFieldConfig.item((y, x))
                self.scene.addEllipse(x * hor_space, y * ver_space + 30, size,
                                      size, self.blackPen,
                                      self.BrushList[detected_plant_type])

        # separation line
        self.scene.addLine(
            QtCore.QLineF(16.4 * hor_space, 0, 16.4 * hor_space, 350))
        # draw a legend
        for i in range(3 if self.level == 0 else 5):
            r = QtCore.QRectF(
                QtCore.QPointF(17 * hor_space, i * ver_space / 2),
                QtCore.QSizeF(size, size))
            self.scene.addRect(r, self.blackPen, self.BrushList[i])
            t = self.scene.addText(self.colorNames[i], QFont("Helvetica"))
            t.setPos(18 * hor_space, i * ver_space / 2)
        i = 3 if self.level == 0 else 5
        self.scene.addEllipse(17 * hor_space, i * ver_space / 2, size, size,
                              self.blackPen, self.BrushList[5])
        t = self.scene.addText(self.colorNames[5], QFont("Helvetica"))
        t.setPos(18 * hor_space, i * ver_space / 2)

        #calculate the score
        true_count_per_row = np.count_nonzero(
            np.logical_and(self.fieldConfig > 0, self.fieldConfig < 5),
            axis=1) + np.count_nonzero(self.fieldConfig == 3, axis=1)
        robot_count_per_row = np.count_nonzero(
            np.logical_and(self.detectedFieldConfig > 0,
                           self.detectedFieldConfig < 5),
            axis=1) + np.count_nonzero(self.detectedFieldConfig == 3, axis=1)
        # plant density score
        error_per_row = np.abs(true_count_per_row - robot_count_per_row)
        density_score = np.zeros(4, dtype=np.int32)
        density_score[error_per_row == 0] = 5
        density_score[error_per_row == 1] = 3
        density_score[error_per_row == 2] = 1
        correct_detections = self.fieldConfig[np.equal(
            self.fieldConfig, self.detectedFieldConfig)]
        points_for_empty_or_stress = 3 if self.level == 0 else 2
        detection_score = points_for_empty_or_stress * len(
            correct_detections[(correct_detections == 0) |
                               (correct_detections == 1)])

        if self.level == 1:
            detection_score += 4 * len(
                correct_detections[(correct_detections == 3) |
                                   (correct_detections == 4)])

        print(detection_score, density_score.sum())
        score = detection_score + density_score.sum()
        self.LCD.display(score)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(
            _translate("MainWindow", "2020 ASABE Robotics Competition"))
        self.StandardButton.setText(_translate("MainWindow", "Standard"))
        self.AdvancedButton.setText(_translate("MainWindow", "Advanced"))

    def initialize(self):
        self.fieldConfig = self.randFieldConfig()
        self.drawPlants()
        self.server_running = False
        self.server_thread.join()
        self.ip_addr = NAME_IP_LIST[self.dropdown_menu.currentIndex()][1]
        self.server_thread = threading.Thread(target=self.server)
        self.server_running = True
        self.server_thread.start()
        self.time_is_up = False
        self.clock_seconds = 0
        self.clockLCD.setStyleSheet(
            'QLCDNumber {background-color: yellow; color: red;}')

    def StdBtnClickedSlot(self):
        self.StandardButton.setStyleSheet("background-color: red")
        self.AdvancedButton.setStyleSheet("background-color: gray")
        self.level = 0
        self.initialize()

    def AdvBtnClickedSlot(self):
        self.AdvancedButton.setStyleSheet("background-color: red")
        self.StandardButton.setStyleSheet("background-color: gray")
        self.level = 1
        self.initialize()

    def randFieldConfig(self):
        #reset robot detection result
        self.detectedFieldConfig = 5 * np.ones((4, 16), dtype=np.int8)
        # standard
        # 0: empty, 12
        # 1: single stressed, 8
        # 2: single healthy, 44

        # advanced
        # 0: empty, 12
        # 1: single stressed, 8
        # 2: single healthuy, 36
        # 3: double, 4
        # 4: tiller, 4
        num_single_healthy_plants_per_row = 11 if self.level == 0 else 9
        single_healthy_block = 2 * np.ones(
            (4, num_single_healthy_plants_per_row), dtype=np.int8)
        num_abnormal_spots = 20 if self.level == 0 else 28
        abnormal_spots_array = np.zeros((1, num_abnormal_spots), dtype=np.int8)
        abnormal_spots_array[0, 12:20] = 1
        if self.level == 1:
            abnormal_spots_array[0, 20:24] = 3
            abnormal_spots_array[0, 24:28] = 4
        shuffle_by_row = np.vectorize(np.random.permutation,
                                      signature='(n)->(n)')
        abnormal_spots_array = shuffle_by_row(abnormal_spots_array)
        abnormal_block = np.reshape(abnormal_spots_array, (4, -1))
        fieldConfig = np.concatenate((single_healthy_block, abnormal_block),
                                     axis=1)
        fieldConfig = shuffle_by_row(fieldConfig)
        return fieldConfig
Ejemplo n.º 29
0
class main_window(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setGeometry(450, 200, 1000, 600)
        self.setWindowTitle("NRange")
        self.scene = QGraphicsScene()
        self.view = QGraphicsView(self.scene)
        self.interfejs()
        self.show()

    def interfejs(self):
        layout = QHBoxLayout()
        ### INPUTY PARAMETROW
        fieldsLayout = QGridLayout()     #layout dla prawej części
        rightHlayout = QVBoxLayout()
        itemsLayout = QVBoxLayout()     # g lowny layout

        self.Ptx = Parametr("Ptx", 0, 99, 0)
        self.Gtx = Parametr("Gtx", 0, 99, 0)
        self.Ftx = Parametr("Ftx", 0, 99, 0)
        self.Grx = Parametr("Grx", 0, 99, 0)
        self.Frx = Parametr("Frx", 0, 99, 0)
        self.SNR = Parametr("SNR", 0, 99, 0)
        self.bandwitch = Parametr("B", 0, 99, 0)
        self.Fnoise = Parametr("Fnoise", 0, 99, 0)
        self.Temp = Parametr("Temp [K]", 0, 999, 0)
        self.Freq = Parametr("Freq [MHz]", 1, 99999, 1)
        self.wyborModelu = modelComboBox("Model propagacyjny")

        fieldsLayout.addItem(self.wyborModelu,0,0)
        fieldsLayout.addItem(self.Ptx,1,0)
        fieldsLayout.addItem(self.Gtx,1,1)
        fieldsLayout.addItem(self.Ftx,1,2)
        fieldsLayout.addItem(self.Grx,2,0)
        fieldsLayout.addItem(self.Frx,2,1)
        fieldsLayout.addItem(self.SNR,2,2)
        fieldsLayout.addItem(self.bandwitch,3,0)
        fieldsLayout.addItem(self.Temp,3,1)
        fieldsLayout.addItem(self.Fnoise,3,2)
        fieldsLayout.addItem(self.Freq,4,0)
        fieldsLayout.setSpacing(20)
        #self.scene = QGraphicsScene()
        #scene.addText("ddddddddddddddddddddddddddddddddddddddddddddd")
        #view = QGraphicsView(self.scene)

        # oblcizanie
        calculateButton = QPushButton()
        calculateButton.setText("Oblicz zasięg")
        calculateButton.clicked.connect(lambda x: self.propagationModel())
        fieldsLayout.addWidget(calculateButton, 5, 2)

        layout.addWidget(self.view)
        self.view.show()
        # lewa strona
        #layout.addWidget(paintContainer)
        verticalSpacer = QSpacerItem(1, 50, QSizePolicy.Fixed, QSizePolicy.Expanding)
        fieldsLayout.addItem(verticalSpacer,5,0)
        fieldsLayout.setRowStretch(0, 1)
        fieldsLayout.setRowStretch(1, 1)
        fieldsLayout.setRowStretch(1, 1)

        itemsLayout.addItem(fieldsLayout)
        layout.addItem(itemsLayout)         # główny layout dzieli obszar na dwie czesci
        #self.Ptx = self.Ptx.container.text()
        #self.scene.addText(self.Ptx.container.text())
        self.setLayout(layout)

    def propagationModel(self, name='ddd'):
        # Lmax = Ptx + Gtx - Ftx + Grx - Frx - S/N - k*T*B - Fnoise - IM
        Ptx = self.Ptx.returnParameterValues()
        Gtx = self.Gtx.returnParameterValues()
        Ftx = self.Ftx.returnParameterValues()
        Grx = self.Grx.returnParameterValues()
        Frx = self.Frx.returnParameterValues()
        SNR = self.SNR.returnParameterValues()
        bandwitch = self.bandwitch.returnParameterValues()
        Temp = self.Temp.returnParameterValues()
        Fnoise = self.Fnoise.returnParameterValues()
        Freq = self.Freq.returnParameterValues()
        k = 1.38e-23
        Lmax = Ptx + Gtx - Ftx + Grx - Frx - SNR - k * bandwitch * Temp - Fnoise - 2

        ### obliczanie zasiegu
        fdB = 20 * math.log10(Freq)
        x = Lmax - 32.4 - fdB
        d = 10**(x/20)
        if name.lower() == 'wpp':
            return 0
        self.scene.clear()
        self.scene.addText(str(round(d*1000, 2)))
Ejemplo n.º 30
0
class panel(QGraphicsView):
    def __init__(self):
        super(panel, self).__init__()

        self.arbolito = None  #arbol de entornos

        self.y = 50  #posicion en y inicial
        self.escena = QGraphicsScene()  #escena de dibujo

        self.setScene(
            self.escena)  #asignamos la escena al QGraphicsView de la clase

    # -------------------------------------------------------------------------------------------------
    #           metodo que verifica cuando se hace click en la escena
    # -------------------------------------------------------------------------------------------------
    def mousePressEvent(self, event):
        print("clicked")
        x = event.pos().x()
        y = event.pos().y()
        print(x, y)
        pt = self.mapToScene(
            event.pos()
        )  #se escala la posicion de click del QGraphicsView a la escena (QGraphicsScene)

        root = self.arbolito.get_root()  #raiz del arbol
        if (root != None):
            rect = QRect(
                int(pt.x()), int(pt.y()), root.tam,
                root.tam)  # se crea un rectangulo para la colision con el nodo
            self.__colision(root, rect)

    # -------------------------------------------------------------------------------------------------
    #           metodo que verifica si el evento del click se realizo sobre algun nodo
    # -------------------------------------------------------------------------------------------------
    def __colision(self, nodo, rect):

        #si el nodo entrante fue el clickeado
        if nodo.rect.intersects(rect):

            #se muestra un mensaje
            #con la informacion del nodo-> nombre del procedimiento o funcion
            msg = QMessageBox()
            msg.setIcon(QMessageBox.Information)

            msg.setText("Nombre Ambiente: " + str(nodo.info))
            msg.exec_()

            return True
        else:
            #si no se mira si se hizo el click en alguno de los hijos
            for i in nodo.childrens:
                self.__colision(i, rect)

    # -------------------------------------------------------------------------------------------------
    #       metodo que limpia la escena y llama al metodo de pintado del arbol
    # -------------------------------------------------------------------------------------------------
    def dibujar(self):

        #self.arbolito.get_root().print_tree()
        self.escena.clear()
        self.pintar()

    # -------------------------------------------------------------------------------------------------
    #       metodo publico que llama el pintado del arbol y sus lineas desde la razi
    # -------------------------------------------------------------------------------------------------
    def pintar(self):

        root = self.arbolito.get_root()
        self.y = 50
        self.__pintar_arbol(root, 10, self.y)
        self.__lineas(root)

    # -------------------------------------------------------------------------------------------------
    #      metodo que pinta todos los nodos del arbol
    # -------------------------------------------------------------------------------------------------
    def __pintar_arbol(self, nodo, x, y):

        pen = QPen(Qt.black)  #lapiz de nodo normal
        pen2 = QPen(Qt.green)  #lapiz de nodo actual
        nodo.x = x  #se asigna posicion x al nodo
        nodo.y = self.y  #se asigna posicion y al nodo

        nodo.rect = QRect(
            nodo.x, nodo.y, nodo.tam, nodo.tam
        )  # se crea un rectangulo para el nodo,para los eventos click

        #print("Pos x : ",nodo.x,"Pos y : ",nodo.y," Dato :",nodo.data," Info : ",nodo.info)

        xp = nodo.tam / 2
        #self.escena.addRect(nodo.rect,pen)
        if nodo.activo:
            self.escena.addEllipse(nodo.x, nodo.y, nodo.tam, nodo.tam, pen2)
        else:
            self.escena.addEllipse(nodo.x, nodo.y, nodo.tam, nodo.tam, pen)

        #texto del nodo
        text = self.escena.addText(str(nodo.data))
        text.setPos(QPointF(nodo.x + 2, nodo.y - 3))

        x += 50

        ##pintar los hijos
        for i in nodo.childrens:
            self.y += 40
            self.__pintar_arbol(i, x, self.y)

    # -------------------------------------------------------------------------------------------------
    #   metodo que pinta las lineas de relacion en el arbol
    # -------------------------------------------------------------------------------------------------
    def __lineas(self, nodo):

        pen = QPen(Qt.black)
        xp = nodo.tam / 2
        for i in nodo.childrens:
            xl1_a = nodo.x + nodo.tam + 5
            yl1_a = nodo.y + nodo.tam - 5

            ylb = i.y + xp
            self.escena.addLine(nodo.x + nodo.tam, yl1_a, xl1_a, yl1_a)
            self.escena.addLine(xl1_a, yl1_a, xl1_a, ylb, pen)
            self.escena.addLine(xl1_a, ylb, i.x, ylb, pen)
            self.__lineas(i)
class CircuitDiagramView(QGraphicsView):
	mousePress = pyqtSignal(tuple, tuple, name='mousePress')
	mouseMove = pyqtSignal(tuple, tuple, name='mouseMove')
	mouseRelease = pyqtSignal(tuple, tuple, name='mouseRelease')

	def __init__(self, parent=None):
		QGraphicsView.__init__(self, parent)

		self._model = None
		self.controller = None

		self.setAcceptDrops(True)

		# setup & render circuit diagram grid
		self.scene = QGraphicsScene()
		self.setScene(self.scene)

		self._shouldShowSelection = False
		self._selection = None
		self._dragging = False
		self.mousePosition = None
		self.draggingStart = None

		self.render()

	@property
	def shouldShowSelection(self):
		return self._shouldShowSelection

	@shouldShowSelection.setter
	def shouldShowSelection(self, value):
		if self.shouldShowSelection is not value and value is not None:
			self._shouldShowSelection = value
			self.render()		

	@property
	def model(self):
		return self._model

	@model.setter
	def model(self, value):
		self._model = value
		self.model.modelChanged.connect(self.render)

	@property
	def selection(self):
		return self._selection

	@selection.setter
	def selection(self, value):
		if self.selection is not value:
			self._selection = value
			self.render()	

	@property
	def dragging(self):
		return self._dragging

	@dragging.setter
	def dragging(self, value):
		self._dragging = value
		self.render()

	def componentTypeToImageName(self, componentType):
		dictionary = {
			ComponentType.Battery: "assets/battery.png",
			ComponentType.Resistor: "assets/resistor.png",
			ComponentType.Voltmeter: "assets/voltmeter.png",
			ComponentType.Ammeter: "assets/ammeter.png",
			ComponentType.Switch: "assets/switch-off.png",
			ComponentType.Bulb: "assets/bulb-off.png",
			ComponentType.Button: "assets/button-off.png",
		}

		return dictionary[componentType]

	def componentToImage(self, component):
		if component.type == ComponentType.Wire:
			image = QPixmap("assets/icon.png").scaled(self.blockSideLength, self.blockSideLength)
			if component.numberOfConnections() == 1:
				image = QPixmap("assets/wire-top.png").scaled(self.blockSideLength, self.blockSideLength)
				if component.connections[Direction.Right] is not None:
					image = image.transformed(QtGui.QTransform().rotate(90))
				elif component.connections[Direction.Bottom] is not None:
					image = image.transformed(QtGui.QTransform().rotate(180))
				elif component.connections[Direction.Left] is not None:
					image = image.transformed(QtGui.QTransform().rotate(270))
			elif component.numberOfConnections() == 2:
				if component.connections[Direction.Left] is not None and component.connections[Direction.Right] is not None:
					image = QPixmap("assets/wire-left-right.png").scaled(self.blockSideLength, self.blockSideLength)
				elif component.connections[Direction.Top] is not None and component.connections[Direction.Bottom] is not None:
					image = QPixmap("assets/wire-left-right.png").scaled(self.blockSideLength, self.blockSideLength).transformed(QtGui.QTransform().rotate(90))
				elif component.connections[Direction.Top] is not None and component.connections[Direction.Right] is not None:
					image = QPixmap("assets/wire-top-right.png").scaled(self.blockSideLength, self.blockSideLength)
				elif component.connections[Direction.Top] is not None and component.connections[Direction.Left] is not None:
					image = QPixmap("assets/wire-top-right.png").scaled(self.blockSideLength, self.blockSideLength).transformed(QtGui.QTransform().rotate(270))
				elif component.connections[Direction.Bottom] is not None and component.connections[Direction.Right] is not None:
					image = QPixmap("assets/wire-top-right.png").scaled(self.blockSideLength, self.blockSideLength).transformed(QtGui.QTransform().rotate(90))
				elif component.connections[Direction.Bottom] is not None and component.connections[Direction.Left] is not None:
					image = QPixmap("assets/wire-top-right.png").scaled(self.blockSideLength, self.blockSideLength).transformed(QtGui.QTransform().rotate(180))
			elif component.numberOfConnections() == 3:
				image = QPixmap("assets/wire-left-top-right.png").scaled(self.blockSideLength, self.blockSideLength)
				if component.connections[Direction.Left] is None:
					image = image.transformed(QtGui.QTransform().rotate(90))
				elif component.connections[Direction.Top] is None:
					image = image.transformed(QtGui.QTransform().rotate(180))
				elif component.connections[Direction.Right] is None:
					image = image.transformed(QtGui.QTransform().rotate(270))
			return image
		else:
			imageName = "assets/wire-right.png"
		
			if component.type == ComponentType.Bulb:
				if component.isOn():
					imageName = "assets/bulb-on.png"
				else:
					imageName = "assets/bulb-off.png"
			elif component.type == ComponentType.Switch:
				if component.closed:
					imageName = "assets/switch-on.png"
				else:
					imageName = "assets/switch-off.png"
			elif component.type == ComponentType.Button:
				if component.closed:
					imageName = "assets/button-on.png"
				else:
					imageName = "assets/button-off.png"
			else:
				imageName = self.componentTypeToImageName(component.type)
			
			return QPixmap(imageName).scaled(self.blockSideLength, self.blockSideLength)

	def mouseCoordinatesToBlockIndex(self, x, y):
		if self.model is None or x < self.startingX or y < self.startingY or x > self.startingX + self.model.gridSize * self.blockSideLength or y > self.startingY + self.model.gridSize * self.blockSideLength:
			return (-1, -1)
		else:
			return (int((x - self.startingX) / self.blockSideLength), int((y - self.startingY) / self.blockSideLength))

	def blockIndexToCoordinate(self, x, y):
		return (self.startingX + self.blockSideLength * x, self.startingY + self.blockSideLength * y)

	def mousePressEvent(self, event):
		index = self.mouseCoordinatesToBlockIndex(event.x(), event.y())
		self.mousePress.emit(index, (event.x(), event.y()))

	def dragEnterEvent(self, event):
		event.acceptProposedAction()

	def dragMoveEvent(self, event):
		index = self.mouseCoordinatesToBlockIndex(event.pos().x(), event.pos().y())
		self.mouseMove.emit(index, (event.pos().x(), event.pos().y()))

	def dropEvent(self, event):
		event.acceptProposedAction()
		index = self.mouseCoordinatesToBlockIndex(event.pos().x(), event.pos().y())
		self.mouseRelease.emit(index, (event.pos().x(), event.pos().y()))
		
	def mouseMoveEvent(self, event):
		self.mousePosition = (event.x(), event.y())
		if self.dragging:
			self.render()
		index = self.mouseCoordinatesToBlockIndex(event.x(), event.y())
		self.mouseMove.emit(index, (event.pos().x(), event.pos().y()))

	def mouseReleaseEvent(self, event):
		index = self.mouseCoordinatesToBlockIndex(event.x(), event.y())
		self.mouseRelease.emit(index, (event.pos().x(), event.pos().y()))

	def resizeEvent(self, event):
		self.render()

	def render(self):
		if self.model is not None:
			self.scene.clear()
			self.renderCircuitDiagramGrid() 
			self.renderComponents() 

	def renderComponents(self):
		if self.model is not None:
			for component in self.model.components:
				pixmap = self.componentToImage(component)
				pixmapItem = self.scene.addPixmap(pixmap)
				offset = self.blockIndexToCoordinate(component.position[0],component.position[1])
				pixmapItem.setOffset(offset[0],offset[1])
				pixmapItem.setTransformationMode(Qt.SmoothTransformation)
		
				if component is self.selection:
					if self.dragging:
						renderPosition = (self.startingX + self.selection.position[0] * self.blockSideLength + self.mousePosition[0] - self.draggingStart[0], self.startingY + self.selection.position[1] * self.blockSideLength + self.mousePosition[1] - self.draggingStart[1])
						pixmapItem.setOffset(renderPosition[0], renderPosition[1])
					elif self.shouldShowSelection:
						pen = QPen(QBrush(QColor(0,0,255,100)), 2, Qt.DashLine)
						self.scene.addRect(self.startingX + component.position[0] * self.blockSideLength, self.startingY + component.position[1] * self.blockSideLength, self.blockSideLength, self.blockSideLength, pen)
				if component.type is ComponentType.Ammeter:
					font = QFont("Arial", self.blockSideLength/3.5)
					reading = self.scene.addText(str("%.2f" % component.current) + "A", font)
					offset = self.blockIndexToCoordinate(component.position[0],component.position[1])
					reading.setPos(offset[0]+self.blockSideLength/20,offset[1]+self.blockSideLength/4)
				elif component.type is ComponentType.Voltmeter:
					font = QFont("Arial", self.blockSideLength/3.5)
					reading = self.scene.addText(str("%.2f" % component.voltage) + "V", font)
					offset = self.blockIndexToCoordinate(component.position[0],component.position[1])
					reading.setPos(offset[0]+self.blockSideLength/20,offset[1]+self.blockSideLength/4)

	def renderCircuitDiagramGrid(self):
		pen = QPen(QBrush(QColor(200,200,200,255)), 1)
		pen2 = QPen(QBrush(QColor(100,100,100,255)), 3)
		width = self.width()
		height = self.height()
		self.blockSideLength = width / (self.model.gridSize + 2) if width < height else height / (self.model.gridSize + 2)

		# draw vertical lines
		currentX = width / 2
		self.startingX = currentX - (self.model.gridSize / 2) * self.blockSideLength
		while currentX - self.blockSideLength >= 0:
			currentX -= self.blockSideLength
		
		while currentX < width:
			self.scene.addLine(currentX, 1, currentX, height - 1, pen)
			
			currentX += self.blockSideLength

		# draw horizontal lines
		currentY = height / 2
		self.startingY = currentY - (self.model.gridSize / 2) * self.blockSideLength
		while currentY - self.blockSideLength >= 0:
			currentY -= self.blockSideLength
		while currentY < height:
			self.scene.addLine(1, currentY, width - 1, currentY, pen)
			currentY += self.blockSideLength

		self.scene.addLine(self.startingX, self.startingY, self.startingX + self.model.gridSize * self.blockSideLength, self.startingY, pen2)
		self.scene.addLine(self.startingX, self.startingY + self.model.gridSize * self.blockSideLength, self.startingX + self.model.gridSize * self.blockSideLength, self.startingY + 10 * self.blockSideLength, pen2)
		self.scene.addLine(self.startingX, self.startingY, self.startingX, self.startingY + self.model.gridSize * self.blockSideLength, pen2)
		self.scene.addLine(self.startingX + self.model.gridSize * self.blockSideLength, self.startingY, self.startingX + self.model.gridSize * self.blockSideLength, self.startingY + 10 * self.blockSideLength, pen2)
Ejemplo n.º 32
0
class MainApp(QMainWindow, Ui_MainWindow):

    process_Num = 0
    segments_list = []

    def __init__(self, parent=None):
        super(MainApp, self).__init__(parent)
        QMainWindow.__init__(self)
        self.setupUi(self)
        self.processes_list = []
        self.memory_created = 0  # use this variable as a flag
        self.process_name = ""
        self.scene = QGraphicsScene()
        self.red = QColor(qRgb(172, 50, 99))
        self.blue = QColor(qRgb(50, 150, 203))
        self.memory_width = 150
        self.memory_height = 600
        self.view.setScene(self.scene)
        self.setup_Ui()
        self.init_Buttons()

    def setup_Ui(self):
        """
        UI setup goes here
        """
        self.center_window()
        self.setWindowTitle("Memory Management")
        self.setFixedSize(530, 750)
        self.NumSegments.setMinimum(0)
        self.NumSegments.setMaximum(999)

    def center_window(self):
        # centering window
        qtRectangle = self.frameGeometry()
        centerPoint = QDesktopWidget().availableGeometry().center()
        qtRectangle.moveCenter(centerPoint)
        self.move(qtRectangle.topLeft())

    def init_Buttons(self):
        """
        Buttons initializations and slots connections goes here
        """
        self.EnterSegments.clicked.connect(self.goToSegmentsWindow)
        self.SizeEnter.clicked.connect(self.createMemory)
        self.AddHole_button.clicked.connect(self.add_hole)
        self.deallocate_button.clicked.connect(self.deallocate_process)
        self.allocate_button.clicked.connect(self.allocate_memory)
        self.compact_button.clicked.connect(self.compact_memory)
        self.clear_button.clicked.connect(self.clear_memory)

    def DrawMemory(self):
        iterator = 0
        self.scene.clear()
        for element in self.memory.get_memoryContents():
            self.scene.addRect(
                0,  # x
                (iterator / self.memory.get_memorySize()) * self.memory_height,  # y
                self.memory_width,  # w
                (element[2] / self.memory.get_memorySize()) * self.memory_height,  # h
                self.red,
                hex_to_qcolor(self.memory.color_from_name(element[1])),
            )
            self.scene.addText(element[0]).setPos(
                0, (iterator / self.memory.get_memorySize()) * self.memory_height
            )
            self.scene.addText(str(iterator)).setPos(
                self.memory_width, (iterator / self.memory.get_memorySize()) * self.memory_height
            )
            iterator = iterator + element[2]

    def createMemory(self):

        try:
            memory_size = int(self.MemorySize.text())
            if memory_size > 0:
                self.memory = Memory(memory_size)
                self.memory_created = 1
                self.DrawMemory()
            else:
                self.show_msgBox(
                    "Memory Size error!\nSet Memory Size please!"
                )  # create error msg here
        except:
            self.show_msgBox(
                "Memory Size error!\nMemory Size Text Box accepts numeric values only."
            )  # create error msg to write only number here

    def add_hole(self):

        if self.memory_created:
            try:
                hole_address = int(self.HoleAddress.text())
                hole_size = int(self.HoleSize.text())
                if hole_size > 0:
                    self.memory.add_hole(hole_address, hole_size)
                    self.memory.Merge()
                    self.DrawMemory()
                else:
                    self.show_msgBox(
                        "Hole Size Value Error!\nHole cannot be of size 0"
                    )  # error msg here, plz add a proper hole size

            except ValueError:
                self.show_msgBox("Please Make sure you entered numeric values.")

            except AssertionError as error:
                if (
                    str(error)
                    == "Can't add a hole here! There's already a hole located in this address"
                ):
                    self.show_msgBox(str(error))
                else:
                    self.show_msgBox(
                        "Memory Limit Exceeded!\n" + str(error)
                    )  # error msg here, hole size or base address are beyond  memory size
        else:
            self.show_msgBox(
                "No Memory Found.\nPlease Create Memory before creating a hole!"
            )  # error msg here, plz create a memory by assigning its size above

    def allocate_memory(self):
        try:
            if self.memory_created:
                algorithm = self.algorithms_list.currentText()
                if len(self.process_name) > 0 and not (
                    self.memory.color_from_name(self.process_name)
                    in chain(*self.memory.get_memoryContents())
                ):
                    if algorithm == "First Fit":
                        self.memory.first_fit(self.segments_list, self.process_name)
                        self.DrawMemory()
                        self.NumSegments.setValue(0)
                    elif algorithm == "Best Fit":
                        self.memory.best_fit(self.segments_list, self.process_name)
                        self.DrawMemory()
                        self.NumSegments.setValue(0)
                    else:
                        self.memory.worst_fit(self.segments_list, self.process_name)
                        self.DrawMemory()
                        self.NumSegments.setValue(0)
                else:
                    self.show_msgBox(
                        "No Selected Process!\nAdd Segments First to be able to allocate a process"
                    )  # error msg here
            else:
                self.show_msgBox(
                    "No Memory Found.\nPlease Create Memory before allocate processes!"
                )  # error msg here, plz create a memory by assigning its size above
        except AssertionError as error:
            self.show_msgBox("Memory Limit Exceeded!\n" + str(error))

    def deallocate_process(self):

        process = self.processesBox.currentText()
        if self.memory_created:
            if len(process) > 0:
                self.memory.deallocate(process)
                process_index = self.processesBox.currentIndex()
                self.processesBox.removeItem(process_index)
                self.memory.Merge()
                self.DrawMemory()
            else:
                self.show_msgBox(
                    "No Process Found.\nPlease Add process first!"
                )  # msg error here, create memory first

        else:
            self.show_msgBox(
                "No Memory Found.\nPlease Create Memory first!"
            )  # msg error here, create memory first

    def goToSegmentsWindow(self):

        if self.memory_created:
            segmentsNo = self.NumSegments.value()
            if segmentsNo > 0:
                self.segments_window = SegmentWindow()
                self.segments_window.set_segmentsNo(segmentsNo)
                self.segments_window.show()
                self.segments_window.set_processesNum(self.process_Num + 1)

                self.segments_window.segmentsData_passingSig.connect(
                    self.receive_segmentsData
                )
            else:
                self.show_msgBox(
                    "Input Value Error\nNumber of segments must be more than 0"
                )  # error handling
        else:
            self.show_msgBox(
                "No Memory Found.\nPlease Create Memory first!"
            )  # error handling

    def receive_segmentsData(self, segList):
        print(segList)  # print for checking
        self.segments_list = segList
        self.process_Num += 1
        self.segments_window.close()
        self.processes_list.append("P" + str(self.process_Num))
        self.processesBox.addItem("P" + str(self.process_Num))
        self.process_name = "P" + str(self.process_Num)

    def compact_memory(self):
        if self.memory_created:
            self.memory.compact()
            self.memory.Merge()
            self.DrawMemory()
        else:
            self.show_msgBox("No Memory Found.\nPlease Create Memory first!")

    def clear_memory(self):
        if self.memory_created:
            del self.memory  # deleting memory object
            self.memory_created = 0  # set memory existence flag = 0
            self.clear_fields()
            # code to delete or remove memory contents in graphics should be added here
        else:
            self.show_msgBox("No Memory Found.\nPlease Create Memory first!")

    def clear_fields(self):
        self.MemorySize.setText("0")
        self.HoleAddress.setText("0")
        self.HoleSize.setText("0")
        self.NumSegments.setValue(0)
        processesNumber = int(self.processesBox.count())
        # print(processesNumber)
        if processesNumber > 0:
            for i in range(processesNumber):
                process = self.processesBox.currentText()
                if len(process) > 0:
                    process_index = self.processesBox.currentIndex()
                    self.processesBox.removeItem(process_index)
        self.process_Num = 0
        self.process_name = ""
        self.processes_list = []
        self.segments_list = []
        self.scene.clear()

    def show_msgBox(self, msg):
        self.msgBox = QMessageBox()
        self.msgBox.setWindowTitle("Error!")
        self.msgBox.setIcon(QMessageBox.Warning)
        self.msgBox.setText(msg)
        self.msgBox.setStandardButtons(QMessageBox.Ok)
        self.msgBox.exec_()
Ejemplo n.º 33
0
class RecordsetWindow(QWidget):

    dataDisplayRequest = pyqtSignal(str, int)
    dataUpdateRequest = pyqtSignal(str, Base)

    def __init__(self, manager, recordset: list, parent=None):
        super().__init__(parent=parent)
        self.UI = Ui_frmRecordsets()
        self.UI.setupUi(self)

        # Internal lists
        self.sensors = {}           # List of sensors objects
        self.sensors_items = {}     # List of QAction corresponding to each sensors
        self.sensors_graphs = {}    # List of graph corresponding to each sensor graph
        self.sensors_location = []  # List of sensors location in this recordset
        self.sensors_blocks = {}    # Sensor blocks - each block of data for each sensor

        # Variables
        self.time_pixmap = False    # Flag used to check if we need to repaint the timeline or not
        self.zoom_level = 1         # Current timeview zoom level

        # Manually created UI objects
        self.time_bar = QGraphicsLineItem()         # Currently selected timestamp bar
        self.selection_rec = QGraphicsRectItem()    # Section rectangle
        self.sensors_menu = QMenu(self.UI.btnNewGraph)
        self.UI.btnNewGraph.setMenu(self.sensors_menu)

        # Data access informations
        self.dbMan = manager
        self.recordsets = recordset

        # Init temporal browser
        self.timeScene = QGraphicsScene()
        self.UI.graphTimeline.setScene(self.timeScene)
        self.UI.graphTimeline.fitInView(self.timeScene.sceneRect())
        self.UI.graphTimeline.time_clicked.connect(self.timeview_clicked)
        self.UI.graphTimeline.time_selected.connect(self.timeview_selected)
        self.UI.scrollTimeline.valueChanged.connect(self.timeview_scroll)

        # Init temporal sensor list
        self.timeSensorsScene = QGraphicsScene()
        self.UI.graphSensorsTimeline.setScene(self.timeSensorsScene)
        self.UI.graphSensorsTimeline.fitInView(self.timeSensorsScene.sceneRect(), Qt.KeepAspectRatio)

        # Update general informations about recordsets
        self.update_recordset_infos()

        # Load sensors for that recordset
        self.load_sensors()

        # Connect signals to slots
        self.UI.btnClearSelection.clicked.connect(self.on_timeview_clear_selection_requested)
        self.UI.btnTimeZoomSelection.clicked.connect(self.on_timeview_zoom_selection_requested)
        self.UI.btnZoomReset.clicked.connect(self.on_timeview_zoom_reset_requested)
        self.UI.btnDisplayTimeline.clicked.connect(self.on_timeview_show_hide_requested)
        self.UI.btnTileHorizontal.clicked.connect(self.tile_graphs_horizontally)
        self.UI.btnTileVertical.clicked.connect(self.tile_graphs_vertically)
        self.UI.btnTileAuto.clicked.connect(self.tile_graphs_auto)
        self.sensors_menu.triggered.connect(self.sensor_graph_selected)

        # Initial UI state
        self.UI.btnZoomReset.setEnabled(False)
        self.UI.btnTimeZoomSelection.setEnabled(False)
        self.UI.btnClearSelection.setEnabled(False)
        self.update_tile_buttons_state()

    def paintEvent(self, paint_event):
        if not self.time_pixmap:
            self.refresh_timeview()
            self.time_pixmap = True

    def resizeEvent(self, resize_event):
        if self.time_pixmap:
            self.refresh_timeview()

    def refresh_timeview(self):
        QGuiApplication.setOverrideCursor(Qt.BusyCursor)

        # Computes required timescene size
        min_width = self.UI.graphTimeline.width() - 5
        if len(self.recordsets) > 0:
            num_days = (self.get_recordset_end_day_date() - self.get_recordset_start_day_date()).days

            # Minimum size for days
            if num_days * 75 > min_width:
                min_width = num_days * 75 - 5

        # Resize timeScene correctly
        self.timeScene.clear()
        self.timeScene.setSceneRect(self.timeScene.itemsBoundingRect())
        self.timeScene.addLine(0, 80, min_width, 80, QPen(Qt.transparent))

        # Set background color
        back_brush = QBrush(Qt.lightGray)
        self.timeScene.setBackgroundBrush(back_brush)
        self.timeSensorsScene.setBackgroundBrush(back_brush)

        # Update display
        self.draw_dates()
        self.draw_sensors_names()
        self.draw_recordsets()
        self.draw_sensors()
        self.draw_grid()
        self.draw_timebar()

        # Adjust splitter sizes
        self.adjust_timeview_size()
        # self.UI.frmSensors.hide()

        QGuiApplication.restoreOverrideCursor()

    def adjust_timeview_size(self):
        self.UI.frameScrollSpacer.setFixedWidth(self.UI.graphTimeline.pos().x())
        if self.timeScene.itemsBoundingRect().width() * self.zoom_level > self.UI.graphTimeline.width():
            self.UI.scrollTimeline.setVisible(True)
            # self.UI.scrollTimeline.setMinimum(self.UI.graphTimeline.width()/2)
            self.UI.scrollTimeline.setMinimum(0)
            self.UI.scrollTimeline.setMaximum(self.timeScene.itemsBoundingRect().width() * self.zoom_level)
            self.UI.scrollTimeline.setPageStep(self.UI.graphTimeline.width()/2)
            self.UI.scrollTimeline.setSingleStep(self.UI.graphTimeline.width()/5)
        else:
            self.UI.scrollTimeline.setVisible(False)

    def load_sensors(self):

        # self.UI.lstSensors.clear()
        self.sensors = {}
        self.sensors_items = {}
        self.sensors_location = []
        self.sensors_menu.clear()

        if len(self.recordsets) > 0:
            for recordset in self.recordsets:
                for sensor in self.dbMan.get_sensors(recordset):
                    if sensor.location not in self.sensors_location:
                        self.sensors_location.append(sensor.location)
                        self.sensors_menu.addSection(sensor.location)
                    if sensor.id_sensor not in self.sensors:
                        self.sensors[sensor.id_sensor] = sensor
                        sensor_item = QAction(sensor.name)
                        sensor_item.setCheckable(True)
                        sensor_item.setProperty("sensor_id", sensor.id_sensor)
                        self.sensors_items[sensor.id_sensor] = sensor_item
                        self.sensors_menu.addAction(sensor_item)

            # Create sensors blocks for display
            self.load_sensors_blocks()
        else:
            self.UI.btnNewGraph.setEnabled(False)

    def update_recordset_infos(self):
        if len(self.recordsets) == 0:
            self.UI.lblTotalValue.setText("Aucune donnée.")
            self.UI.lblDurationValue.setText("Aucune donnée.")
            return

        start_time = self.recordsets[0].start_timestamp
        end_time = self.recordsets[len(self.recordsets) - 1].end_timestamp

        # Coverage
        self.UI.lblTotalValue.setText(start_time.strftime('%d-%m-%Y %H:%M:%S') + " @ " + end_time.strftime(
                                                                                                '%d-%m-%Y %H:%M:%S'))

        # Duration
        # TODO: format better
        self.UI.lblDurationValue.setText(str(end_time - start_time))

        self.UI.lblCursorTime.setText(start_time.strftime('%d-%m-%Y %H:%M:%S'))

    def get_recordset_start_day_date(self):
        if len(self.recordsets) == 0:
            return None
        start_time = self.recordsets[0].start_timestamp
        start_time = (datetime(start_time.year, start_time.month, start_time.day, 0, 0, 0))
        return start_time

    def get_recordset_end_day_date(self):
        if len(self.recordsets) == 0:
            return None
        end_time = self.recordsets[len(self.recordsets) - 1].end_timestamp
        end_time = (datetime(end_time.year, end_time.month, end_time.day, 0, 0, 0) + timedelta(days=1))
        return end_time

    def get_relative_timeview_pos(self, current_time):
        # start_time = self.recordsets[0].start_timestamp.timestamp()
        start_time = self.get_recordset_start_day_date().timestamp()
        # end_time = self.recordsets[len(self.recordsets) - 1].end_timestamp.timestamp()
        end_time = self.get_recordset_end_day_date().timestamp()
        time_span = (end_time - start_time)  # Total number of seconds in recordsets
        # if type(current_time) is datetime:
        if isinstance(current_time, datetime):
            current_time = current_time.timestamp()

        if time_span > 0:
            # return ((current_time - start_time) / time_span) * self.UI.graphTimeline.width()
            return ((current_time - start_time) / time_span) * self.timeScene.width()
        else:
            return 0

    def get_time_from_timeview_pos(self, pos):
        if len(self.recordsets) == 0:
            return None;

        start_time = self.get_recordset_start_day_date().timestamp()
        end_time = self.get_recordset_end_day_date().timestamp()

        current_time = (pos / self.timeScene.width()) * (end_time - start_time) + start_time
        current_time = datetime.fromtimestamp(current_time)

        return current_time

    def draw_dates(self):
        if len(self.recordsets) == 0:
            return

        # Computations
        start_time = self.recordsets[0].start_timestamp
        end_time = self.recordsets[len(self.recordsets) - 1].end_timestamp
        # time_span = (end_time - start_time).total_seconds()  # Total number of seconds in recordsets
        current_time = (datetime(start_time.year, start_time.month, start_time.day, 0, 0, 0) + timedelta(days=1))

        # Drawing tools
        black_pen = QPen(Qt.black)
        blue_brush = QBrush(Qt.darkBlue)

        # Date background
        self.timeScene.addRect(0, 0, self.timeScene.width(), 20, black_pen, blue_brush)
        self.timeSensorsScene.addRect(0, 0, self.timeSensorsScene.width(), 20, black_pen, blue_brush)

        # First date
        date_text = self.timeScene.addText(start_time.strftime("%d-%m-%Y"))
        date_text.setPos(0, 0)  # -5
        date_text.setDefaultTextColor(Qt.white)
        date_text.setFlag(QGraphicsItem.ItemIgnoresTransformations, True)

        # Date separators
        while current_time <= end_time:
            pos = self.get_relative_timeview_pos(current_time)
            date_text = self.timeScene.addText(current_time.strftime("%d-%m-%Y"))
            date_text.setPos(pos, 0)  # -5
            date_text.setDefaultTextColor(Qt.white)
            date_text.setFlag(QGraphicsItem.ItemIgnoresTransformations, True)
            current_time += timedelta(days=1)

        # self.UI.graphTimeline.fitInView(self.timeScene.sceneRect(), Qt.KeepAspectRatio)

    def draw_grid(self):
        if len(self.recordsets) == 0:
            return

        # Computations
        start_time = self.recordsets[0].start_timestamp
        end_time = self.recordsets[len(self.recordsets) - 1].end_timestamp
        # time_span = (end_time - start_time).total_seconds()  # Total number of seconds in recordsets
        current_time = (datetime(start_time.year, start_time.month, start_time.day, 0, 0, 0) + timedelta(days=1))

        vgrid_pen = QPen(Qt.gray)
        hgrid_pen = QPen(Qt.black)
        vgrid_pen.setCosmetic(True)

        # Horizontal lines
        pos = 20
        # last_location = ""
        sensor_location_brush = QBrush(Qt.black)
        sensor_location_pen = QPen(Qt.transparent)
        for location in self.sensors_location:
            # Must create a new location line
            self.timeScene.addRect(0, pos, self.timeScene.width() - 1, 15, sensor_location_pen, sensor_location_brush)
            pos += 15
            sensors = self.get_sensors_for_location(location)
            for _ in sensors:
                self.timeScene.addLine(0, pos, self.timeScene.width() - 1, pos, hgrid_pen)
                self.timeSensorsScene.addLine(0, pos, self.timeSensorsScene.width(), pos, hgrid_pen)
                pos += 20

        # Final line
        self.timeScene.addLine(0, pos, self.timeScene.width() - 1, pos, hgrid_pen)
        self.timeSensorsScene.addLine(0, pos, self.timeSensorsScene.width() - 1, pos, hgrid_pen)

        # Date separators
        self.timeScene.addLine(0, 0, 0, self.timeScene.height(), vgrid_pen)

        # Other dates
        while current_time <= end_time:
            pos = self.get_relative_timeview_pos(current_time)
            self.timeScene.addLine(pos, 0, pos, self.timeScene.height(), vgrid_pen)
            current_time += timedelta(days=1)

    def draw_recordsets(self):
        recordset_brush = QBrush(QColor(212, 247, 192))  # Green
        recordset_pen = QPen(Qt.transparent)

        # Recording length
        for record in self.recordsets:
            start_pos = self.get_relative_timeview_pos(record.start_timestamp)
            end_pos = self.get_relative_timeview_pos(record.end_timestamp)
            span = end_pos - start_pos
            # print (str(span))
            self.timeScene.addRect(start_pos, 21, span, self.timeSensorsScene.height()-21, recordset_pen,
                                   recordset_brush)

        # self.UI.graphTimeline.update()
        return

    def draw_sensors_names(self):
        if len(self.sensors) == 0:
            return

        sensor_location_brush = QBrush(Qt.black)
        sensor_location_pen = QPen(Qt.transparent)

        # Sensor names
        pos = 20

        for location in self.sensors_location:
            # Must create a new location space for later
            pos += 15
            sensors = self.get_sensors_for_location(location)
            for sensor_id in sensors:
                sensor = self.sensors[sensor_id]
                # Sensor names
                label = self.timeSensorsScene.addText(sensor.name)
                label.setPos(0, pos)
                label.setDefaultTextColor(Qt.black)
                # label.setFont(QFont("Times", 10, QFont.Bold))
                pos += 20

        # Adjust size appropriately
        self.timeSensorsScene.setSceneRect(self.timeSensorsScene.itemsBoundingRect())
        self.UI.graphSensorsTimeline.setMaximumWidth(self.timeSensorsScene.itemsBoundingRect().width())

        # Sensor location background
        pos = 20
        for location in self.sensors_location:
            # Must create a new location line
            self.timeSensorsScene.addRect(0, pos, self.timeSensorsScene.width(), 15, sensor_location_pen,
                                          sensor_location_brush)
            label = self.timeSensorsScene.addText(location)
            label.setPos(0, pos)
            label.setDefaultTextColor(Qt.white)
            label.setFont(QFont("Times", 7))
            pos += 15
            sensors = self.get_sensors_for_location(location)
            for sensor_id in sensors:
                pos += 20

    def draw_sensors(self):
        if len(self.sensors) == 0:
            return

        sensor_brush = QBrush(Qt.darkGreen)
        sensor_pen = QPen(Qt.transparent)

        sensors_rects = self.create_sensors_rects()
        for _, rect in enumerate(sensors_rects):
            self.timeScene.addRect(rect, sensor_pen, sensor_brush)

        # Adjust size appropriately
        self.timeSensorsScene.setSceneRect(self.timeSensorsScene.itemsBoundingRect())
        self.UI.graphSensorsTimeline.setMaximumWidth(self.timeSensorsScene.itemsBoundingRect().width())
        # self.UI.graphSensorsTimeline.setMaximumHeight(self.timeSensorsScene.itemsBoundingRect().height())

    def load_sensors_blocks(self):
        # Create request tasks
        tasks = []
        for location in self.sensors_location:
            sensors = self.get_sensors_for_location(location)
            for sensor_id in sensors:
                for record in self.recordsets:
                    tasks.append(DBSensorTimesTask(title="Chargement des données temporelles", db_manager=self.dbMan,
                                                   sensor_id=sensor_id, recordset=record))

        QGuiApplication.setOverrideCursor(Qt.BusyCursor)
        process = BackgroundProcess(tasks)
        dialog = ProgressDialog(process, "Chargement")

        process.start()
        dialog.exec()
        QGuiApplication.restoreOverrideCursor()

        # Combine tasks results
        self.sensors_blocks = {}
        for task in tasks:
                for result in task.results:
                    if result['sensor_id'] not in self.sensors_blocks:
                        self.sensors_blocks[result['sensor_id']] = []
                    start_time = result['start_time']
                    end_time = result['end_time']
                    data = {"start_time": start_time, "end_time": end_time}
                    self.sensors_blocks[result['sensor_id']].append(data)

    def create_sensors_rects(self):
        rects = []
        pos = 20
        for location in self.sensors_location:
            # Must create a new location space for later
            pos += 15
            sensors = self.get_sensors_for_location(location)
            for sensor_id in sensors:
                # sensor = self.sensors[sensor_id]
                # for record in self.recordsets:
                #    datas = self.dbMan.get_all_sensor_data(sensor=sensor, recordset=record, channel=sensor.channels[0])
                #     for data in datas:
                #         start_pos = self.get_relative_timeview_pos(data.timestamps.start_timestamp)
                #         end_pos = self.get_relative_timeview_pos(data.timestamps.end_timestamp)
                #         span = max(end_pos - start_pos, 1)
                #         rects.append(QRectF(start_pos, pos + 3, span, 14))
                if sensor_id in self.sensors_blocks:
                    for block in self.sensors_blocks[sensor_id]:
                        start_pos = self.get_relative_timeview_pos(block['start_time'])
                        end_pos = self.get_relative_timeview_pos(block['end_time'])
                        span = max(end_pos - start_pos, 1)
                        rects.append(QRectF(start_pos, pos + 3, span, 14))
                pos += 20

        return rects

    def draw_timebar(self):
        line_pen = QPen(Qt.cyan)
        line_pen.setWidth(2)
        self.time_bar = self.timeScene.addLine(1, 21, 1, self.timeScene.height()-1, line_pen)
        # self.time_bar = self.timeScene.addLine(0, 1, 0, self.timeScene.height() - 1, line_pen)
        self.time_bar.setFlag(QGraphicsItem.ItemIgnoresTransformations, True)

    def get_sensors_for_location(self, location):
        sensors_id = []
        for sensor in self.sensors.values():
            if sensor.location == location:
                sensors_id.append(sensor.id_sensor)

        return sensors_id

    @staticmethod
    def get_sensor_graph_type(sensor):
        if sensor.id_sensor_type == SensorType.ACCELEROMETER \
                or sensor.id_sensor_type == SensorType.GYROMETER \
                or sensor.id_sensor_type == SensorType.BATTERY \
                or sensor.id_sensor_type == SensorType.LUX \
                or sensor.id_sensor_type == SensorType.CURRENT \
                or sensor.id_sensor_type == SensorType.BAROMETER \
                or sensor.id_sensor_type == SensorType.MAGNETOMETER \
                or sensor.id_sensor_type == SensorType.TEMPERATURE \
                or sensor.id_sensor_type == SensorType.HEARTRATE \
                or sensor.id_sensor_type == SensorType.ORIENTATION \
                or sensor.id_sensor_type == SensorType.FSR:
            return GraphType.LINECHART

        if sensor.id_sensor_type == SensorType.GPS:
            return GraphType.MAP

        return GraphType.UNKNOWN

    @pyqtSlot(Sensor, datetime, datetime)
    def query_sensor_data(self, sensor: Sensor, start_time: datetime, end_time: datetime):
        timeseries = self.get_sensor_data(sensor, start_time, end_time)[0]

        if self.sensors_graphs[sensor.id_sensor]:
            graph_type = self.get_sensor_graph_type(sensor)
            graph_window = self.sensors_graphs[sensor.id_sensor]
            if graph_type == GraphType.LINECHART:
                series_id = 0
                for series in timeseries:
                    # Filter times that don't fit in the range
                    y_range = series['y']
                    x_range = series['x']
                    y_range = y_range[x_range >= start_time.timestamp()]
                    x_range = x_range[x_range >= start_time.timestamp()]
                    y_range = y_range[x_range <= end_time.timestamp()]
                    x_range = x_range[x_range <= end_time.timestamp()]
                    if len(x_range)>0 and len(y_range)>0:
                        graph_window.graph.update_data(x_range, y_range, series_id)
                    series_id += 1
        return

    @pyqtSlot(QAction)
    # @timing
    def sensor_graph_selected(self, sensor_item):
        sensor_id = sensor_item.property("sensor_id")
        sensor = self.sensors[sensor_id]
        sensor_label = sensor.name + " (" + sensor.location + ")"

        if sensor_item.isChecked():
            # Choose the correct display for each sensor
            graph_window = None
            timeseries, channel_data = self.get_sensor_data(sensor)  # Fetch all sensor data

            # Color map for curves
            colors = [Qt.blue, Qt.green, Qt.yellow, Qt.red]

            graph_type = self.get_sensor_graph_type(sensor)
            graph_window = GraphWindow(graph_type, sensor, self.UI.mdiArea)
            graph_window.setStyleSheet(self.styleSheet() + graph_window.styleSheet())

            if graph_type == GraphType.LINECHART:
                # Add series
                for series in timeseries:
                    graph_window.graph.add_data(series['x'], series['y'], color=colors.pop(),
                                                legend_text=series['label'])

                graph_window.graph.set_title(sensor_label)

            if graph_type == GraphType.MAP:
                for data in channel_data:
                    gps = GPSGeodetic()
                    gps.from_bytes(data.data)
                    if gps.latitude != 0 and gps.longitude != 0:
                        graph_window.graph.addPosition(data.timestamps.start_timestamp, gps.latitude / 1e7,
                                                       gps.longitude / 1e7)
                        graph_window.setCursorPositionFromTime(data.timestamps.start_timestamp)

            if graph_window is not None:
                self.UI.mdiArea.addSubWindow(graph_window).setWindowTitle(sensor_label)
                self.sensors_graphs[sensor.id_sensor] = graph_window
                # self.UI.displayContents.layout().insertWidget(0,graph)

                graph_window.show()
                QApplication.instance().processEvents()

                graph_window.aboutToClose.connect(self.graph_was_closed)
                graph_window.requestData.connect(self.query_sensor_data)
                graph_window.graph.cursorMoved.connect(self.graph_cursor_changed)
                graph_window.graph.selectedAreaChanged.connect(self.graph_selected_area_changed)
                graph_window.graph.clearedSelectionArea.connect(self.on_timeview_clear_selection_requested)
                graph_window.zoomAreaRequested.connect(self.graph_zoom_area)
                graph_window.zoomResetRequested.connect(self.graph_zoom_reset)

                self.UI.mdiArea.tileSubWindows()
        else:
            # Remove from display
            try:
                if self.sensors_graphs[sensor.id_sensor] is not None:
                    self.UI.mdiArea.removeSubWindow(self.sensors_graphs[sensor.id_sensor].parent())
                    self.sensors_graphs[sensor.id_sensor].hide()
                    del self.sensors_graphs[sensor.id_sensor]
                    self.UI.mdiArea.tileSubWindows()
            except KeyError:
                pass
        self.update_tile_buttons_state()

    # @timing
    def get_sensor_data(self, sensor, start_time=None, end_time=None):
        QGuiApplication.setOverrideCursor(Qt.BusyCursor)
        task = DBSensorAllDataTask("Chargement des données...", self.dbMan, sensor, start_time, end_time,
                                   self.recordsets)

        process = BackgroundProcess([task])
        dialog = ProgressDialog(process, "Traitement")

        process.start()
        dialog.exec()
        QGuiApplication.restoreOverrideCursor()

        return task.results['timeseries'], task.results['channel_data']

    def update_tile_buttons_state(self):
        if self.sensors_graphs.keys().__len__() > 1:
            self.UI.btnTileAuto.setEnabled(True)
            self.UI.btnTileHorizontal.setEnabled(True)
            self.UI.btnTileVertical.setEnabled(True)
        else:
            self.UI.btnTileAuto.setEnabled(False)
            self.UI.btnTileHorizontal.setEnabled(False)
            self.UI.btnTileVertical.setEnabled(False)

    @pyqtSlot(QObject)
    def graph_was_closed(self, graph):
        for sensor_id, sensor_graph in self.sensors_graphs.items():
            if sensor_graph == graph:
                # self.sensors_graphs[sensor_id] = None
                del self.sensors_graphs[sensor_id]
                self.sensors_items[sensor_id].setChecked(False)
                break

        self.UI.mdiArea.tileSubWindows()
        self.update_tile_buttons_state()

    @pyqtSlot(float)
    def graph_cursor_changed(self, timestamp):
        current_time = timestamp / 1000
        for graph in self.sensors_graphs.values():
            if graph is not None:
                graph.setCursorPositionFromTime(current_time, False)

        pos = self.get_relative_timeview_pos(current_time)
        self.time_bar.setPos(pos,0)

        # Ensure time bar is visible if scrollable
        self.ensure_time_bar_visible(pos)

        self.UI.lblCursorTime.setText(datetime.fromtimestamp(current_time).strftime('%d-%m-%Y %H:%M:%S'))

    def ensure_time_bar_visible(self, pos):
        if self.UI.scrollTimeline.isVisible():
            max_visible_x = self.UI.graphTimeline.mapToScene(self.UI.graphTimeline.rect()).boundingRect().x() \
                            + self.UI.graphTimeline.mapToScene(self.UI.graphTimeline.rect()).boundingRect().width()
            min_visible_x = self.UI.graphTimeline.mapToScene(self.UI.graphTimeline.rect()).boundingRect().x()
            if pos < min_visible_x or pos > max_visible_x:
                self.UI.scrollTimeline.setValue(pos)

    @pyqtSlot(datetime, datetime)
    def graph_zoom_area(self, start_time, end_time):
        for graph in self.sensors_graphs.values():
            if graph is not None:
                graph.zoomAreaRequestTime(start_time, end_time)

    @pyqtSlot()
    def graph_zoom_reset(self):
        for graph in self.sensors_graphs.values():
            if graph is not None:
                graph.zoomResetRequest(False)

    @pyqtSlot(float, float)
    def graph_selected_area_changed(self, start_timestamp, end_timestamp):
        # Update timeview selection area
        start_pos = self.get_relative_timeview_pos(start_timestamp / 1000)
        end_pos = self.get_relative_timeview_pos(end_timestamp / 1000)
        self.timeview_selected(start_pos, end_pos)

        # Ensure time bar is visible if scrollable
        self.ensure_time_bar_visible(start_pos)

        # Update selection for each graph
        for graph in self.sensors_graphs.values():
            if graph is not None:
                graph.setSelectionAreaFromTime(start_timestamp, end_timestamp)

    @pyqtSlot(int)
    def timeview_scroll(self, pos):
        self.UI.graphTimeline.centerOn(pos / self.zoom_level, 0)

    @pyqtSlot(float)
    def timeview_clicked(self, x):
        self.time_bar.setPos(x, 0)
        if len(self.recordsets)==0:
            return

        # Find time corresponding to that position
        timestamp = self.get_time_from_timeview_pos(x)
        self.UI.lblCursorTime.setText(timestamp.strftime('%d-%m-%Y %H:%M:%S'))

        for graph in self.sensors_graphs.values():
            if graph is not None:
                # try:
                graph.setCursorPositionFromTime(timestamp, False)
            # except AttributeError:
            #    continue

    @pyqtSlot(float, float)
    def timeview_selected(self, start_x, end_x):
        selection_brush = QBrush(QColor(153, 204, 255, 128))
        selection_pen = QPen(Qt.transparent)
        self.timeScene.removeItem(self.selection_rec)
        self.selection_rec = self.timeScene.addRect(start_x, 20, end_x-start_x, self.timeScene.height()-20,
                                                    selection_pen, selection_brush)

        self.UI.btnClearSelection.setEnabled(True)
        self.UI.btnTimeZoomSelection.setEnabled(True)

        # Update selection for each graph
        for graph in self.sensors_graphs.values():
            if graph is not None:
                graph.setSelectionAreaFromTime(self.get_time_from_timeview_pos(start_x),
                                               self.get_time_from_timeview_pos(end_x))

    @pyqtSlot()
    def on_timeview_clear_selection_requested(self):
        self.timeScene.removeItem(self.selection_rec)
        self.UI.btnClearSelection.setEnabled(False)
        self.UI.btnTimeZoomSelection.setEnabled(False)

        # Clear all selected areas in graphs
        for graph in self.sensors_graphs.values():
            graph.clearSelectionArea()

    @pyqtSlot()
    def on_timeview_zoom_selection_requested(self):
        self.UI.graphTimeline.scale(1 / self.zoom_level, 1)
        # zoom_value = (self.timeScene.width() / (self.selection_rec.rect().width()))
        zoom_value = (self.UI.graphTimeline.width() / (self.selection_rec.rect().width()))
        self.zoom_level = zoom_value
        self.UI.graphTimeline.scale(zoom_value, 1)
        self.UI.btnZoomReset.setEnabled(True)
        self.adjust_timeview_size()
        # self.UI.graphTimeline.ensureVisible(self.selection_rec.rect(), 0, 0)
        # self.UI.graphTimeline.centerOn(self.selection_rec.rect().x() + self.selection_rec.rect().width() / 2, 0)
        self.UI.scrollTimeline.setValue((self.selection_rec.rect().x() + self.selection_rec.rect().width() / 2)
                                        * self.zoom_level)
        self.on_timeview_clear_selection_requested()

    @pyqtSlot()
    def on_timeview_zoom_reset_requested(self):
        self.UI.graphTimeline.scale(1 / self.zoom_level, 1)
        self.zoom_level = 1
        self.UI.btnZoomReset.setEnabled(False)
        self.adjust_timeview_size()
        self.UI.scrollTimeline.setValue(0)

    @pyqtSlot()
    def on_timeview_show_hide_requested(self):
        visible = not self.UI.frameTimeline.isVisible()
        self.UI.frameTimeline.setVisible(visible)
        self.UI.frameTimelineControls.setVisible(visible)
        # self.UI.lblCursorTime.setVisible(visible)

    @pyqtSlot()
    def on_process_recordset(self):
        # Display Process Window
        window = ProcessSelectWindow(self.dbMan, self.recordsets)
        window.setStyleSheet(self.styleSheet())

        if window.exec() == QDialog.Accepted:
            self.dataUpdateRequest.emit("result", window.processed_data)
            self.dataDisplayRequest.emit("result", window.processed_data.id_processed_data)

    @pyqtSlot()
    def tile_graphs_horizontally(self):
        self.tile_graphs(True)

    @pyqtSlot()
    def tile_graphs_vertically(self):
        self.tile_graphs(False)

    def tile_graphs(self, horizontal: bool):
        if self.UI.mdiArea.subWindowList() is None:
            return

        position = QPoint(0, 0)

        for window in self.UI.mdiArea.subWindowList():
            if horizontal:
                rect = QRect(0, 0, self.UI.mdiArea.width() / len(self.UI.mdiArea.subWindowList()),
                             self.UI.mdiArea.height())
            else:
                rect = QRect(0, 0, self.UI.mdiArea.width(),
                             self.UI.mdiArea.height() / len(self.UI.mdiArea.subWindowList()))
            window.setGeometry(rect)
            window.move(position)
            if horizontal:
                position.setX(position.x() + window.width())
            else:
                position.setY(position.y() + window.height())

    @pyqtSlot()
    def tile_graphs_auto(self):
        self.UI.mdiArea.tileSubWindows()
Ejemplo n.º 34
0
class AMANDisplay(QGraphicsView):
    def __init__(self):
        super(AMANDisplay, self).__init__()
        self.setGeometry(0, 0, 500, 600)
        self.setStyleSheet("background-color:#233370")
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.scene = QGraphicsScene(0, 0, 500, 600)

        # Timeline boundaries
        pen = QPen(QColor("white"))
        brush = QBrush(QColor("#233370"))
        self.scene.addLine(220, 0, 220, 600, pen)
        self.scene.addLine(280, 0, 280, 600, pen)
        self.scene.addLine(0, 30, 500, 30, pen)

        timelinebox = self.scene.addRect(220, 30, 60, 540, pen, brush)
        timelinebox.setFlag(timelinebox.ItemClipsChildrenToShape, True)

        # Timeline scale
        self.timeline = QGraphicsItemGroup()
        self.timeline.setParentItem(timelinebox)
        self.timeticks = []
        for i in range(40):
            y = 15 * i
            w = 6
            if i % 5 == 0:
                w = 10
                self.timeticks.append(self.scene.addText("%02d" % (40 - i), QFont("Courier", 10)))
                self.timeticks[-1].setPos(240, y - 10)
                self.timeticks[-1].setDefaultTextColor(QColor("white"))
                self.timeline.addToGroup(self.timeticks[-1])
            self.timeline.addToGroup(self.scene.addLine(220, y, 220 + w, y, pen))
            self.timeline.addToGroup(self.scene.addLine(280 - w, y, 280, y, pen))

        self.lrwy = self.scene.addText("18R", QFont("Arial", 20, 50))
        self.lrwy.setPos(1, 1)
        self.lrwy.setDefaultTextColor(QColor("white"))
        # Finalize
        self.setScene(self.scene)
        self.show()

    def update(self, simt, data):
        # data has: ids, iafs, eats, etas, delays, rwys, spdratios

        # First delete old labels
        for (key,) in self.aircraft.keys:
            if key not in data.ids:
                # del label
                del self.aircraft[key]

        for i in len(data.ids):
            if data.ids[i] not in self.aircraft:
                # self.aircraft[data.ids[i]] = QLabel()
                pass

            # Generate the new label text and position
            newtext = "<font color=Red>bla</font>"  # veranderen
            lbl = self.aircraft[data.ids[i]]
            lbl.setText(newtext)
            lbl.move(posx, posy)  # move in pixels
Ejemplo n.º 35
0
class AMANDisplay(QGraphicsView):
    def __init__(self):
        super().__init__()
        self.setGeometry(0, 0, 500, 600)
        self.setStyleSheet('background-color:#233370')
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.scene = QGraphicsScene(0, 0, 500, 600)

        # Timeline boundaries
        pen = QPen(QColor('white'))
        brush = QBrush(QColor('#233370'))
        self.scene.addLine(220, 0, 220, 600, pen)
        self.scene.addLine(280, 0, 280, 600, pen)
        self.scene.addLine(0, 30, 500, 30, pen)

        timelinebox = self.scene.addRect(220, 30, 60, 540, pen, brush)
        timelinebox.setFlag(timelinebox.ItemClipsChildrenToShape, True)

        # Timeline scale
        self.timeline  = QGraphicsItemGroup()
        self.timeline.setParentItem(timelinebox)
        self.timeticks = []
        for i in range(40):
            y = 15 * i
            w = 6
            if i % 5 == 0:
                w = 10
                self.timeticks.append(self.scene.addText('%02d' % (40 - i), QFont('Courier', 10)))
                self.timeticks[-1].setPos(240, y - 10)
                self.timeticks[-1].setDefaultTextColor(QColor('white'))
                self.timeline.addToGroup(self.timeticks[-1])
            self.timeline.addToGroup(self.scene.addLine(220, y, 220 + w, y, pen))
            self.timeline.addToGroup(self.scene.addLine(280 - w, y, 280, y, pen))

        self.lrwy = self.scene.addText('18R', QFont('Arial', 20, 50))
        self.lrwy.setPos(1, 1)
        self.lrwy.setDefaultTextColor(QColor('white'))
        # Finalize
        self.setScene(self.scene)
        self.show()

    def update(self, simt, data):
        # data has: ids, iafs, eats, etas, delays, rwys, spdratios

        # First delete old labels
        for key, in self.aircraft.keys:
            if key not in data.ids:
                # del label
                del self.aircraft[key]

        for i in len(data.ids):
            if data.ids[i] not in self.aircraft:
                # self.aircraft[data.ids[i]] = QLabel()
                pass

            # Generate the new label text and position
            newtext = '<font color=Red>bla</font>'  # veranderen
            lbl = self.aircraft[data.ids[i]]
            lbl.setText(newtext)
            lbl.move(posx, posy)  # move in pixels
Ejemplo n.º 36
0
class Airspeed_Tape(QGraphicsView):
    def __init__(self, parent=None):
        super(Airspeed_Tape, self).__init__(parent)
        self.setStyleSheet("border: 0px")
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setRenderHint(QPainter.Antialiasing)
        self.setFocusPolicy(Qt.NoFocus)
        self._airspeed = 0

    def resizeEvent(self, event):

        # V Speeds
        Vs = 45
        Vs0 = 40
        Vno = 125
        Vne = 140
        Va = 120
        Vfe = 70

        w = self.width()
        h = self.height()
        self.pph = 10
        f = QFont()
        f.setPixelSize(20)
        fontMetrics = QFontMetricsF(f)
        speed_pixel = 1500 + h

        dialPen = QPen(QColor(Qt.white))
        dialPen.setWidth(2)

        vnePen = QPen(QColor(Qt.red))
        vneBrush = QBrush(QColor(Qt.red))
        vnePen.setWidth(8)

        vsoPen = QPen(QColor(Qt.white))
        vsoPen.setWidth(8)

        vnoPen = QPen(QColor(Qt.green))
        vnoPen.setWidth(8)

        yellowPen = QPen(QColor(Qt.yellow))
        yellowPen.setWidth(8)

        self.scene = QGraphicsScene(0, 0, w, speed_pixel)
        self.scene.addRect(0, 0, w, speed_pixel, QPen(QColor(Qt.black)),
                           QBrush(QColor(Qt.black)))

        for i in range(150, -1, -5):
            if i % 10 == 0:
                self.scene.addLine(0, (-i * 10) + 1500 + h / 2, w / 2,
                                   (-i * 10) + 1500 + h / 2, dialPen)
                t = self.scene.addText(str(i))
                t.setFont(f)
                self.scene.setFont(f)
                t.setDefaultTextColor(QColor(Qt.white))
                t.setX(w - t.boundingRect().width())
                t.setY(((-i * 10) + 1500 + h / 2) -
                       t.boundingRect().height() / 2)
            else:
                self.scene.addLine(0, (-i * 10) + 1500 + h / 2, w / 2 - 20,
                                   (-i * 10) + 1500 + h / 2, dialPen)

        #Add Markings
        self.scene.addLine(4, Vs0 * -self.pph + 1500 + self.height() / 2 - 4,
                           4, Vfe * -self.pph + 1500 + self.height() / 2 + 4,
                           vsoPen)
        self.scene.addLine(4, Vfe * -self.pph + 1500 + self.height() / 2 - 4,
                           4, Vno * -self.pph + 1500 + self.height() / 2 + 4,
                           vnoPen)
        self.scene.addLine(4, Vne * -self.pph + 1500 + self.height() / 2 - 4,
                           4, Vno * -self.pph + 1500 + self.height() / 2 + 4,
                           yellowPen)
        self.scene.addLine(4, Vne * -self.pph + 1500 + self.height() / 2 - 4,
                           4, 150 * -self.pph + 1500 + self.height() / 2 + 4,
                           vnePen)

        self.setScene(self.scene)

    def redraw(self):
        self.resetTransform()
        self.centerOn(self.scene.width() / 2,
                      -self._airspeed * self.pph + 1500 + self.height() / 2)

    def getAirspeed(self):
        return self._airspeed

    def setAirspeed(self, airspeed):
        print(airspeed)
        if airspeed != self._airspeed:
            self._airspeed = airspeed
            self.redraw()

    airspeed = property(getAirspeed, setAirspeed)