Example #1
0
class View(QGraphicsView):
    
    def __init__(self):
        super().__init__()
        
        self.setGeometry(300, 300, 300, 300)
        self.setRenderHint(QPainter.Antialiasing)
       
        self.init()
        
        
    def init(self):

        self.scene = QGraphicsScene()
        
        r1 = self.scene.addRect(150, 40, 100, 100)
        r1.setBrush(QColor(250, 50, 0))
        r1.setPen(QColor(250, 50, 0))
               
        el = self.scene.addEllipse(40, 70, 80, 80)
        el.setBrush(QColor(0, 50, 250))
        el.setPen(QColor(0, 50, 250))
        
        r2 = self.scene.addRect(60, 180, 150, 70)
        r2.setBrush(QColor(0, 250, 50))
        r2.setPen(QColor(0, 250, 50))
        
        self.setScene(self.scene)  
Example #2
0
    def setupGUI(self):
        tabmain = QTabWidget()
        self.setCentralWidget(tabmain)

        # GPS Converter
        widget = QWidget()
        mainLayout = QGridLayout()
        widget.setLayout(mainLayout)
        self.openButton = self.createButton("Open Files", self.openFileClicked)
        mainLayout.addWidget(self.openButton, 0, 0)
        self.listWidget = QListWidget()
        mainLayout.addWidget(self.listWidget, 2, 0, 1, 2)
        self.runConvButton = self.createButton("Run Conversion",
                                               self.runConversionClicked)
        mainLayout.addWidget(self.runConvButton, 0, 1)
        self.runConvButton.setEnabled(False)
        self.multiCheckbox = self.createCheckbox("Multiple Markers per Map")
        mainLayout.addWidget(self.multiCheckbox, 1, 1)
        tabmain.addTab(widget, "GPS Data Conversion")

        # GPS View
        gpswidget = QWidget()
        gpsLayout = QGridLayout()
        gpswidget.setLayout(gpsLayout)
        gview = QGraphicsView()
        scene = QGraphicsScene()
        gview.setScene(scene)
        gpsLayout.addWidget(gview)

        blueBrush = QBrush(Qt.blue)
        mypen = QPen(Qt.black)
        scene.addRect(100, 0, 80, 100, mypen, blueBrush)

        tabmain.addTab(gpswidget, "GPS Visualisation")
Example #3
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)
Example #4
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()
Example #5
0
    def __init__(self):
        super().__init__()

        self.timerId = 0

        size = self.size()
        width_border = SCREEN_HEIGHT_BORDER
        height_border = SCREEN_HEIGHT_BORDER
        board_start_x = 2
        board_start_y = 2
        board_width = (size.width() - width_border) / 4 * 3
        board_height = size.height() - height_border

        x = board_start_x
        y = board_start_y
        x_diff = int((board_width - 2 * x) / 8)
        y_diff = int((board_height - 2 * y) / 8)

        scene = QGraphicsScene(self)
        view = QGraphicsView(scene)
        scene.setItemIndexMethod(QGraphicsScene.NoIndex)
        # scene.setSceneRect(-900, -900, 900, 900)
        scene.setSceneRect(scene.itemsBoundingRect())
        # scene.setSceneRect(QRectF(0, 0, 3000, 2400))
        view.setSceneRect(scene.sceneRect())
        self.setScene(scene)
        self.setCacheMode(QGraphicsView.CacheBackground)
        self.setViewportUpdateMode(QGraphicsView.BoundingRectViewportUpdate)
        self.setRenderHint(QPainter.Antialiasing)
        self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)
        self.setResizeAnchor(QGraphicsView.AnchorViewCenter)
        corn_silk_color = QColor(255, 248, 220)
        saddle_brown_color = QColor(139, 69, 19)
        antique_white_color = QColor(250, 235, 215)
        scene.addRect(0, 0, 50, 50, corn_silk_color)
        scene.addRect(110, 110, 50, 50, saddle_brown_color)
        scene.addRect(50, 50, 90, 90, saddle_brown_color)
        scene.addRect(x, y, board_width - x, board_height - y, corn_silk_color)
        board = Board()
        for fields_row in reversed(board.fields):
            for field in fields_row:
                field_color = antique_white_color if (
                    field.c + field.r) % 2 else saddle_brown_color
                scene.addRect(x, y, x_diff, y_diff, field_color)
                x += x_diff
            y += y_diff
            x = board_start_x

        node1 = Node(self)
        scene.addItem(node1)
        node1.setPos(-210, -520)

        self.scale(0.8, 0.8)
        self.setMinimumSize(400, 400)
        self.setWindowTitle("Elastic Nodes")
Example #6
0
 def paint(self, img):
     pixmap = cv233io.to_QPixmap(img)
     scene = QGraphicsScene(self)
     scene.addPixmap(pixmap)
     rect = QRectF(pixmap.rect())
     if img is self.img:
         scene.addRect(rect, QPen(Qt.black, 3, Qt.SolidLine, Qt.SquareCap))
     else:
         scene.addRect(rect, QPen(Qt.red, 3, Qt.DashLine, Qt.SquareCap))
     scene.setSceneRect(rect)
     self.graphicsView.setScene(scene)
     self.paintHist(img)
	def InitWindow(self):

		self.button1 = QPushButton("Rotate - ", self)
		self.button1.setGeometry(200,420,100,50)
		self.button1.clicked.connect(self.rotateMinus)

		self.button2 = QPushButton("Rotate +", self)
		self.button2.setGeometry(400,420,100,50)
		self.button2.clicked.connect(self.rotatePlus)

		scene = QGraphicsScene(self)
		redBrush = QBrush(Qt.red)
		blueBrush = QBrush(Qt.blue)
		blackPen = QPen(Qt.black)
		blackPen.setWidth(7)

		ellipse = scene.addEllipse(10,10,200,200, blackPen, redBrush)
		rect = scene.addRect(-100,-100,200,200, blackPen, blueBrush)

		ellipse.setFlag(QGraphicsItem.ItemIsMovable) # set it to movable
		rect.setFlag(QGraphicsItem.ItemIsMovable)

		self.view = QGraphicsView(scene, self)
		self.view.setGeometry(0,0,680,400)


		self.setWindowTitle(self.title)
		self.setGeometry(self.top, self.left, self.width, self.height)
		self.setWindowIcon(QtGui.QIcon('./icon/icon.png'))
		self.show()
Example #8
0
    def InitWindow(self):

        self.button1 = QPushButton("Rotate - ", self)
        self.button1.setGeometry(200, 420, 100, 50)
        self.button1.clicked.connect(self.rotateminus)

        self.button2 = QPushButton("Rotate +", self)
        self.button2.setGeometry(320, 420, 100, 50)
        self.button2.clicked.connect(self.rotateplus)

        scene = QGraphicsScene()  #the scene

        redbrush = QBrush(Qt.red)
        bluebrush = QBrush(Qt.blue)
        blackpen = QPen(Qt.black)
        blackpen.setWidth(7)

        ellipse = scene.addEllipse(10, 10, 200, 200, blackpen, redbrush)
        rect = scene.addRect(-100, -100, 200, 200, blackpen, bluebrush)
        line = scene.addLine(-100, -100, 200, 200, blackpen)

        ellipse.setFlag(QGraphicsItem.ItemIsMovable)
        rect.setFlag(QGraphicsItem.ItemIsMovable)
        line.setFlag(QGraphicsItem.ItemIsMovable)

        self.view = QGraphicsView(scene, self)
        self.view.setGeometry(0, 0, 680, 400)

        self.setWindowIcon(QtGui.QIcon("mongol.jpg"))
        self.setWindowTitle(self.title)
        self.setGeometry(self.top, self.left, self.width, self.height)
        self.show()
Example #9
0
    def __init__(self, parent) -> None:
        """
        CONSTRUCTOR
        """
        super().__init__(parent)
        self.ui = frm_lego_designer.Ui_Dialog(self)
        self.setWindowTitle("Lego Diagram Editor")

        #
        # Graphics view
        #
        self.ctrl_graphics_view = InteractiveGraphicsView()
        v = self.ctrl_graphics_view
        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        sizePolicy.setHeightForWidth(v.sizePolicy().hasHeightForWidth())
        v.setSizePolicy(sizePolicy)
        v.setObjectName("graphicsView")
        v.setBackgroundBrush(QBrush(QColor(255, 255, 255)))
        v.setInteractive(True)
        layout = QGridLayout()
        self.ui.FRA_MAIN.setLayout(layout)
        layout.addWidget(v)

        # Open GL rendering
        if groot.data.config.options().opengl:
            v.setViewport(QGLWidget(QGLFormat(QGL.SampleBuffers)))

        # Default (empty) scene
        scene = QGraphicsScene()
        scene.addRect(QRectF(-10, -10, 20, 20))

        v.setScene(scene)

        #
        # Create our model view!
        #
        self.model_view: ModelView = None
        self.update_view()

        self.toggle_show_edit(False)

        # Button clicks
        for x in (self.ui.BTN_S_EDGES_, self.ui.BTN_S_COMPS_,
                  self.ui.BTN_S_GENES_, self.ui.BTN_S_MINCOMPS_,
                  self.ui.BTN_S_DOMAINS_):
            x.clicked[bool].connect(self.on_btn_click)
Example #10
0
class MainScreen(QMainWindow):
    def __init__(self):

        super().__init__()
        #self.setupUi(self)

        # Graphic Screen set
        self.img = QGraphicsPixmapItem(QPixmap('KarlaOnMyShoulder.jpg'))
        self.scene = QGraphicsScene()
        self.graphicsView = QGraphicsView()
        self.scene.addItem(self.img)
        self.graphicsView.setScene(self.scene)

        # Full Screen set size
        _WIDTH_ADD = 25
        _HEIGHT_ADD = 25
        self.setGeometry(0, 0, 640 + _WIDTH_ADD, 500 + _HEIGHT_ADD)

        self.graphicsView.viewport().installEventFilter(self)

        self.current_item = None
        self.start_pos = QPointF()
        self.end_pos = QPointF()
        self.show()

    def eventFilter(self, o, e):
        if self.graphicsView.viewport() is o:
            if e.type() == QEvent.MouseButtonPress:
                if e.buttons() & Qt.LeftButton:
                    print("press")
                    self.start_pos = self.end_pos = self.graphicsView.mapToScene(
                        e.pos())
                    pen = QPen(QColor(240, 240, 240))
                    pen.setWidth(3)
                    brush = QBrush(QColor(100, 255, 100, 100))
                    self.current_item = self.scene.addRect(
                        QRectF(), pen, brush)
                    self._update_item()
            elif e.type() == QEvent.MouseMove:
                if e.buttons(
                ) & Qt.LeftButton and self.current_item is not None:
                    print("move")
                    self.end_pos = self.graphicsView.mapToScene(e.pos())
                    self._update_item()
            elif e.type() == QEvent.MouseButtonRelease:
                print("release")
                self.end_pos = self.graphicsView.mapToScene(e.pos())
                self._update_item()
                self.current_item = None

        return super().eventFilter(o, e)

    def _update_item(self):
        if self.current_item is not None:
            self.current_item.setRect(
                QRectF(self.start_pos, self.end_pos).normalized())
Example #11
0
    def initUi(self):

        layout = QGridLayout()

        graphics_view = QGraphicsView()
        layout.addWidget(graphics_view)

        width = graphics_view.frameGeometry().width()
        height = graphics_view.frameGeometry().height()

        scene = QGraphicsScene()
        scene.setSceneRect(0.0, 0.0, float(width), float(height))

        scene.addRect(100, 100, 150, 150)

        pen = QPen(Qt.SolidLine)
        pen.setColor(Qt.red)
        brush = QBrush(Qt.Dense3Pattern)
        brush.setColor(Qt.darkGreen)
        scene.addEllipse(300, 300, 100, 100, pen, brush)

        graphics_view.setScene(scene)

        self.setLayout(layout)
    def init(self):
        scene = QGraphicsScene()

        redBrush = QBrush(Qt.red)
        blueBrush = QBrush(Qt.blue)
        blackPen = QPen(Qt.black)
        blackPen.setWidth(7)

        ellipse = scene.addEllipse(10, 10, 200, 200, blackPen, redBrush)
        rectange = scene.addRect(-100, -100, 200, 200, blackPen, blueBrush)

        ellipse.setFlag(QGraphicsItem.ItemIsMovable)  #使图像可移动
        rectange.setFlag(QGraphicsItem.ItemIsMovable)

        self.graphicsView.setScene(scene)
        self.graphicsView.scale(1.2, -1.2)
class Window(QMainWindow):
    def __init__(self):
        super().__init__()

        self.title = "PyQt5 QGraphicView"
        self.top = 200
        self.left = 500
        self.width = 600
        self.height = 500

        self.InitWindow()

    def InitWindow(self):
        self.setWindowIcon(QtGui.QIcon("icon.png"))
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        self.createGraphicView()

        self.show()

    def createGraphicView(self):
        self.scene = QGraphicsScene()
        self.greenBrush = QBrush(Qt.green)
        self.grayBrush = QBrush(Qt.gray)

        self.pen = QPen(Qt.red)

        graphicView = QGraphicsView(self.scene, self)
        graphicView.setGeometry(0, 0, 600, 500)

        self.shapes()

    def shapes(self):
        ellipse = self.scene.addEllipse(20, 20, 200, 200, self.pen,
                                        self.greenBrush)
        rect = self.scene.addRect(-100, -100, 200, 200, self.pen,
                                  self.grayBrush)

        ellipse.setFlag(QGraphicsItem.ItemIsMovable)
        rect.setFlag(QGraphicsItem.ItemIsMovable)
        ellipse.setFlag(QGraphicsItem.ItemIsSelectable)
    def InitWindow(self):

        scene = QGraphicsScene(self)
        redBrush = QBrush(Qt.red)
        blueBrush = QBrush(Qt.blue)
        blackPen = QPen(Qt.black)
        blackPen.setWidth(7)

        ellipse = scene.addEllipse(10, 10, 200, 200, blackPen, redBrush)
        rect = scene.addRect(-100, -100, 200, 200, blackPen, blueBrush)

        ellipse.setFlag(QGraphicsItem.ItemIsMovable)  # set it to movable
        rect.setFlag(QGraphicsItem.ItemIsMovable)

        view = QGraphicsView(scene, self)
        view.setGeometry(0, 0, 680, 500)

        self.setWindowTitle(self.title)
        self.setGeometry(self.top, self.left, self.width, self.height)
        self.setWindowIcon(QtGui.QIcon('./icon/icon.png'))
        self.show()
Example #15
0
def main(args):  # pragma: no cover
    from PyQt5.QtWidgets import QApplication
    app = QApplication(args)
    view = StickyGraphicsView()
    scene = QGraphicsScene(view)
    scene.setBackgroundBrush(QBrush(Qt.lightGray, Qt.CrossPattern))
    view.setScene(scene)
    scene.addRect(QRectF(0, 0, 300, 20), Qt.red,
                  QBrush(Qt.red, Qt.BDiagPattern))
    scene.addRect(QRectF(0, 25, 300, 100))
    scene.addRect(QRectF(0, 130, 300, 20), Qt.darkGray,
                  QBrush(Qt.darkGray, Qt.BDiagPattern))
    view.setHeaderSceneRect(QRectF(0, 0, 300, 20))
    view.setFooterSceneRect(QRectF(0, 130, 300, 20))
    view.show()
    return app.exec()
Example #16
0
def main(args):  # pragma: no cover
    # pylint: disable=import-outside-toplevel,protected-access
    from PyQt5.QtWidgets import QApplication, QAction
    from PyQt5.QtGui import QKeySequence
    app = QApplication(args)
    view = StickyGraphicsView()
    scene = QGraphicsScene(view)
    scene.setBackgroundBrush(QBrush(Qt.lightGray, Qt.CrossPattern))
    view.setScene(scene)
    scene.addRect(QRectF(0, 0, 300, 20), Qt.red,
                  QBrush(Qt.red, Qt.BDiagPattern))
    scene.addRect(QRectF(0, 25, 300, 100))
    scene.addRect(QRectF(0, 130, 300, 20), Qt.darkGray,
                  QBrush(Qt.darkGray, Qt.BDiagPattern))
    view.setHeaderSceneRect(QRectF(0, 0, 300, 20))
    view.setFooterSceneRect(QRectF(0, 130, 300, 20))
    view.show()
    zoomin = QAction("Zoom in", view, shortcut=QKeySequence.ZoomIn)
    zoomout = QAction("Zoom out", view, shortcut=QKeySequence.ZoomOut)
    zoomreset = QAction("Reset",
                        view,
                        shortcut=QKeySequence(Qt.ControlModifier | Qt.Key_0))
    view._zoom = 100

    def set_zoom(zoom):
        if view._zoom != zoom:
            view._zoom = zoom
            view.setTransform(QTransform.fromScale(*(view._zoom / 100, ) * 2))
            zoomout.setEnabled(zoom >= 20)
            zoomin.setEnabled(zoom <= 300)

    @zoomin.triggered.connect
    def _():
        set_zoom(view._zoom + 10)

    @zoomout.triggered.connect
    def _():
        set_zoom(view._zoom - 10)

    @zoomreset.triggered.connect
    def _():
        set_zoom(100)

    view.addActions([zoomin, zoomout, zoomreset])

    return app.exec()
Example #17
0
class MyGraphicsView(QGraphicsView):
    def __init__(self, central_widget):
        super().__init__(central_widget)
        self.widget = central_widget
        self.start = [0, 0]
        self.end = [0, 0]
        self.my_scene = QGraphicsScene()
        self.rect = QRectF()
        self.old_rect_item = None
        self.old_img_item = None
        self.drawing = False

    def mousePressEvent(self, event):
        self.start = [event.x(), event.y()]
        self.drawing = True

    def mouseMoveEvent(self, event):
        if not self.drawing:
            return
        self.end = [event.x(), event.y()]

        temp_start = [min(self.start[0], self.end[0]), min(self.start[1], self.end[1])]
        temp_end = [max(self.start[0], self.end[0]), max(self.start[1], self.end[1])]

        if self.old_rect_item:
            self.my_scene.removeItem(self.old_rect_item)

        self.rect.setRect(temp_start[0], temp_start[1], temp_end[0] - temp_start[0], temp_end[1] - temp_start[1])
        self.old_rect_item = self.my_scene.addRect(self.rect, QPen(Qt.red, 1, Qt.SolidLine))
        self.setScene(self.my_scene)

    # 释放鼠标
    def mouseReleaseEvent(self, event):
        print('start:[{}, {}]'.format(self.start[0], self.start[1]))
        print('end:[{}, {}]'.format(self.end[0], self.end[1]))
        print(self.rect.getRect())
        
        self.drawing = False
Example #18
0
class PegBoard(QWidget):

    def __init__(self):
        super().__init__()
        self.region_x = 1000
        self.region_y = 1000
        self.scene = QGraphicsScene()
        self.setMouseTracking(True)
        self.board = None
        self.initUI()

    def initUI(self):
        self.setGeometry(500, 500, 500, 500)

    #TODO: will generate random board fields
    def generate_board(self):
        x =  random.randint(0, self.region_x)
        y = random.randint(0, self.region_y)
        board = [[0]*x for _ in range(y)]


    def populate_board(self, matrix):
        rectangles = [[None]*7 for _ in range(7)]
        for row_index, row_value in enumerate(matrix):
            for column_index, column_value in enumerate(row_value):
                    rec = Rectangle(100*row_index, 100*column_index, 100, 100)
                    if column_value == 1:
                        rec.state = 1
                        rectangles[row_index][column_index] = rec
                        self.scene.addRect(rec.x, rec.y, rec.w, rec.h, rec.pen, rec.brushOn)
                    elif column_value == 0:
                        rec.state == 0
                        rectangles[row_index][column_index] = rec
                        self.scene.addRect(rec.x, rec.y, rec.w, rec.h, rec.pen, rec.brushOff)
                    else:
                        rec.state = -1
                        rectangles[row_index][column_index] = rec
                        self.scene.addRect(rec.x, rec.y, rec.w, rec.h, rec.pen, rec.brushOff)
        return rectangles
Example #19
0
    def test(self):
        view = StickyGraphicsView()
        scene = QGraphicsScene(view)
        scene.setBackgroundBrush(QBrush(Qt.lightGray, Qt.CrossPattern))
        view.setScene(scene)
        scene.addRect(QRectF(0, 0, 300, 20), Qt.red,
                      QBrush(Qt.red, Qt.BDiagPattern))
        scene.addRect(QRectF(0, 25, 300, 100))
        scene.addRect(QRectF(0, 130, 300, 20), Qt.darkGray,
                      QBrush(Qt.darkGray, Qt.BDiagPattern))
        view.setHeaderSceneRect(QRectF(0, 0, 300, 20))
        view.setFooterSceneRect(QRectF(0, 130, 300, 20))

        header = view.headerView()
        footer = view.footerView()

        view.resize(310, 310)
        view.grab()

        self.assertFalse(header.isVisibleTo(view))
        self.assertFalse(footer.isVisibleTo(view))

        view.resize(310, 100)
        view.verticalScrollBar().setValue(0)  # scroll to top
        view.grab()

        self.assertFalse(header.isVisibleTo(view))
        self.assertTrue(footer.isVisibleTo(view))

        view.verticalScrollBar().setValue(
            view.verticalScrollBar().maximum())  # scroll to bottom
        view.grab()

        self.assertTrue(header.isVisibleTo(view))
        self.assertFalse(footer.isVisibleTo(view))

        qWheelScroll(header.viewport(), angleDelta=QPoint(0, -720 * 8))
Example #20
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
Example #21
0
class MainForm(QDialog):

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

        self.filename = ""
        self.copiedItem = QByteArray()
        self.pasteOffset = 5
        self.prevPoint = QPoint()
        self.addOffset = 5
        self.borders = []

        self.printer = QPrinter(QPrinter.HighResolution)
        self.printer.setPageSize(QPrinter.Letter)

        self.view = GraphicsView()
        self.scene = QGraphicsScene(self)
        self.scene.setSceneRect(0, 0, PageSize[0], PageSize[1])
        self.addBorders()
        self.view.setScene(self.scene)

        self.wrapped = [] # Needed to keep wrappers alive
        buttonLayout = QVBoxLayout()
        for text, slot in (
                ("Add &Text", self.addText),
                ("Add &Box", self.addBox),
                ("Add Pi&xmap", self.addPixmap),
                ("&Align", None),
                ("&Copy", self.copy),
                ("C&ut", self.cut),
                ("&Paste", self.paste),
                ("&Delete...", self.delete),
                ("&Rotate", self.rotate),
                ("Pri&nt...", self.print_),
                ("&Open...", self.open),
                ("&Save", self.save),
                ("&Quit", self.accept)):
            button = QPushButton(text)
            if not MAC:
                button.setFocusPolicy(Qt.NoFocus)
            if slot is not None:
                button.clicked.connect(slot)
            if text == "&Align":
                menu = QMenu(self)
                for text, arg in (
                        ("Align &Left", Qt.AlignLeft),
                        ("Align &Right", Qt.AlignRight),
                        ("Align &Top", Qt.AlignTop),
                        ("Align &Bottom", Qt.AlignBottom)):
                    wrapper = functools.partial(self.setAlignment, arg)
                    self.wrapped.append(wrapper)
                    menu.addAction(text, wrapper)
                button.setMenu(menu)
            if text == "Pri&nt...":
                buttonLayout.addStretch(5)
            if text == "&Quit":
                buttonLayout.addStretch(1)
            buttonLayout.addWidget(button)
        buttonLayout.addStretch()

        layout = QHBoxLayout()
        layout.addWidget(self.view, 1)
        layout.addLayout(buttonLayout)
        self.setLayout(layout)

        fm = QFontMetrics(self.font())
        self.resize(self.scene.width() + fm.width(" Delete... ") + 50,
                    self.scene.height() + 50)
        self.setWindowTitle("Page Designer")


    def addBorders(self):
        self.borders = []
        rect = QRectF(0, 0, PageSize[0], PageSize[1])
        self.borders.append(self.scene.addRect(rect, Qt.yellow))
        margin = 5.25 * PointSize
        self.borders.append(self.scene.addRect(
                rect.adjusted(margin, margin, -margin, -margin),
                Qt.yellow))


    def removeBorders(self):
        while self.borders:
            item = self.borders.pop()
            self.scene.removeItem(item)
            del item


    def reject(self):
        self.accept()


    def accept(self):
        self.offerSave()
        QDialog.accept(self)


    def offerSave(self):
        if (Dirty and QMessageBox.question(self,
                            "Page Designer - Unsaved Changes",
                            "Save unsaved changes?",
                            QMessageBox.Yes|QMessageBox.No) == 
           QMessageBox.Yes):
            self.save()


    def position(self):
        point = self.mapFromGlobal(QCursor.pos())
        if not self.view.geometry().contains(point):
            coord = random.randint(36, 144)
            point = QPoint(coord, coord)
        else:
            if point == self.prevPoint:
                point += QPoint(self.addOffset, self.addOffset)
                self.addOffset += 5
            else:
                self.addOffset = 5
                self.prevPoint = point
        return self.view.mapToScene(point)


    def addText(self):
        dialog = TextItemDlg(position=self.position(),
                             scene=self.scene, parent=self)
        dialog.exec_()


    def addBox(self):
        BoxItem(self.position(), self.scene)


    def addPixmap(self):
        path = (QFileInfo(self.filename).path()
            if self.filename else ".")
        fname,filetype = QFileDialog.getOpenFileName(self,
                "Page Designer - Add Pixmap", path,
                "Pixmap Files (*.bmp *.jpg *.png *.xpm)")
        if not fname:
            return
        self.createPixmapItem(QPixmap(fname), self.position())


    def createPixmapItem(self, pixmap, position, matrix=QTransform()):
        item = GraphicsPixmapItem(pixmap)
        item.setFlags(QGraphicsItem.ItemIsSelectable|
                      QGraphicsItem.ItemIsMovable)
        item.setPos(position)
        item.setTransform(matrix)
        self.scene.clearSelection()
        self.scene.addItem(item)
        item.setSelected(True)
        global Dirty
        Dirty = True
        return item


    def selectedItem(self):
        items = self.scene.selectedItems()
        if len(items) == 1:
            return items[0]
        return None


    def copy(self):
        item = self.selectedItem()
        if item is None:
            return
        self.copiedItem.clear()
        self.pasteOffset = 5
        stream = QDataStream(self.copiedItem, QIODevice.WriteOnly)
        self.writeItemToStream(stream, item)


    def cut(self):
        item = self.selectedItem()
        if item is None:
            return
        self.copy()
        self.scene.removeItem(item)
        del item


    def paste(self):
        if self.copiedItem.isEmpty():
            return
        stream = QDataStream(self.copiedItem, QIODevice.ReadOnly)
        self.readItemFromStream(stream, self.pasteOffset)
        self.pasteOffset += 5


    def setAlignment(self, alignment):
        # Items are returned in arbitrary order
        items = self.scene.selectedItems()
        if len(items) <= 1:
            return
        # Gather coordinate data
        leftXs, rightXs, topYs, bottomYs = [], [], [], []
        for item in items:
            rect = item.sceneBoundingRect()
            leftXs.append(rect.x())
            rightXs.append(rect.x() + rect.width())
            topYs.append(rect.y())
            bottomYs.append(rect.y() + rect.height())
        # Perform alignment
        if alignment == Qt.AlignLeft:
            xAlignment = min(leftXs)
            for i, item in enumerate(items):
                item.moveBy(xAlignment - leftXs[i], 0)
        elif alignment == Qt.AlignRight:
            xAlignment = max(rightXs)
            for i, item in enumerate(items):
                item.moveBy(xAlignment - rightXs[i], 0)
        elif alignment == Qt.AlignTop:
            yAlignment = min(topYs)
            for i, item in enumerate(items):
                item.moveBy(0, yAlignment - topYs[i])
        elif alignment == Qt.AlignBottom:
            yAlignment = max(bottomYs)
            for i, item in enumerate(items):
                item.moveBy(0, yAlignment - bottomYs[i])
        global Dirty
        Dirty = True


    def rotate(self):
        for item in self.scene.selectedItems():
            item.setRotation(item.rotation()+30)

    def delete(self):
        items = self.scene.selectedItems()
        if (len(items) and QMessageBox.question(self,
                "Page Designer - Delete",
                "Delete {0} item{1}?".format(len(items),
                "s" if len(items) != 1 else ""),
                QMessageBox.Yes|QMessageBox.No) ==
                QMessageBox.Yes):
            while items:
                item = items.pop()
                self.scene.removeItem(item)
                del item
            global Dirty
            Dirty = True


    def print_(self):
        dialog = QPrintDialog(self.printer)
        if dialog.exec_():
            painter = QPainter(self.printer)
            painter.setRenderHint(QPainter.Antialiasing)
            painter.setRenderHint(QPainter.TextAntialiasing)
            self.scene.clearSelection()
            self.removeBorders()
            self.scene.render(painter)
            self.addBorders()


    def open(self):
        self.offerSave()
        path = (QFileInfo(self.filename).path()
                if self.filename else ".")
        fname,filetype = QFileDialog.getOpenFileName(self,
                "Page Designer - Open", path,
                "Page Designer Files (*.pgd)")
        if not fname:
            return
        self.filename = fname
        fh = None
        try:
            fh = QFile(self.filename)
            if not fh.open(QIODevice.ReadOnly):
                raise IOError(str(fh.errorString()))
            items = self.scene.items()
            while items:
                item = items.pop()
                self.scene.removeItem(item)
                del item
            self.addBorders()
            stream = QDataStream(fh)
            stream.setVersion(QDataStream.Qt_5_7)
            magic = stream.readInt32()
            if magic != MagicNumber:
                raise IOError("not a valid .pgd file")
            fileVersion = stream.readInt16()
            if fileVersion != FileVersion:
                raise IOError("unrecognised .pgd file version")
            while not fh.atEnd():
                self.readItemFromStream(stream)
        except IOError as e:
            QMessageBox.warning(self, "Page Designer -- Open Error",
                    "Failed to open {0}: {1}".format(self.filename, e))
        finally:
            if fh is not None:
                fh.close()
        global Dirty
        Dirty = False


    def save(self):
        if not self.filename:
            path = "."
            fname,filetype = QFileDialog.getSaveFileName(self,
                    "Page Designer - Save As", path,
                    "Page Designer Files (*.pgd)")
            if not fname:
                return
            self.filename = fname
        fh = None
        try:
            fh = QFile(self.filename)
            if not fh.open(QIODevice.WriteOnly):
                raise IOError(str(fh.errorString()))
            self.scene.clearSelection()
            stream = QDataStream(fh)
            stream.setVersion(QDataStream.Qt_5_7)
            stream.writeInt32(MagicNumber)
            stream.writeInt16(FileVersion)
            for item in self.scene.items():
                self.writeItemToStream(stream, item)
        except IOError as e:
            QMessageBox.warning(self, "Page Designer -- Save Error",
                    "Failed to save {0}: {1}".format(self.filename, e))
        finally:
            if fh is not None:
                fh.close()
        global Dirty
        Dirty = False


    def readItemFromStream(self, stream, offset=0):
        type = ""
        position = QPointF()
        matrix = QTransform()
        rotateangle=0#add by yangrongdong
        type=stream.readQString()
        stream >> position >> matrix
        if offset:
            position += QPointF(offset, offset)
        if type == "Text":
            text = ""
            font = QFont()
            text=stream.readQString()
            stream >> font
            rotateangle=stream.readFloat()
            tx=TextItem(text, position, self.scene, font, matrix)
            tx.setRotation(rotateangle)
        elif type == "Box":
            rect = QRectF()
            stream >> rect
            style = Qt.PenStyle(stream.readInt16())
            rotateangle=stream.readFloat()
            bx=BoxItem(position, self.scene, style, rect, matrix)
            bx.setRotation(rotateangle)
        elif type == "Pixmap":
            pixmap = QPixmap()
            stream >> pixmap
            rotateangle=stream.readFloat()
            px=self.createPixmapItem(pixmap, position, matrix)
            px.setRotation(rotateangle)


    def writeItemToStream(self, stream, item):
        if isinstance(item, TextItem):
            stream.writeQString("Text")
            stream<<item.pos()<< item.transform() 
            stream.writeQString(item.toPlainText())
            stream<< item.font()
            stream.writeFloat(item.rotation())#add by yangrongdong
        elif isinstance(item, GraphicsPixmapItem):
            stream.writeQString("Pixmap")
            stream << item.pos() << item.transform() << item.pixmap()
            stream.writeFloat(item.rotation())#add by yangrongdong
        elif isinstance(item, BoxItem):
            stream.writeQString("Box")
            stream<< item.pos() << item.transform() << item.rect
            stream.writeInt16(item.style)
            stream.writeFloat(item.rotation())#add by yangrongdong
Example #22
0
class Board(QGraphicsView):
    def __init__(self, score, player_clock, ai_clock, add_comment, text_field, set_prompt, confirm_button,
                 disable_buttons, sack_counter):
        QGraphicsView.__init__(self)

        self.scale = 1

        self._board_squares = {}
        self._other_squares = {}
        self._bonus_fields = []
        self._labels = {}

        self.scene = QGraphicsScene()
        self.build_board_scene()
        self.prepare_board()
        self.setScene(self.scene)

        self.player_clock = player_clock
        self.ai_clock = ai_clock
        self.add_info = add_comment
        self.set_prompt = set_prompt
        self.disable_buttons = disable_buttons
        self.confirm_button = confirm_button
        self.text_field = text_field

        self.is_game_started = False

        # parameters visible for AI
        self.tiles_for_ai = {}
        # sack represents sack
        self.sack = None

        self.sack_counter = sack_counter
        # score represents total score of both players
        self.score = score
        # tiles represent all tiles on board
        self._tiles = {}
        # latest tiles represent tiles added in last turn
        self.new_tiles = []
        self._latest_tiles = set()
        self._tiles_in_rack = set()
        self._tiles_to_exchange = set()
        self._blanks = []
        self._points = 0
        self._words = []
        self._is_connected = False
        self.ai = None

    def auto_resize(self):
        if self.height() / self.width() < DEFAULT_HEIGHT / DEFAULT_WIDTH:
            scale = round(self.height() / DEFAULT_HEIGHT, 1)
        else:
            scale = round(self.width() / DEFAULT_WIDTH, 1)

        if abs(scale - self.scale) < 0.0001:
            return
        self.scale = scale

        self.scene.setSceneRect(-SQUARE_SIZE / 2, -SQUARE_SIZE / 2, SQUARE_SIZE * 16 * self.scale,
                                SQUARE_SIZE * 19 * self.scale)
        for tile in self._tiles.values():
            tile.resize(self.scale)
        for square in self._board_squares.values():
            square.setScale(self.scale)
        for square in self._other_squares.values():
            square.setScale(self.scale)
        for x, y in self._labels:
            label = self._labels.get((x, y))
            label.setScale(self.scale)
            label.setPos(x * self.scale, y * self.scale)

    def prepare_game(self):
        self.sack = Sack(self.sack_counter)
        self.ai = AI(self.tiles_for_ai, self.sack)

    def reset_game(self):
        self.is_game_started = False
        self.ai.stop()

        for tile in self._tiles.values():
            self.scene.removeItem(tile)

        self.tiles_for_ai.clear()
        self._tiles.clear()
        self._latest_tiles.clear()
        self._tiles_in_rack.clear()
        self._tiles_to_exchange.clear()
        self._blanks.clear()
        self._words.clear()
        self._points = 0
        self._is_connected = False
        self.prepare_game()

    def start_game(self):
        if self.is_game_started:
            self.reset_game()
        self.prepare_game()
        self.is_game_started = True
        self.ai.is_turn = bool(getrandbits(1))
        self.add_letters_to_rack()
        self.ai.finished.connect(self.end_ai_turn)
        self.ai.start()
        if self.ai.is_turn:
            self.add_info('Przeciwnik zaczyna')
            self.start_ai_turn()
        else:
            self.add_info('Zaczynasz')
            self.player_clock.start()

    def move_to_rack(self, tile):
        old_coords = tile.coords
        if old_coords in self._tiles_in_rack:
            return

        coords = Coords(LEFT_RACK_BOUND, RACK_ROW)
        while coords in self._tiles_in_rack:
            coords = coords.move(RIGHT)

        if old_coords in self._tiles_to_exchange:
            self._tiles_to_exchange.remove(old_coords)
        else:
            self._latest_tiles.remove(old_coords)

        del self._tiles[old_coords]
        self._tiles[coords] = tile
        self._tiles_in_rack.add(coords)
        tile.move_to_coords(coords)

    def collect_tiles(self):
        for coords in set.union(self._latest_tiles, self._tiles_to_exchange):
            tile = self.get_tile(coords)
            self.move_to_rack(tile)

    def skip_turn(self):
        self.collect_tiles()
        self.score.add_points('Gracz', '(Pominięcie ruchu)', 0)
        self.start_ai_turn()

    def player_ends(self):
        self.player_clock.stop()
        points = 0
        letters = ' '
        for letter in self.ai.rack:
            points += Sack.get_value(letter)
            letters += f'{letter}, '

        self.score.add_points('AI', f'(Zostały {letters[:-2]})', -points)
        self.score.add_points('Gracz', '', points)
        self.end_game()

    def ai_ends(self):
        points = 0
        letters = ' '
        for coords in self._tiles_in_rack:
            tile = self.get_tile(coords)
            points += tile.points
            letters += f'{tile.letter}, '
        for coords in self._tiles_to_exchange:
            tile = self.get_tile(coords)
            points += tile.points
            letters += f'{tile.letter}, '

        self.score.add_points('Gracz', f'(Zostały {letters[:-2]})', -points)
        self.score.add_points('AI', '', points)
        self.end_game()

    def end_game(self):
        self.disable_buttons(True)
        player_score = self.score.get_score('Gracz')
        ai_score = self.score.get_score('AI')
        if player_score > ai_score:
            self.add_info('Gratulacje! Udało Ci się pokonać algorytm!')
        elif player_score < ai_score:
            self.add_info('Tym razem się nie udało. Próbuj dalej :)')
        else:
            self.add_info('Dobry remis nie jest zły ;)')

    def add_letters_to_rack(self, letters=None):
        if not letters:
            letters = self.sack.draw(MAX_RACK_SIZE - len(self._tiles_in_rack) - len(self._tiles_to_exchange))

        for column in range(LEFT_RACK_BOUND, RIGHT_RACK_BOUND + 1):
            if not letters:
                return
            coords = Coords(column, RACK_ROW)
            if not self.get_tile(coords) and len(self._tiles_in_rack) + len(self._tiles_to_exchange) < MAX_RACK_SIZE:
                letter = letters.pop()

                coords = Coords(column, RACK_ROW)
                points = Sack.get_value(letter)
                tile = Tile(letter, points, coords, self.scale, self.on_tile_move, self.move_to_rack)
                self.scene.addItem(tile)
                self._tiles_in_rack.add(coords)
                self._tiles[coords] = tile

    def exchange_letters(self):
        if self.ai.is_turn:
            self.add_info('Ruch przeciwnika')
            return

        if not self._tiles_to_exchange:
            self.add_info('Brak liter do wymiany')
            return

        letters_to_exchange = []
        for coords in self._tiles_to_exchange:
            tile = self.get_tile(coords)
            letters_to_exchange.append(tile.letter)
            del self._tiles[tile.coords]
            self.scene.removeItem(tile)

        letters_on_board = []
        for coords in self._latest_tiles:
            tile = self.get_tile(coords)
            letters_on_board.append(tile.letter)
            del self._tiles[tile.coords]
            self.scene.removeItem(tile)

        self._tiles_to_exchange.clear()
        self._latest_tiles.clear()

        new_letters = self.sack.exchange(letters_to_exchange)
        self.score.add_points('Gracz', '(wymiana liter)', 0)

        if not new_letters:
            self.add_info('Za mało płytek w worku')
            self.add_letters_to_rack(letters_to_exchange + letters_on_board)
            return

        self.add_info('Wymieniłeś/aś litery')
        self.add_letters_to_rack(new_letters + letters_on_board)

        self.start_ai_turn()

    def start_ai_turn(self):
        self.player_clock.stop()
        self.tiles_for_ai.clear()
        for coords in self._latest_tiles:
            self.tiles_for_ai[coords] = self.get_tile(coords)

        for tile in self.new_tiles:
            tile.remove_highlight()
        self.new_tiles.clear()

        self.ai.is_turn = True
        self.ai_clock.start()
        self.disable_buttons(True)

    def end_ai_turn(self):
        if not self.is_game_started:
            return

        self.ai_clock.stop()
        self.disable_buttons(False)

        word = self.ai.word
        words = [word]

        for coords in self._latest_tiles:
            tile = self.get_tile(coords)
            tile.remove_highlight()

        self._latest_tiles.clear()

        if word:
            for coords in word.added_letters:
                letter, points = word.added_letters.get(coords)
                tile = Tile(letter, points, coords, self.scale)
                tile.place()
                self._tiles[coords] = tile
                self.scene.addItem(tile)
                self.new_tiles.append(tile)
                perpendicular_word = self.find_word(coords, ~word.direction(), False)
                if perpendicular_word:
                    words.append(perpendicular_word)

            self.score.add_points('AI', words, word.sum_up())

        else:
            self.add_info(f'Komputer wymienił litery')
            self.score.add_points('AI', '(wymiana liter)', 0)

        if not self.ai.rack:
            self.ai_ends()
            return

        self.player_clock.start()

    def wait_for_blank(self, blank):
        self._blanks.append(blank)
        self.set_prompt("Jaką literą ma być blank?")
        self.text_field.setDisabled(False)
        self.confirm_button.setDisabled(False)
        self.disable_buttons(True)

    def stop_waiting_for_blank(self):
        self.set_prompt('')
        self.text_field.setDisabled(True)
        self.text_field.clear()
        self.confirm_button.setDisabled(True)
        self.disable_buttons(False)

    def revert_blanks(self):
        for blank in self._blanks:
            blank.change_back()
        self._blanks.clear()
        self.stop_waiting_for_blank()

    def blank_entered(self):
        tile = self._blanks[-1]
        new_letter = self.text_field.text()
        if new_letter.lower() in Sack.values_without_blank():
            tile.change_to_blank(new_letter)
            self.stop_waiting_for_blank()
            self.end_turn()
        else:
            self.add_info('Podaj poprawną literę')
            self.text_field.clear()
            return

    def end_turn(self):
        if self.ai.is_turn:
            self.add_info('Ruch przeciwnika')
            return

        self._is_connected = False

        if not self._latest_tiles:
            self.add_info('Musisz najpierw wykonać ruch')
            return

        if not self.get_tile(Coords.central()):
            self.add_info('Pierwszy wyraz musi przechodzić przez środek')
            return

        if Coords.central() in self._latest_tiles:
            self._is_connected = True
            if len(self._latest_tiles) == 1:
                self.add_info('Wyraz musi zawierać przynajmniej dwie litery')
                return

        first_tile_coords = min(self._latest_tiles)
        last_tile_coords = max(self._latest_tiles)

        if first_tile_coords.is_same_column(last_tile_coords):
            direction = DOWN
        else:
            direction = RIGHT

        if len(self._latest_tiles) == 1 and (self.get_tile(first_tile_coords.move(RIGHT)) or self.get_tile(
                first_tile_coords.move(RIGHT))):
            self._is_connected = True

        columns = set()
        rows = set()
        for tile in self._latest_tiles:
            columns.add(tile.x)
            rows.add(tile.y)

        if len(rows) > 1 and len(columns) > 1:
            self.add_info('Litery muszą być ułożone w jednej linii')
            return

        while self.get_tile(first_tile_coords.move(-direction)):
            first_tile_coords = first_tile_coords.move(-direction)

        while self.get_tile(last_tile_coords.move(direction)):
            last_tile_coords = last_tile_coords.move(direction)

        current_coords = first_tile_coords

        while current_coords <= last_tile_coords:
            tile = self.get_tile(current_coords)
            if not tile:
                self.add_info("Litery muszą należeć do tego samego wyrazu")
                return

            if tile.is_placed or self.get_tile(
                    current_coords.move(~direction)) or self.get_tile(
                    current_coords.move(-~direction)):
                self._is_connected = True

            if tile.letter == BLANK:
                self.wait_for_blank(tile)
                return

            current_coords = current_coords.move(direction)

        if not self._is_connected:
            self.add_info('Wyraz musi się stykać z występującymi już na planszy')
            return

        self._words.clear()
        self._points = 0

        self.find_word(first_tile_coords, direction)

        if len(columns) > 1:
            for column in columns:
                self.find_word(Coords(column, first_tile_coords.y), ~direction)

        else:
            for row in rows:
                self.find_word(Coords(first_tile_coords.x, row), ~direction)

        for word in self._words:
            if not Dictionary.is_word_in_dictionary(word):
                self.add_info(f'słowo "{word}" nie występuje w słowniku')
                if self._blanks:
                    self.revert_blanks()
                return

        for coords in self._latest_tiles:
            tile = self.get_tile(coords)
            tile.place()

        self._blanks.clear()

        if len(self._latest_tiles) == MAX_RACK_SIZE:
            self._points += 50

        self.score.add_points('Gracz', self._words, self._points)
        self.add_letters_to_rack()

        if not self._tiles_in_rack and not self._tiles_to_exchange and not self.sack.how_many_remain():
            self.player_ends()
            return

        self.start_ai_turn()

    def find_word(self, coords, direction, is_players_turn=True):
        word = ''
        word_points = 0
        word_multiplier = 1
        direction = abs(direction)

        first_tile = coords
        while self.get_tile(first_tile.move(-direction)):
            first_tile = first_tile.move(-direction)

        last_tile = coords
        while self.get_tile(last_tile.move(direction)):
            last_tile = last_tile.move(direction)

        if first_tile == last_tile:
            return

        current_tile = first_tile
        while current_tile <= last_tile:
            tile = self.get_tile(current_tile)
            points = tile.points

            if not tile.is_placed:
                if current_tile in double_letter_bonuses:
                    points *= 2
                elif current_tile in triple_letter_bonuses:
                    points *= 3
                elif current_tile in double_word_bonuses:
                    word_multiplier *= 2
                elif current_tile in triple_word_bonuses:
                    word_multiplier *= 3

            word_points += points
            word += tile.letter

            current_tile = current_tile.move(direction)

        if is_players_turn:
            self._words.append(word)
            self._points += word_points * word_multiplier
        else:
            return word

    def swap_tiles(self, tile, other_tile):
        tile.swap_with_other(other_tile)
        self._tiles[tile.coords] = tile
        self._tiles[other_tile.coords] = other_tile

    def on_tile_move(self, tile):
        if not tile.coords.is_valid():
            tile.undo_move()
            return
        if tile.coords.is_on_board() and self.ai.is_turn:
            self.add_info('Ruch przeciwnika')
            tile.undo_move()
            return

        other_tile = None
        if tile.coords in set.union(self._latest_tiles, self._tiles_in_rack, self._tiles_to_exchange):
            other_tile = self.get_tile(tile.coords)

        if other_tile:
            self.swap_tiles(tile, other_tile)

        elif self.get_tile(tile.coords):
            tile.undo_move()
            return

        else:
            del self._tiles[tile.old_coords]
            if tile.old_coords.is_in_rack():
                self._tiles_in_rack.remove(tile.old_coords)

            elif tile.old_coords.is_in_exchange_zone():
                self._tiles_to_exchange.remove(tile.old_coords)
            else:
                self._latest_tiles.remove(tile.old_coords)

            self._tiles[tile.coords] = tile
            if tile.coords.is_in_rack():
                self._tiles_in_rack.add(tile.coords)
            elif tile.coords.is_in_exchange_zone():
                self._tiles_to_exchange.add(tile.coords)
            else:
                self._latest_tiles.add(tile.coords)

    def get_tile(self, coords: Coords) -> Tile:
        return self._tiles.get(coords)

    def build_board_scene(self):
        self.build_squares()
        self.prepare_bonus_fields()
        self.build_bonus_fields()
        self.build_rack()
        self.build_exchange_zone()
        self.build_labels()

    def build_squares(self):
        brush = QBrush(LIGHT_SEA_GREEN)
        pen = QPen(DARK_SEA_GREEN, 1, Qt.SolidLine)

        for row in range(LAST_ROW + 1):
            for column in range(LAST_COLUMN + 1):
                square = self.add_square(row, column, pen, brush)
                self._board_squares[Coords(row, column)] = square

    def build_bonus_fields(self):
        for bonus_field in self._bonus_fields:
            brush = bonus_field["Brush"]
            pen = bonus_field["Pen"]
            bonus_fields = []

            for coords in bonus_field["Coords"]:
                label = bonus_field["Name"]
                if coords == Coords.central():
                    label = '✸'
                square = self._board_squares[coords]
                square.setZValue(2)
                bonus_fields.append(square)
                field_name = QGraphicsSimpleTextItem(label)
                font = field_name.font()
                font.setPointSize(10)
                if coords == Coords.central():
                    font.setPointSize(20)
                fm = QFontMetrics(font)
                field_name.setZValue(2.1)
                field_name.setFont(font)
                x = coords.x * SQUARE_SIZE + (SQUARE_SIZE - fm.width(label)) / 2
                y = coords.y * SQUARE_SIZE + (SQUARE_SIZE - fm.height()) / 2
                field_name.setPos(x, y)
                field_name.setBrush(bonus_field["Label brush"])

                self._labels[(x, y)] = field_name
                self.scene.addItem(field_name)

            paint_graphic_items(bonus_fields, pen, brush)

    def build_rack(self):
        brush = QBrush(LIGHT_BROWN)
        pen = QPen(BROWN, 1, Qt.SolidLine)
        for column in range(LEFT_RACK_BOUND, RIGHT_RACK_BOUND + 1):
            square = self.add_square(RACK_ROW, column, pen, brush)
            self._other_squares[Coords(column, RACK_ROW)] = square

    def build_exchange_zone(self):
        brush = QBrush(LIGHT_BROWN)
        pen = QPen(BROWN, 1, Qt.SolidLine)
        for column in range(LEFT_RACK_BOUND, RIGHT_RACK_BOUND + 1):
            square = self.add_square(EXCHANGE_ROW, column, pen, brush)
            self._other_squares[Coords(column, EXCHANGE_ROW)] = square

        text = 'Litery do wymiany →     '
        font = QFont('Verdana', 10)
        fm = QFontMetrics(font)
        x = SQUARE_SIZE * LEFT_RACK_BOUND - fm.width(text)
        y = SQUARE_SIZE * EXCHANGE_ROW + (SQUARE_SIZE - fm.height()) / 2
        label = QGraphicsSimpleTextItem(text)
        label.setPos(x, y)
        label.setFont(font)
        label.setBrush(QBrush(Qt.white))
        self._labels[(x, y)] = label
        self.scene.addItem(label)

    def add_square(self, row, column, pen, brush):
        height = SQUARE_SIZE
        width = SQUARE_SIZE

        column_distance = column * width
        row_distance = row * height

        x = column_distance
        y = row_distance
        rectangle = QRectF(x, y, width, height)

        return self.scene.addRect(rectangle, pen, brush)

    def build_labels(self):
        font = QFont('Verdana', 10)
        fm = QFontMetrics(font)
        for count in range(LAST_ROW + 1):
            number = str(count + 1)
            number_label = QGraphicsSimpleTextItem(number)
            x = -fm.width(number) - SQUARE_SIZE / 8
            y = count * SQUARE_SIZE + (SQUARE_SIZE - fm.height()) / 2
            number_label.setPos(x, y)
            number_label.setFont(font)
            number_label.setBrush(QBrush(Qt.white))
            self._labels[(x, y)] = number_label

            letter = chr(count + ord('A'))
            letter_label = QGraphicsSimpleTextItem(letter)
            x = count * SQUARE_SIZE + (SQUARE_SIZE - fm.width(letter)) / 2
            y = -fm.height() - SQUARE_SIZE / 8
            letter_label.setPos(x, y)
            letter_label.setFont(font)
            letter_label.setBrush(QBrush(Qt.white))
            self._labels[(x, y)] = letter_label

            self.scene.addItem(number_label)
            self.scene.addItem(letter_label)

    def prepare_bonus_fields(self):

        triple_word_bonus_fields = {
            "Name": "3S",
            "Pen": QPen(DARK_RED, 1, Qt.SolidLine, Qt.RoundCap, Qt.BevelJoin),
            "Brush": QBrush(RED),
            "Label brush": QBrush(DARK_RED),
            "Coords": triple_word_bonuses
        }
        self._bonus_fields.append(triple_word_bonus_fields)

        double_word_bonus_fields = {
            "Name": "2S",
            "Pen": QPen(RED, 1, Qt.SolidLine, Qt.RoundCap, Qt.BevelJoin),
            "Brush": QBrush(PINK),
            "Label brush": QBrush(RED),
            "Coords": double_word_bonuses
        }
        self._bonus_fields.append(double_word_bonus_fields)

        triple_letter_bonus_fields = {
            "Name": "3L",
            "Pen": QPen(NAVY_BLUE, 1, Qt.SolidLine, Qt.RoundCap, Qt.BevelJoin),
            "Brush": QBrush(BLUE),
            "Label brush": QBrush(NAVY_BLUE),
            "Coords": triple_letter_bonuses
        }
        self._bonus_fields.append(triple_letter_bonus_fields)

        double_letter_bonus_fields = {
            "Name": "2L",
            "Pen": QPen(BLUE2, 1, Qt.SolidLine, Qt.RoundCap, Qt.BevelJoin),
            "Brush": QBrush(LIGHT_BLUE),
            "Label brush": QBrush(BLUE2),
            "Coords": double_letter_bonuses
        }
        self._bonus_fields.append(double_letter_bonus_fields)

    def prepare_board(self):
        self.scene.setSceneRect(-SQUARE_SIZE / 2, -SQUARE_SIZE / 2, SQUARE_SIZE * 16, SQUARE_SIZE * 19)
        self.scene.setBackgroundBrush(QBrush(SEA_GREEN))
        self.setMinimumSize(MINIMAL_WIDTH, MINIMAL_HEIGHT)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
Example #23
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_()
Example #24
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
Example #25
0
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1100, 700)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred,
                                           QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            MainWindow.sizePolicy().hasHeightForWidth())
        MainWindow.setSizePolicy(sizePolicy)
        MainWindow.setStyleSheet("color: rgb(85, 85, 255);\n"
                                 "font: 25 10pt \"Calibri Light\";")
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.gridLayout_2 = QtWidgets.QGridLayout(self.centralwidget)
        self.gridLayout_2.setObjectName("gridLayout_2")
        self.table = QtWidgets.QTableWidget(self.centralwidget)
        self.table.setObjectName("table")
        self.table.setColumnCount(5)
        self.table.setRowCount(0)
        item = QtWidgets.QTableWidgetItem()
        self.table.setHorizontalHeaderItem(0, item)
        item = QtWidgets.QTableWidgetItem()
        self.table.setHorizontalHeaderItem(1, item)
        item = QtWidgets.QTableWidgetItem()
        self.table.setHorizontalHeaderItem(2, item)
        item = QtWidgets.QTableWidgetItem()
        self.table.setHorizontalHeaderItem(3, item)
        item = QtWidgets.QTableWidgetItem()
        self.table.setHorizontalHeaderItem(4, item)
        self.gridLayout_2.addWidget(self.table, 7, 0, 1, 1)
        self.label_gantt_chart = QtWidgets.QLabel(self.centralwidget)
        self.label_gantt_chart.setStyleSheet("font: 75 12pt \"Calibri\";\n"
                                             "color: rgb(0, 85, 127);")
        self.label_gantt_chart.setObjectName("label_gantt_chart")
        self.gridLayout_2.addWidget(self.label_gantt_chart, 11, 0, 1, 2,
                                    QtCore.Qt.AlignHCenter)
        self.label_processes_data = QtWidgets.QLabel(self.centralwidget)
        self.label_processes_data.setStyleSheet("font: 75 12pt \"Calibri\";\n"
                                                "color: rgb(0, 85, 127);")
        self.label_processes_data.setObjectName("label_processes_data")
        self.gridLayout_2.addWidget(self.label_processes_data, 2, 0, 1, 1,
                                    QtCore.Qt.AlignHCenter)
        self.chart_view = QtWidgets.QGraphicsView(self.centralwidget)
        self.chart_view.setObjectName("chart_view")
        self.gridLayout_2.addWidget(self.chart_view, 15, 0, 1, 2)
        spacerItem = QtWidgets.QSpacerItem(40, 20,
                                           QtWidgets.QSizePolicy.Expanding,
                                           QtWidgets.QSizePolicy.Minimum)
        self.gridLayout_2.addItem(spacerItem, 1, 0, 1, 2)
        self.formLayout = QtWidgets.QFormLayout()
        self.formLayout.setObjectName("formLayout")
        self.label_avg_waiting_time = QtWidgets.QLabel(self.centralwidget)
        self.label_avg_waiting_time.setObjectName("label_avg_waiting_time")
        self.formLayout.setWidget(0, QtWidgets.QFormLayout.LabelRole,
                                  self.label_avg_waiting_time)
        self.label_avg_turnaround_time = QtWidgets.QLabel(self.centralwidget)
        self.label_avg_turnaround_time.setObjectName(
            "label_avg_turnaround_time")
        self.formLayout.setWidget(1, QtWidgets.QFormLayout.LabelRole,
                                  self.label_avg_turnaround_time)
        self.avg_waiting_label = QtWidgets.QLabel(self.centralwidget)
        self.avg_waiting_label.setText("")
        self.avg_waiting_label.setObjectName("avg_waiting_label")
        self.formLayout.setWidget(0, QtWidgets.QFormLayout.FieldRole,
                                  self.avg_waiting_label)
        self.avg_turnaround_label = QtWidgets.QLabel(self.centralwidget)
        self.avg_turnaround_label.setText("")
        self.avg_turnaround_label.setObjectName("avg_turnaround_label")
        self.formLayout.setWidget(1, QtWidgets.QFormLayout.FieldRole,
                                  self.avg_turnaround_label)
        self.gridLayout_2.addLayout(self.formLayout, 6, 1, 1, 1)
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.label_desired_algorithm = QtWidgets.QLabel(self.centralwidget)
        self.label_desired_algorithm.setObjectName("label_desired_algorithm")
        self.horizontalLayout_2.addWidget(self.label_desired_algorithm, 0,
                                          QtCore.Qt.AlignRight)
        self.algorithm_dropdown = QtWidgets.QComboBox(self.centralwidget)
        self.algorithm_dropdown.setStyleSheet(
            "background-color: rgb(247, 248, 255);")
        self.algorithm_dropdown.setObjectName("algorithm_dropdown")
        self.algorithm_dropdown.addItem("")
        self.algorithm_dropdown.setItemText(0, "")
        self.algorithm_dropdown.addItem("")
        self.algorithm_dropdown.addItem("")
        self.algorithm_dropdown.addItem("")
        self.algorithm_dropdown.addItem("")
        self.algorithm_dropdown.addItem("")
        self.algorithm_dropdown.addItem("")
        self.horizontalLayout_2.addWidget(self.algorithm_dropdown)
        self.label_time_quantum = QtWidgets.QLabel(self.centralwidget)
        self.label_time_quantum.setObjectName("label_time_quantum")
        self.horizontalLayout_2.addWidget(self.label_time_quantum, 0,
                                          QtCore.Qt.AlignRight)
        self.tq_in = QtWidgets.QLineEdit(self.centralwidget)
        self.tq_in.setObjectName("tq_in")
        self.horizontalLayout_2.addWidget(self.tq_in, 0, QtCore.Qt.AlignLeft)
        self.simulate_b = QtWidgets.QPushButton(self.centralwidget)
        self.simulate_b.setStyleSheet("background-color: rgb(247, 248, 255);")
        self.simulate_b.setObjectName("simulate_b")
        self.horizontalLayout_2.addWidget(self.simulate_b)
        self.clear_b = QtWidgets.QPushButton(self.centralwidget)
        self.clear_b.setStyleSheet("background-color: rgb(247, 248, 255);")
        self.clear_b.setObjectName("clear_b")
        self.horizontalLayout_2.addWidget(self.clear_b)
        self.gridLayout_2.addLayout(self.horizontalLayout_2, 13, 0, 2, 2)
        spacerItem1 = QtWidgets.QSpacerItem(40, 20,
                                            QtWidgets.QSizePolicy.Expanding,
                                            QtWidgets.QSizePolicy.Minimum)
        self.gridLayout_2.addItem(spacerItem1, 8, 0, 1, 2)
        self.label_scheduling_stats = QtWidgets.QLabel(self.centralwidget)
        self.label_scheduling_stats.setStyleSheet(
            "font: 75 12pt \"Calibri\";\n"
            "color: rgb(0, 85, 127);")
        self.label_scheduling_stats.setObjectName("label_scheduling_stats")
        self.gridLayout_2.addWidget(self.label_scheduling_stats, 2, 1, 1, 1,
                                    QtCore.Qt.AlignHCenter)
        self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_3.setObjectName("horizontalLayout_3")
        self.add_b = QtWidgets.QPushButton(self.centralwidget)
        self.add_b.setStyleSheet("background-color: rgb(247, 248, 255);")
        self.add_b.setObjectName("add_b")
        self.horizontalLayout_3.addWidget(self.add_b)
        self.remove_b = QtWidgets.QPushButton(self.centralwidget)
        self.remove_b.setStyleSheet("background-color: rgb(247, 248, 255);")
        self.remove_b.setObjectName("remove_b")
        self.horizontalLayout_3.addWidget(self.remove_b)
        self.gridLayout_2.addLayout(self.horizontalLayout_3, 6, 0, 1, 1)
        self.stats_table = QtWidgets.QTableWidget(self.centralwidget)
        self.stats_table.setObjectName("stats_table")
        self.stats_table.setColumnCount(4)
        self.stats_table.setRowCount(0)
        item = QtWidgets.QTableWidgetItem()
        self.stats_table.setHorizontalHeaderItem(0, item)
        item = QtWidgets.QTableWidgetItem()
        self.stats_table.setHorizontalHeaderItem(1, item)
        item = QtWidgets.QTableWidgetItem()
        self.stats_table.setHorizontalHeaderItem(2, item)
        item = QtWidgets.QTableWidgetItem()
        self.stats_table.setHorizontalHeaderItem(3, item)
        self.gridLayout_2.addWidget(self.stats_table, 7, 1, 1, 1)
        self.title_label = QtWidgets.QLabel(self.centralwidget)
        self.title_label.setStyleSheet("font: 75 16pt \"Calibri\";\n"
                                       "text-decoration: underline;\n"
                                       "color: rgb(0, 85, 127);")
        self.title_label.setObjectName("title_label")
        self.gridLayout_2.addWidget(self.title_label, 0, 0, 1, 2,
                                    QtCore.Qt.AlignHCenter)
        spacerItem2 = QtWidgets.QSpacerItem(40, 20,
                                            QtWidgets.QSizePolicy.Expanding,
                                            QtWidgets.QSizePolicy.Minimum)
        self.gridLayout_2.addItem(spacerItem2, 12, 0, 1, 2)
        spacerItem3 = QtWidgets.QSpacerItem(40, 20,
                                            QtWidgets.QSizePolicy.Expanding,
                                            QtWidgets.QSizePolicy.Minimum)
        self.gridLayout_2.addItem(spacerItem3, 3, 0, 1, 2)
        MainWindow.setCentralWidget(self.centralwidget)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        # Attributes
        self.row = 0
        self.processes_list = []
        self.chart = []
        self.clear_flag = False
        self.comboBox = []

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

        # Buttons Connections
        self.add_b.clicked.connect(lambda: self.add_clicked())
        self.remove_b.clicked.connect(lambda: self.remove_clicked())
        self.simulate_b.clicked.connect(lambda: self.simulate_clicked())
        self.clear_b.clicked.connect(lambda: self.clear_clicked())
        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        item = self.table.horizontalHeaderItem(0)
        item.setText(_translate("MainWindow", "PID"))
        item = self.table.horizontalHeaderItem(1)
        item.setText(_translate("MainWindow", "Color"))
        item = self.table.horizontalHeaderItem(2)
        item.setText(_translate("MainWindow", "Arrival Time"))
        item = self.table.horizontalHeaderItem(3)
        item.setText(_translate("MainWindow", "Burst Time"))
        item = self.table.horizontalHeaderItem(4)
        item.setText(_translate("MainWindow", "Priority"))
        self.label_gantt_chart.setText(_translate("MainWindow", "GANTT Chart"))
        self.label_processes_data.setText(
            _translate("MainWindow", "Processes Data"))
        self.label_avg_waiting_time.setText(
            _translate("MainWindow", "Average Waiting Time:"))
        self.label_avg_turnaround_time.setText(
            _translate("MainWindow", "Average Turnaround Time:"))
        self.label_desired_algorithm.setText(
            _translate("MainWindow", "Desired Scheduling Algorithm"))
        self.algorithm_dropdown.setItemText(
            1, _translate("MainWindow", "First Come, First Served"))
        self.algorithm_dropdown.setItemText(
            2,
            _translate(
                "MainWindow",
                "Shortest Job First                     (Non Preemptive)"))
        self.algorithm_dropdown.setItemText(
            3,
            _translate("MainWindow",
                       "Shortest Job First                     (Preemptive)"))
        self.algorithm_dropdown.setItemText(
            4,
            _translate(
                "MainWindow",
                "Priority                                      (Non Preemptive)"
            ))
        self.algorithm_dropdown.setItemText(
            5,
            _translate(
                "MainWindow",
                "Priority                                      (Preemptive)"))
        self.algorithm_dropdown.setItemText(
            6, _translate("MainWindow", "Round Robin"))
        self.label_time_quantum.setText(
            _translate("MainWindow", "RR Time Quantum"))
        self.simulate_b.setStatusTip(
            _translate("MainWindow",
                       "Simulates CPU Scheduling and View GANTT Chart"))
        self.simulate_b.setText(_translate("MainWindow", "Simulate"))
        self.clear_b.setStatusTip(
            _translate("MainWindow", "Clears Application"))
        self.clear_b.setText(_translate("MainWindow", "Clear"))
        self.label_scheduling_stats.setText(
            _translate("MainWindow", "Scheduling Statistics"))
        self.add_b.setStatusTip(
            _translate("MainWindow", "Adds a Process Entry to the Table"))
        self.add_b.setText(_translate("MainWindow", "Add Process"))
        self.remove_b.setStatusTip(
            _translate("MainWindow", "Removes a Process Entry from the Table"))
        self.remove_b.setText(_translate("MainWindow", "Remove Process"))
        item = self.stats_table.horizontalHeaderItem(0)
        item.setText(_translate("MainWindow", "PID"))
        item = self.stats_table.horizontalHeaderItem(1)
        item.setText(_translate("MainWindow", "Finish Time"))
        item = self.stats_table.horizontalHeaderItem(2)
        item.setText(_translate("MainWindow", "Turnaround Time"))
        item = self.stats_table.horizontalHeaderItem(3)
        item.setText(_translate("MainWindow", "Waiting Time"))
        self.title_label.setText(_translate("MainWindow", "CPU Scheduler"))

    # UI Functionality
    def get_departure_time(self, pid):
        for index in range(len(self.chart) - 1, -1, -1):
            if self.chart[index] == "Idle":
                continue
            elif self.chart[index].pid == pid:
                return index + 1

    def get_arrival_time(self, pid):
        for process in self.processes_list:
            if process.pid == pid:
                return process.arrival_time

    def get_burst_time(self, pid):
        for index in range(len(self.pids)):
            if self.pids[index] == pid:
                return self.burst_times[index]

    def get_turnaround_time(self, pid):
        return self.get_departure_time(pid) - self.get_arrival_time(pid)

    def get_waiting_time(self, pid):
        return self.get_turnaround_time(pid) - self.get_burst_time(pid)

    # Populate Stats Table
    def display_stats(self):

        # Clear Table
        for r in range(self.stats_table.rowCount()):
            self.stats_table.removeRow(0)

        # Average Waiting/Turnaround Time
        total_waiting_time = 0
        total_turnaround_time = 0

        for process_row in range(len(self.processes_list)):
            self.stats_table.insertRow(process_row)
            pid = self.processes_list[process_row].pid
            finish_time = str(self.get_departure_time(pid))
            waiting_time = str(self.get_waiting_time(pid))
            total_waiting_time += int(waiting_time)
            turnaround_time = str(self.get_turnaround_time(pid))
            total_turnaround_time += int(turnaround_time)

            item = QTableWidgetItem(pid)
            item.setTextAlignment(QtCore.Qt.AlignCenter)
            self.stats_table.setItem(process_row, 0, item)

            item = QTableWidgetItem(finish_time)
            item.setTextAlignment(QtCore.Qt.AlignCenter)
            self.stats_table.setItem(process_row, 1, item)

            item = QTableWidgetItem(turnaround_time)
            item.setTextAlignment(QtCore.Qt.AlignCenter)
            self.stats_table.setItem(process_row, 2, item)

            item = QTableWidgetItem(waiting_time)
            item.setTextAlignment(QtCore.Qt.AlignCenter)
            self.stats_table.setItem(process_row, 3, item)

        self.avg_waiting_label.setText(
            str(round(total_waiting_time / len(self.processes_list), 3)))
        self.avg_turnaround_label.setText(
            str(round(total_turnaround_time / len(self.processes_list), 3)))
        self.processes_list = []

    # Draw Gantt Chart
    def draw_chart(self):

        self.clear_flag = True

        # Scene
        pen = QPen(Qt.lightGray)
        red_brush = QBrush(Qt.darkRed, Qt.SolidPattern)
        blue_brush = QBrush(Qt.darkBlue, Qt.SolidPattern)
        pink_brush = QBrush(Qt.darkMagenta, Qt.SolidPattern)
        green_brush = QBrush(Qt.darkGreen, Qt.SolidPattern)
        yellow_brush = QBrush(Qt.darkYellow, Qt.SolidPattern)
        cyan_brush = QBrush(Qt.darkCyan, Qt.SolidPattern)
        grey_brush = QBrush(Qt.darkGray, Qt.SolidPattern)
        black_brush = QBrush(Qt.black, Qt.SolidPattern)
        white_brush = QBrush(Qt.white, Qt.SolidPattern)

        self.scene = QGraphicsScene()

        rect_x = 0
        for process in self.chart:
            if process == "Idle":
                self.scene.addRect(rect_x, -50, 20, 100, pen, white_brush)
            elif process.color == "red":
                self.scene.addRect(rect_x, -50, 20, 100, pen, red_brush)
            elif process.color == "blue":
                self.scene.addRect(rect_x, -50, 20, 100, pen, blue_brush)
            elif process.color == "pink":
                self.scene.addRect(rect_x, -50, 20, 100, pen, pink_brush)
            elif process.color == "green":
                self.scene.addRect(rect_x, -50, 20, 100, pen, green_brush)
            elif process.color == "yellow":
                self.scene.addRect(rect_x, -50, 20, 100, pen, yellow_brush)
            elif process.color == "cyan":
                self.scene.addRect(rect_x, -50, 20, 100, pen, cyan_brush)
            elif process.color == "grey":
                self.scene.addRect(rect_x, -50, 20, 100, pen, grey_brush)
            elif process.color == "black":
                self.scene.addRect(rect_x, -50, 20, 100, pen, black_brush)

            # Time axis labels
            text_item = QtWidgets.QGraphicsTextItem(
                str(int((rect_x + 20) / 20)))
            text_item.setPos(rect_x + 12, 50)
            self.scene.addItem(text_item)

            rect_x += 20

        # Show Scene
        self.chart_view = QGraphicsView(self.scene, self.chart_view)
        self.gridLayout_2.addWidget(self.chart_view, 15, 0, 1, 2)
        #self.chart_view.setGeometry(QtCore.QRect(0, 0, 1000, 700))
        self.chart_view.show()

    # Show Error Message Popup
    def popup(self, title, text):

        msg = QMessageBox()
        msg.setWindowTitle(title)
        msg.setText(text)
        msg.setIcon(QMessageBox.Warning)

        show_msg = msg.exec_()

    # Clear Button is Clicked
    def clear_clicked(self):

        self.stats_table.setRowCount(0)
        self.avg_turnaround_label.clear()
        self.avg_waiting_label.clear()

        if self.clear_flag:
            self.scene.clear()
            self.clear_flag = False

    # Add Button is Clicked
    def add_clicked(self):
        # Add table row
        self.table.insertRow(self.row)

        # Center Alignment
        for col in range(5):
            item = QtWidgets.QTableWidgetItem()
            item.setTextAlignment(QtCore.Qt.AlignCenter)
            self.table.setItem(self.row, col, item)

        # Create Drop-down menu for colors
        self.comboBox.append(QtWidgets.QComboBox())
        self.comboBox[self.row].addItem("")
        self.comboBox[self.row].addItem("black")
        self.comboBox[self.row].addItem("grey")
        self.comboBox[self.row].addItem("blue")
        self.comboBox[self.row].addItem("cyan")
        self.comboBox[self.row].addItem("red")
        self.comboBox[self.row].addItem("pink")
        self.comboBox[self.row].addItem("green")
        self.comboBox[self.row].addItem("yellow")
        self.table.setCellWidget(self.row, 1, self.comboBox[self.row])

        self.row += 1

    # Remove Button is Clicked
    def remove_clicked(self):
        # Remove table row
        if self.row > 0:
            self.row -= 1
            self.table.removeRow(self.row)
            self.comboBox.pop(self.row)

    # Simulate Button is Clicked
    def simulate_clicked(self):

        # Error Checking
        # Check if at least 1 process is provided
        if self.row == 0:
            self.popup("Process Selection",
                       "Please Provide at least one Process.")
            return

        # Check that all mandatory table cells are provided
        # Also checks for data validation
        for row in range(self.table.rowCount()):
            for col in range(4):
                # Check if color cell
                if col == 1:
                    if self.comboBox[row].currentText() != "":
                        continue
                    else:
                        # Error Message
                        self.popup("Invalid Input",
                                   "Please Fill All Essential Table Entries.")
                        return

                # Empty Cells
                elif self.table.item(row, col).text() == "":
                    # Error Message
                    self.popup("Invalid Input",
                               "Please Fill All Essential Table Entries.")
                    return

                # Invalid Input
                elif not self.table.item(row, col).text().isdigit():
                    # Error Message
                    self.popup("Invalid Input",
                               "Table cells only accept numeric values.")
                    return

            if not self.table.item(row,
                                   4).text().isdigit() and self.table.item(
                                       row, 4).text() != "":
                # Error Message
                self.popup("Invalid Input",
                           "Table cells only accept numeric values.")
                return

        # Take data from table
        self.processes_list = []
        for row in range(self.table.rowCount()):
            pid = self.table.item(row, 0).text()
            color = self.comboBox[row].currentText()
            arrival = int(self.table.item(row, 2).text())
            burst = int(self.table.item(row, 3).text())
            if self.table.item(row, 4).text() != "":
                priority = int(self.table.item(row, 4).text())
            else:
                priority = 0
            self.processes_list.append(
                Process(pid, color, arrival, burst, priority))

        # Get the desired algorithm
        selected_algorithm = self.algorithm_dropdown.currentText()

        # Populate one list with pids and another with corresponding burst times
        self.pids = []
        self.burst_times = []
        for process in self.processes_list:
            self.pids.append(process.pid)
            self.burst_times.append(process.burst_time)

        # First Come, First Served
        if selected_algorithm == "First Come, First Served":
            self.chart = CPU_SCHEDULER.first_come_first_served(
                self.processes_list)

        # Shortest Job First (Non)
        elif selected_algorithm == "Shortest Job First                     (Non Preemptive)":
            self.chart = CPU_SCHEDULER.shortest_job_first(self.processes_list,
                                                          preemptive=0)

        # Shortest Job First (Pre)
        elif selected_algorithm == "Shortest Job First                     (Preemptive)":
            self.chart = CPU_SCHEDULER.shortest_job_first(self.processes_list,
                                                          preemptive=1)

        # Priority (Non)
        elif selected_algorithm == "Priority                                      (Non Preemptive)":
            # Priority fields check
            for row in range(self.table.rowCount()):
                if self.table.item(row, 4).text() == "":
                    # Error Message
                    self.popup("Invalid Input", "Please Fill Priority Cells.")
                    return

            self.chart = CPU_SCHEDULER.priority(self.processes_list,
                                                preemptive=0)

        # Priority (Pre)
        elif selected_algorithm == "Priority                                      (Preemptive)":
            # Priority fields check
            for row in range(self.table.rowCount()):
                if self.table.item(row, 4).text() == "":
                    # Error Message
                    self.popup("Invalid Input", "Please Fill Priority Cells.")
                    return

            self.chart = CPU_SCHEDULER.priority(self.processes_list,
                                                preemptive=1)

        # Round Robin
        elif selected_algorithm == "Round Robin":
            if self.tq_in.text() == "":
                self.popup("Time Quantum Selection",
                           "Please Specify the Desired Time Quantum.")
                return
            else:
                self.chart = CPU_SCHEDULER.round_robin(int(self.tq_in.text()),
                                                       self.processes_list)

        # No Algorithm is checked
        else:
            self.popup("Algorithm Selection",
                       "Please Select the Desired Algorithm.")
            return

        self.display_stats()
        self.draw_chart()
Example #26
0
class SchedulerGUI(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent=parent)
        self.setupUi(self)

        self.schedule = sampleSchedule()

        self.activatedColumns = {}

        for key in self.schedule.columns:
            self.activatedColumns[key] = True

        self.lang = 'en'

        self.restore_buttons = []
        self.restoreAllButton.clicked.connect(self.restoreAllColumns)

        self.translateDict = {}
        for widget in self.centralwidget.findChildren((QPushButton, QLabel)):
            langDict = {}

            for l in languages:
                langDict[l] = trans(widget.text(), l)
            key = widget

            self.translateDict[key] = langDict

        self.translateWidgets()

        self.language0Button.clicked.connect(partial(self.changeLang, 'en'))
        self.language1Button.clicked.connect(partial(self.changeLang, 'ru'))
        self.language2Button.clicked.connect(partial(self.changeLang, 'de'))

        self.drawAlarm = QTimer()
        self.drawAlarm.timeout.connect(self.drawAlarmFunc)
        self.drawAlarm.start(0.3)

    def closeEvent(self, event):
        quit()

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

    def drawAlarmFunc(self):
        self.drawAlarm.stop()
        self.draw()

    def draw(self):
        self.scheduleScene = QGraphicsScene()
        self.activatedScene = QGraphicsScene()

        self.w = self.scheduleView.width()
        self.h = Y_SIDE * 24
        self.h_a = self.activatedView.height()

        self.gridPen = QPen(QtCore.Qt.gray)

        for i in range(0, 24):
            self.scheduleScene.addLine(0, i * Y_SIDE, self.w, i * Y_SIDE)

        self.drawTimeTapes()

        cols = self.getActivatedColumns()

        if (len(cols) > 0):
            self.drawColumns(cols)

        self.scheduleView.setScene(self.scheduleScene)
        self.activatedView.setScene(self.activatedScene)

    def drawTimeTapes(self):
        for i in range(0, len(self.schedule.timeTapes)):
            self.scheduleScene.addLine(WIDTH_TL * i, 0, WIDTH_TL * i, self.h)

            self.activatedScene.addLine(WIDTH_TL * i, 0, WIDTH_TL * i,
                                        self.h_a)

            l = QLabel(self.schedule.timeTapes[i].name)
            l.move(WIDTH_TL * i, 0)
            self.activatedScene.addWidget(l)

            for j in range(0, 24):
                l = QLabel(self.schedule.timeTapes[i].labels[j])
                l.move(WIDTH_TL * i, Y_SIDE * j)
                self.scheduleScene.addWidget(l)

    def drawColumns(self, cols):
        x_offset = WIDTH_TL * len(self.schedule.timeTapes)

        act_col_width = (self.w - x_offset) / len(cols)

        self.deactivateButtons = []
        for i in range(0, len(cols)):
            self.scheduleScene.addLine(x_offset + act_col_width * i, 0,
                                       x_offset + act_col_width * i, self.h)
            self.activatedScene.addLine(x_offset + act_col_width * i, 0,
                                        x_offset + act_col_width * i, self.h_a)

            b = QPushButton(cols[i].name[self.lang])
            b.move(x_offset + act_col_width * i, 0)
            b.clicked.connect(partial(self.deactivateColumn, cols[i].abr))
            b.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
            b.resize(act_col_width, self.h_a)
            b = self.activatedScene.addWidget(b)

            for event in cols[i].events:
                self.drawEvent(event, x_offset, act_col_width, i)

    def drawEvent(self, event, x_offset, col_width, x_loc):
        t0_f = timeStrToFloat(event.t0)
        t1_f = timeStrToFloat(event.t1)

        length = (t1_f - t0_f) * (self.h / 24)

        space = QtCore.QSizeF(col_width, length)

        r = QtCore.QRectF(
            QtCore.QPointF(x_offset + x_loc * col_width, t0_f * (self.h / 24)),
            space)

        pen = QtGui.QPen(QtCore.Qt.blue)
        brush = QtGui.QBrush(QtCore.Qt.blue)
        self.scheduleScene.addRect(r, pen, brush)

        font_size = MAX_EVENT_FONT_PT

        l_title = QLabel(event.title[self.lang])
        l_title.move(x_offset + x_loc * col_width, t0_f * (self.h / 24))

        l_title.setFont(
            QtGui.QFont(DEFAULT_EVENT_FONT, font_size, QtGui.QFont.Bold))
        title_width = l_title.fontMetrics().boundingRect(
            l_title.text()).width()
        title_height = l_title.fontMetrics().boundingRect(
            l_title.text()).height()

        while (title_height > length
               or title_width > col_width) and font_size > MIN_EVENT_FONT_PT:
            font_size -= 2

            l_title.setFont(
                QtGui.QFont(DEFAULT_EVENT_FONT, font_size, QtGui.QFont.Bold))
            title_width = l_title.fontMetrics().boundingRect(
                l_title.text()).width()
            title_height = l_title.fontMetrics().boundingRect(
                l_title.text()).height()

            print(font_size, length, title_width, col_width)
        '''
        l_title = QLabel(event.title[self.lang])
        l_title.move(x_offset + x_loc * col_width, t0_f * (self.h/24))
        
        l_time = QLabel(event.t0 + ' - ' + event.t1)
        
        
        if (length > 2 * LABEL_FONT_PT + 2):
            titleFont = QtGui.QFont(LABEL_FONT, LABEL_FONT_PT, 
                                    QtGui.QFont.Bold)
            l_title.setFont(titleFont)
            title_height = l_title.fontMetrics().boundingRect(l_title.text()).height()
            
            timeFont = QtGui.QFont(LABEL_FONT, LABEL_FONT_PT, QtGui.QFont.Bold)
            l_time.move(x_offset + i * act_col_width, t0_f * (self.h/24) + title_height + 1)
            l_time.setFont(timeFont)
        '''

        self.scheduleScene.addWidget(l_title)
        #self.scheduleScene.addWidget(l_time)

    def getActivatedColumns(self):
        cols = []

        for key in self.schedule.columns:
            if self.activatedColumns[key]:
                cols.append(self.schedule.columns[key])

        cols = sorted(cols, key=lambda x: x.abr)
        return cols

    def getDeactivatedColumns(self):
        cols = []

        for key in self.schedule.columns:
            if not self.activatedColumns[key]:
                cols.append(self.schedule.columns[key])

        cols = sorted(cols, key=lambda x: x.abr)
        return cols

    def deactivateColumn(self, key):
        b = QPushButton(RESTORE[self.lang] + ' ' +
                        self.schedule.columns[key].name[self.lang])
        b.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
        self.restoreButtonLayout.insertWidget(-1, b)
        b.clicked.connect(partial(self.activateColumn, key, b))
        self.restore_buttons.append(b)

        self.activatedColumns[key] = False
        self.draw()

    def activateColumn(self, key, b):
        self.activatedColumns[key] = True
        self.draw()
        b.deleteLater()
        self.restore_buttons.remove(b)

    def restoreAllColumns(self):
        for key in self.activatedColumns:
            self.activatedColumns[key] = True
        for b in self.restore_buttons:
            b.deleteLater()
        self.restore_buttons = []
        self.draw()

    def translateWidgets(self):
        for widget in self.centralwidget.findChildren((QPushButton, QLabel)):
            try:
                widget.setText(self.translateDict[widget][self.lang])
            except KeyError:
                langDict = {}

                for l in languages:
                    langDict[l] = trans(widget.text(), l)
                    key = widget

                self.translateDict[key] = langDict

                widget.setText(self.translateDict[widget][self.lang])

    def changeLang(self, lang):
        self.lang = lang
        self.translateWidgets()
        self.drawAlarm.start(1)
Example #27
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())
Example #28
0
class Paint(QGraphicsView):

    def __init__(self):
        QGraphicsView.__init__(self)
        self.setSceneRect(QRectF(self.viewport().rect()))
        self.scene = QGraphicsScene()
        self.paint = False
        self.put_clusters = False
        self.isdelete = False
        self.coords_points = []
        self.coords_clusters = []
        self.clusters = []
        self.points = []
  
    def tools(self, e):
        x = e.x()
        y = e.y()
        if self.paint:
            brush = QBrush(Qt.SolidPattern)
            if self.put_clusters:
                pen = QPen(Qt.blue)
                self.coords_clusters.append([x, y])
                self.clusters.append(self.scene.addEllipse(x, y, 15, 15, pen, brush))
                self.scene.addItem(self.clusters[-1])
                self.setScene(self.scene)
            else:
                pen = QPen(Qt.black)
                self.coords_points.append([x, y])
                self.points.append(self.scene.addEllipse(x, y, 8, 8, pen, brush))
                self.scene.addItem(self.points[-1])
                self.setScene(self.scene)
            
            

        if self.isdelete:
            _ = [self.scene.removeItem(item) for item in self.items()]
            self.isdelete = False

    def mousePressEvent(self, event):
        e = QPointF(self.mapToScene(event.pos()))
        self.tools(e)

    def redraw_points(self, coords_poins):
        colors = {0: Qt.black,
                  1: Qt.green,
                  2: Qt.cyan,
                  3: Qt.yellow,
                  4: Qt.gray,
                  5: Qt.magenta,
                  6: Qt.red,
                  7:Qt.darkYellow}
        set = []
        for i in [list(product([i], set)) for i, set in coords_poins.items()]:
            set.extend(i)
        _ = [self.scene.removeItem(item) for item in self.points]
        self.points.clear()
        self.scene.clearFocus()
        brush = QBrush(Qt.SolidPattern)
        pen = QPen()
        for point in set:
            pen.setColor(colors[point[0] % 8])
            self.points.append(self.scene.addRect(point[1][0], point[1][1], 10, 10, pen, brush))
            self.scene.addItem(self.points[-1])
Example #29
0
class Battlefield(QGraphicsView):
    """The graphical battlefield."""

    click = pyqtSignal(int)
    start = pyqtSignal()
    stop = pyqtSignal()

    def __init__(self, path: str):
        super().__init__()

        self.load_from_file(path)
        self.possible_colors = {"health": 0, "strength": 1, "braveness": 2}
        self.unit_size = 10
        self.scene = QGraphicsScene()
        self.grid_size = 50
        self.colormap = 0
        self.background = QPixmap("gui/fond.png")
        self.zoom_level = 1
        self.selected_unit = 0
        self.edit = False
        self.simu = False

        self.wait = False

        self.mousePressEvent = self.on_mousePressEvent
        self.mouseMoveEvent = self.on_mouseMoveEvent
        self.mouseReleaseEvent = self.on_mouseReleaseEvent

        self.setGeometry(300, 300, self.grid_size * 10, self.grid_size * 10)
        self.setScene(self.scene)
        self.show()
        self.draw()

    def get_specs_tables(self):
        SPECS = [[[], []], [[], []], [[], []]]

        for i in range(self.size):
            speci = [[0, 0], [0, 0], [0, 0], [0, 0]]
            for unit in self.simulation.units(i):
                speci[0][unit.side] += 1
                speci[1][unit.side] += unit.health
                speci[2][unit.side] += unit.strength
                speci[3][unit.side] += unit.braveness

            for j in range(3):
                for k in range(2):
                    SPECS[j][k].append(speci[j + 1][k] / speci[0][k])
        return SPECS

    def load_from_file(self, path: str):
        self.simulation = read_battle(path)
        self._state = 0
        self._size = self.simulation.size

    def update(self, state_step: int):
        """Update the graphics and the grid between two steps."""
        step_validity = 0 <= self._state + state_step < self.simulation.size
        if step_validity:
            self._state += state_step
            self.draw()
        return step_validity

    def go_to_state(self, state):
        """Move animation to given state."""
        if 0 <= state < self.simulation.size:
            self._state = int(state)
            self.draw()

    def zoom(self, precision: float):
        """Zoom in on the picture."""
        self.zoom_level *= precision
        self.resetCachedContent()
        self.draw()

    def get_unit(self, index: int):
        """Access specific unit."""
        return self.simulation.units(self._state)[index]

    @property
    def size(self):
        """Get the size of the simulation."""
        return self._size

    @property
    def state(self):
        """Get the current state."""
        return self._state

    def change_colormap(self, color: str):
        """Change the colormap."""
        if color in self.possible_colors:
            self.colormap = self.possible_colors[color]
            self.draw()

    def unit_position(self, unit):
        """Get screen position of unit."""
        return (unit.coords + 10) * self.unit_size * self.zoom_level

    def on_mousePressEvent(self, event):
        pos = self.mapToScene(event.pos())
        click = np.array((pos.x(), pos.y()))
        for i, unit in enumerate(self.simulation.units(self.state)):
            unit_pos = self.unit_position(unit)
            if np.all(unit_pos <= click) and np.all(
                    click <= unit_pos + self.unit_size):
                self.click.emit(i)
                self.selected_unit = i
                self.draw()
                break
        else:  # no unit found under pointer
            pos = event.pos()
            self.centerOn(pos.x(), pos.y())

    def on_mouseMoveEvent(self, event):
        if self.edit:
            self.draw()
            pos = self.mapToScene(event.pos())
            self.scene.addRect(pos.x(), pos.y(), self.unit_size,
                               self.unit_size, QPen(),
                               QBrush(QColor(0, 255, 0, 125)))
            QTest.qWait(10)

    def on_mouseReleaseEvent(self, event):
        if self.edit:
            pos = self.mapToScene(event.pos())
            new_x = (pos.x() / (self.zoom_level * self.unit_size)) - 10
            new_y = (pos.y() / (self.zoom_level * self.unit_size)) - 10
            self.simulation.units(
                self.state)[self.selected_unit].coords = np.array(
                    [new_x, new_y])
            self.draw()
            if self.simu:
                self.instant_export()

    def change_mod(self):
        self.edit = not (self.edit)

    def change_simu(self):
        self.simu = not (self.simu)

    def gen_color(self, index, unit):
        """Generate a colormap for unit."""
        def specs(unit):
            if not unit.is_centurion:
                return [unit.health, unit.strength, unit.braveness]
            return [0, 0, 0]

        max_val = max(
            [specs(unit)[index] for unit in self.simulation.units(0)])
        shade = 150 * (specs(unit)[index] / max_val) + 105
        color = [0, 0, 0]
        color[2 * unit.side] = shade
        return QColor(*color)

    def draw_unit(self, unit, pen, brush):
        position = self.unit_position(unit)
        if unit.reach >= 5:
            self.scene.addEllipse(*position, *[self.unit_size] * 2, pen, brush)
        else:
            self.scene.addRect(*position, *[self.unit_size] * 2, pen, brush)

    def draw_image(self, image):
        def shape(dim):
            return int(dim * (1 + self.zoom_level))

        self.scene.addPixmap(
            image.scaled(*map(shape, (image.width(), image.height()))))

    def draw(self):
        """Draw the units and background."""
        self.scene.clear()
        self.draw_image(self.background)

        # shuffle so that we also see blue units
        state = self.simulation.units(self.state)
        for unit in state:
            if not unit.is_dead:
                if not unit.is_centurion:
                    color = self.gen_color(self.colormap, unit)
                else:
                    if unit.side == 0:
                        color = QColor(255, 0, 0)
                    else:
                        color = QColor(0, 0, 255)
                self.draw_unit(unit, QPen(), QBrush(color))
        self.draw_unit(state[self.selected_unit], QPen(),
                       QBrush(QColor(0, 255, 0)))

    def export(self, name):
        """To export the current state"""
        if not (self.wait):
            self.wait = True
            self.scene.addRect(
                -10, -10, int(self.background.width() * (1 + self.zoom_level)),
                int(self.background.height() * (1 + self.zoom_level)), QPen(),
                QBrush(QColor(255, 255, 255)))
            loading = QLabel()
            gif_load = QMovie("gui/loading.gif")
            loading.setMovie(gif_load)
            gif_load.start()
            self.scene.addWidget(loading)
            QTest.qWait(200)
            make_battle(self.simulation.state(self.state), name)
            QTest.qWait(200)
            self.draw()
            self.wait = False

    def instant_export(self):
        if not (self.wait):
            self.export("data/new.txt")
            self.load_from_file("data/new.txt")
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)
Example #31
0
    app = QApplication(sys.argv)
    rs = QRectF(0, 0, 100, 100)
    ro = QRectF(-1, -1, 3, 2)
    s = QGraphicsScene(rs)
    v = QGraphicsView(s)
    v.setGeometry(20, 20, 600, 600)
    v._origin_u = True
    v._origin_l = True

    print('screenGeometry():', app.desktop().screenGeometry())
    print('scene rect=', s.sceneRect())

    v.fitInView(rs, Qt.KeepAspectRatio) # Qt.IgnoreAspectRatio Qt.KeepAspectRatioByExpanding Qt.KeepAspectRatio

    s.addRect(rs, pen=QPen(Qt.black, 0, Qt.SolidLine), brush=QBrush(Qt.yellow))
    s.addRect(ro, pen=QPen(Qt.black, 0, Qt.SolidLine), brush=QBrush(Qt.red))

    ruler1 = FWRuler(v, 'L')
    ruler2 = FWRuler(v, 'D')
    ruler3 = FWRuler(v, 'U')
    ruler4 = FWRuler(v, 'R')

    v.setWindowTitle("My window")
    v.setContentsMargins(0,0,0,0)
    v.show()
    app.exec_()

    ruler1.remove()
    ruler2.remove()
    ruler3.remove()
Example #32
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
Example #33
0
class MainWindow(QMainWindow):
    def __init__(self, parent: QWidget=None) -> None:
        super(MainWindow, self).__init__(parent)
        uic.loadUi(os.path.join(getResourcesPath(), 'ui', 'mainwindow.ui'),
                   self)
        self.actionExit.triggered.connect(QApplication.quit)
        self.actionLoad_G_Code.triggered.connect(self.askGCodeFile)
        self.actionPrint.triggered.connect(self.actionPrintSlot)
        self.actionClear.triggered.connect(self.actionClearSlot)
        self.actionZoomIn.triggered.connect(self.zoomIn)
        self.actionZoomOut.triggered.connect(self.zoomOut)
        self.actionResetZoom.triggered.connect(self.resetZoom)
        self.actionSetPenWidth.triggered.connect(self.askPenWidth)
        self.actionShowMovement.toggled.connect(self.actionShowMovementSlot)
        self.checkBoxActionShowMovement = QCheckBox(
            self.actionShowMovement.text(), self.toolBar)
        self.checkBoxActionShowMovement.setChecked(True)
        # noinspection PyUnresolvedReferences
        self.checkBoxActionShowMovement.toggled.connect(
            self.actionShowMovementSlot)
        self.toolBar.insertWidget(self.actionSetMoveLineColor,
                                  self.checkBoxActionShowMovement)
        self.actionSetMoveLineColor.triggered.connect(
            self.actionSetMoveLineColorSlot)

        self.zoomFactor = 1
        self._precision = 1
        self._moveLineColor = Qt.green
        self.material = None
        self.scene = QGraphicsScene()
        self.graphicsView.setScene(self.scene)
        self.graphicsView.scale(1, -1)
        self.graphicsView.setBackgroundBrush(QBrush(Qt.lightGray))
        self.clearScene()
        self.updateStatusBar()

    @property
    def moveLineColor(self) -> QColor:
        return self._moveLineColor

    @moveLineColor.setter
    def moveLineColor(self, new_color: QColor) -> None:
        self._moveLineColor = new_color
        for item in self.scene.items():
            if isinstance(item, QGraphicsMovementLineItem):
                item.color = self.moveLineColor

    @property
    def precision(self) -> number:
        return self._precision

    @precision.setter
    def precision(self, new_precision: number) -> None:
        self._precision = new_precision
        for item in self.scene.items():
            if isinstance(item, PenWidthSettable) and\
                    isinstance(item, QGraphicsItem):
                item.penWidth = self.precision
        self.updateStatusBar()

    def actionPrintSlot(self) -> None:
        printer = QPrinter()
        printer.setPageOrientation(QPageLayout.Landscape)
        if QPrintDialog(printer).exec_():
            painter = QPainter(printer)
            painter.setRenderHint(QPainter.Antialiasing)
            view = QGraphicsView()
            view.setScene(self.scene)
            view.setSceneRect(QRectF(0, 0, 290, 200))
            view.fitInView(QRectF(0, 0, 290, 200), Qt.KeepAspectRatio)
            view.scale(1, -1)
            view.render(painter)
            del painter  # necessary, thanks Qt

    def updateStatusBar(self) -> None:
        # noinspection PyUnresolvedReferences
        self.statusBar.showMessage('Current pen width: %.3f' % self._precision)

    def actionShowMovementSlot(self, toggle: bool) -> None:
        self.checkBoxActionShowMovement.setChecked(toggle)
        self.actionShowMovement.setChecked(toggle)
        for item in self.scene.items():
            if isinstance(item, QGraphicsMovementLineItem):
                item.setVisible(toggle)

    def askPenWidth(self) -> None:
        # noinspection PyCallByClass, PyTypeChecker
        res = QInputDialog.getDouble(self, 'Change pen width',
                                     'Enter new pen width:',
                                     self.precision, -10000, 10000, 3)
        if res[1]:
            self.precision = res[0]

    def actionClearSlot(self) -> None:
        if self.askClearScene():
            self.clearScene()

    def actionSetMoveLineColorSlot(self) -> None:
        # Inspector doesn't understand Qt's static methods
        # noinspection PyCallByClass,PyTypeChecker
        color = QColorDialog.getColor(self.moveLineColor, self,
                                      'Select new move line color')
        if QColor.isValid(color):
            self.moveLineColor = color

    def askClearScene(self) -> bool:
        msgbox = QMessageBox(self)
        msgbox.setText('This will clear the area.')
        msgbox.setInformativeText('Are you sure you want to continue?')
        msgbox.setStandardButtons(
            QMessageBox.Cancel | QMessageBox.Ok)
        msgbox.setDefaultButton(QMessageBox.Cancel)
        ret = msgbox.exec()
        if ret == QMessageBox.Ok:
            return True
        return False

    def clearScene(self) -> None:
        self.scene.clear()
        self.precision = 1
        self.updateStatusBar()
        self.material = self.scene.addRect(QRectF(0, 0, 290, 200))
        self.material.setPen(QPen(Qt.white))
        self.material.setBrush(QBrush(Qt.white))

    def askGCodeFile(self) -> None:
        # noinspection PyCallByClass, PyTypeChecker
        filetuple = QFileDialog.getOpenFileName(self,
                                                'Select G Code file',
                                                getResourcesPath(),
                                                'G Code files (*.gcode);;'
                                                'Text files (*.txt);;'
                                                'All Files (*.*)')
        if filetuple:
            if os.path.isfile(filetuple[0]):
                self.loadGCode(filetuple[0])

    def zoomIn(self) -> None:
        self.graphicsView.scale(1.15, 1.15)
        self.zoomFactor *= 1.15

    def zoomOut(self) -> None:
        self.graphicsView.scale(1.0 / 1.15, 1.0 / 1.15)
        self.zoomFactor /= 1.15

    def resetZoom(self) -> None:
        self.graphicsView.scale(1.0 / self.zoomFactor, 1.0 / self.zoomFactor)
        self.zoomFactor = 1

    def loadGCode(self, filename: str) -> None:
        rawSteps = []
        # a step is tuple of str (command) and dict of arg -> value
        # eg ('G1', {'X': 0})
        with open(filename) as f:
            for index, line in enumerate(f):
                line = line.split(';', 1)[0]
                if not line:
                    continue
                splitted = line.strip().split(' ')
                cmd = splitted[0]
                packedArgs = splitted[1:]
                args = {}
                for arg in packedArgs:
                    args[arg[0]] = arg[1:]
                rawSteps.append((cmd, args))
        for rawStep in rawSteps:
            cmd = rawStep[0]
            args = rawStep[1]
            if cmd == 'G2' or cmd == 'G3':
                try:
                    args['I']
                except KeyError:
                    args['I'] = 0
                try:
                    args['J']
                except KeyError:
                    args['J'] = 0
        self.execGCode(rawSteps)

    def execGCode(self, codes: List[GCode]) -> None:
        relative_mode = False
        prevX = 0
        prevY = 0
        for code in codes:
            cmd = code[0]
            args = code[1]
            if 'X' in args:
                x = float(args['X']) + (prevX if relative_mode else 0)
            else:
                x = prevX
            if 'Y' in args:
                y = float(args['Y']) + (prevY if relative_mode else 0)
            else:
                y = prevY
            if cmd == 'G0':
                line = QGraphicsMovementLineItem(
                    line=QLineF(prevX, prevY, x, y),
                    color=self._moveLineColor,
                    penWidth=self.precision)
                if not self.checkBoxActionShowMovement.isChecked():
                    line.setVisible(False)
                self.scene.addItem(line)
            elif cmd == 'G1':
                self.scene.addItem(
                    QGraphicsColoredLineItem(
                        line=QLineF(prevX, prevY, x, y),
                        penWidth=self.precision))
            elif cmd == 'G2' or cmd == 'G3':
                offsetX = float(args['I'])
                offsetY = float(args['J'])
                if offsetX == 0 and offsetY == 0:
                    # only R given
                    radius = float(args['R'])
                    dx = x - prevX
                    dy = y - prevY
                    dist = math.sqrt(dx ** 2 + dy ** 2)
                    h = math.sqrt((radius ** 2) - ((dist ** 2) / 4))
                    tmpx = dy * h / dist
                    tmpy = -dx * h / dist
                    ccw = (cmd == 'G3')
                    if (ccw and radius > 0) or ((not ccw) and radius < 0):
                        tmpx = -tmpx
                        tmpy = -tmpy
                    middleX = tmpx + (2 * x - dx) / 2
                    middleY = tmpy + (2 * y - dy) / 2
                else:
                    radius = math.sqrt(offsetX ** 2 + offsetY ** 2)
                    middleX = prevX + offsetX
                    middleY = prevY + offsetY
                rectBottomLeftX = middleX - radius
                rectBottomLeftY = middleY - radius
                rectLength = 2 * radius
                alpha = math.degrees(math.atan2(prevY - middleY,
                                                prevX - middleX))
                beta = math.degrees(math.atan2(y - middleY, x - middleX))
                if cmd == 'G2':
                    if beta > alpha:
                        if beta >= 180:
                            beta -= 360
                        else:
                            alpha += 360
                elif cmd == 'G3':
                    if beta < alpha:
                        if alpha > 180:
                            alpha -= 360
                        else:
                            beta += 360
                delta = alpha - beta
                if delta == 0:
                    delta = 360
                ellipse = QGraphicsArcItem(rectBottomLeftX, rectBottomLeftY,
                                           rectLength, rectLength,
                                           penWidth=self.precision)
                ellipse.setStartAngle(-alpha)
                ellipse.setSpanAngle(delta)
                self.scene.addItem(ellipse)
            elif cmd == 'G91':
                relative_mode = True
            elif cmd == 'G90':
                relative_mode = False
            elif cmd == 'G28':
                # reference drive + general init
                relative_mode = False
                x = -0.9
                y = 242.3
            prevX = x
            prevY = y