def __init__(self, pickerView): scene = QGraphicsScene() scene.addText( "QGraphicsItem in QGraphicsView. Press mouse to mock pick, key to open dialog." ) QGraphicsView.__init__(self, scene) # Accept touch on both this widget and viewport (abstract scroll area) # Touch engenders LMB mouse press event since app attribute for that is set. self.setAttribute(Qt.WA_AcceptTouchEvents) self.viewport().setAttribute(Qt.WA_AcceptTouchEvents) self.qmlMaster = QmlMaster() ''' See the QML, created there? " A Person model which is mock-picked" self.model = Person() ''' if pickerView is not None: self.pickerView = pickerView self.pickDelegate = self.qmlMaster.findComponent( self.pickerView, className=model.person.Person, objectName="person") self.dialogDelegate = self.qmlMaster.findComponent( self.pickerView, className=model.qmlDelegate.QmlDelegate, objectName="dialogDelegate") else: self.pickDelegate = None self.dialogDelegate = None
def __init__(self, pickerView): scene = QGraphicsScene() scene.addText( "QGraphicsItem in QGraphicsView. Press mouse to mock pick, key to open dialog." ) QGraphicsView.__init__(self, scene) self.qmlMaster = QmlMaster() ''' See the QML, created there? " A Person model which is mock-picked" self.model = Person() ''' if pickerView is not None: self.pickerView = pickerView self.pickDelegate = self.qmlMaster.findComponent( self.pickerView, className=model.person.Person, objectName="person") self.dialogDelegate = self.qmlMaster.findComponent( self.pickerView, className=model.qmlDelegate.QmlDelegate, objectName="dialogDelegate") else: self.pickDelegate = None self.dialogDelegate = None
def on_imagesTree_currentItemChanged(self, current, previous): """ Private slot to show a preview of the selected image. @param current current image entry (QTreeWidgetItem) @param previous old current entry (QTreeWidgetItem) """ if current is None: return imageUrl = QUrl(current.text(1)) if not imageUrl.host(): imageUrl.setHost(QUrl(self.siteAddressLabel.text()).host()) imageUrl.setScheme(QUrl(self.siteAddressLabel.text()).scheme()) import Helpviewer.HelpWindow cache = Helpviewer.HelpWindow.HelpWindow.networkAccessManager().cache() if cache: cacheData = cache.data(imageUrl) else: cacheData = None pixmap = QPixmap() invalidPixmap = False scene = QGraphicsScene(self.imagePreview) if not cacheData: invalidPixmap = True else: pixmap.loadFromData(cacheData.readAll()) if pixmap.isNull(): invalidPixmap = True if invalidPixmap: scene.addText(self.tr("Preview not available.")) else: scene.addPixmap(pixmap) self.imagePreview.setScene(scene)
def on_imagesTree_currentItemChanged(self, current, previous): """ Private slot to show a preview of the selected image. @param current current image entry (QTreeWidgetItem) @param previous old current entry (QTreeWidgetItem) """ if current is None: return imageUrl = QUrl(current.text(1)) if not imageUrl.host(): imageUrl.setHost(QUrl(self.siteAddressLabel.text()).host()) imageUrl.setScheme(QUrl(self.siteAddressLabel.text()).scheme()) import Helpviewer.HelpWindow cache = Helpviewer.HelpWindow.HelpWindow.networkAccessManager().cache() if cache: cacheData = cache.data(imageUrl) else: cacheData = None pixmap = QPixmap() invalidPixmap = False scene = QGraphicsScene(self.imagePreview) if not cacheData: invalidPixmap = True else: pixmap.loadFromData(cacheData.readAll()) if pixmap.isNull(): invalidPixmap = True if invalidPixmap: scene.addText(self.tr("Preview not available.")) else: scene.addPixmap(pixmap) self.imagePreview.setScene(scene)
def set_signal(self): indx = self.ui.combobox_signals.currentIndex() if indx != 0: self.ui.inpt.setReadOnly(True) else: self.ui.inpt.setReadOnly(False) self.ui.inpt.setText("10010110") self.decoder_update() return signal = self.signals[indx - 1] pa = ProtocolAnalyzer(signal) pa.get_protocol_from_signal() self.ui.inpt.setText("".join(pa.decoded_proto_bits_str)) tmp_scene = QGraphicsScene() tmp_scene.addText(self.tr("Loading Signal...")) QApplication.setOverrideCursor(Qt.WaitCursor) self.ui.graphicsView_signal.setScene(tmp_scene) QApplication.processEvents() if signal is not None: last_message = pa.messages[-1] lookup = { i: msg.bit_sample_pos for i, msg in enumerate(pa.messages) } plot_data = signal.qad[lookup[0][0]:lookup[pa.num_messages - 1][len(last_message) - 1]] self.ui.graphicsView_signal.plot_data(plot_data) self.ui.graphicsView_signal.centerOn(0, 0) QApplication.restoreOverrideCursor()
def __init__(self, pickerView): scene = QGraphicsScene() scene.addText("QGraphicsItem in QGraphicsView. Press mouse to mock pick, key to open dialog.") QGraphicsView.__init__(self, scene) # Accept touch on both this widget and viewport (abstract scroll area) # Touch engenders LMB mouse press event since app attribute for that is set. self.setAttribute(Qt.WA_AcceptTouchEvents) self.viewport().setAttribute(Qt.WA_AcceptTouchEvents) self.qmlMaster = QmlMaster() """ See the QML, created there? " A Person model which is mock-picked" self.model = Person() """ if pickerView is not None: self.pickerView = pickerView self.pickDelegate = self.qmlMaster.findComponent( self.pickerView, className=model.person.Person, objectName="person" ) self.dialogDelegate = self.qmlMaster.findComponent( self.pickerView, className=model.qmlDelegate.QmlDelegate, objectName="dialogDelegate" ) else: self.pickDelegate = None self.dialogDelegate = None
def set_signal(self): indx = self.ui.combobox_signals.currentIndex() if indx != 0: self.ui.inpt.setReadOnly(True) else: self.ui.inpt.setReadOnly(False) self.ui.inpt.setText("10010110") self.decoder_update() return signal = self.signals[indx - 1] pa = ProtocolAnalyzer(signal) pa.get_protocol_from_signal() self.ui.inpt.setText("".join(pa.decoded_proto_bits_str)) tmp_scene = QGraphicsScene() tmp_scene.addText(self.tr("Loading Signal...")) QApplication.instance().setOverrideCursor(Qt.WaitCursor) self.ui.graphicsView_signal.setScene(tmp_scene) if signal is not None: last_message = pa.messages[-1] lookup = {i: msg.bit_sample_pos for i, msg in enumerate(pa.messages)} plot_data = signal.qad[lookup[0][0]:lookup[pa.num_messages - 1][len(last_message) - 1]] self.ui.graphicsView_signal.plot_data(plot_data) self.ui.graphicsView_signal.centerOn(0, 0) QApplication.instance().restoreOverrideCursor()
def initUI(self): # self.setGeometry(400, 200, 1000, 700) # self.setWindowTitle("Circles") scene = QGraphicsScene() scene.addText("Hello, world!") view = QGraphicsView(scene)
def __init__(self, parent=None): super().__init__() scene = QGraphicsScene() scene.addText("Hello, world!") view = QGraphicsView(scene) view.show()
class MainWindow(QGraphicsView): def __init__(self, parent=None): super(MainWindow, self).__init__(parent) #创建场景 self.scene = QGraphicsScene() #在场景中添加文字 self.scene.addText("Hello, world!") #将场景加载到窗口 self.setScene(self.scene)
def __showLoadingText(self): """ Private method to show some text while loading an image. """ self.imagePreview.setBackgroundBrush( self.__imagePreviewStandardBackground) scene = QGraphicsScene(self.imagePreview) scene.addText(self.tr("Loading...")) self.imagePreview.setScene(scene)
def iterator_done(self): view = self.findChild(QGraphicsView, "graphicsView") scene = QGraphicsScene() scene.addText("All data processing complete") view.setScene(scene) h_layout = self.findChild(QHBoxLayout, "horizontalLayout") for i in reversed(range(h_layout.count())): h_layout.itemAt(i).widget().deleteLater() close_button = QPushButton("Close") close_button.clicked.connect(lambda: self.close()) h_layout.addWidget(close_button)
def init_ui(self): scene = QGraphicsScene() scene.setBackgroundBrush(QColor(255, 255, 255)) scene.setItemIndexMethod(QGraphicsScene.BspTreeIndex) scene.setSceneRect(scene.itemsBoundingRect()) self.setDragMode(QGraphicsView.RubberBandDrag) self.setViewportUpdateMode(QGraphicsView.FullViewportUpdate) self.setRenderHints(QPainter.Antialiasing | QPainter.TextAntialiasing) self.frame_item = QGraphicsPixmapItem() scene.addItem(self.frame_item) scene.addText("hello world!") self.setScene(scene)
class Example(QGraphicsView): def __init__(self): super().__init__() self.setGeometry(300, 300, 250, 150) self.setWindowTitle("Simple") self.init() def init(self): self.scene = QGraphicsScene() self.scene.addText("ZetCode") self.setScene(self.scene)
class View(QGraphicsView): def __init__(self, parent=None): QGraphicsView.__init__(self, parent) self.scene = QGraphicsScene(self) self.scene.setBackgroundBrush(Qt.yellow) self.setScene(self.scene) center_rect = QGraphicsRectItem(-10, -10, 20, 20) self.scene.addItem(center_rect) rect = QGraphicsRectItem(0, 0, 100, 100) rect.setPos(-100, -100) self.scene.addItem(rect) rect2 = QGraphicsRectItem(0, 0, 100, 100) self.scene.addItem(rect2) text = self.scene.addText("Hello WOrld") # self.scene.addLine(QLineF(0, 10, -20, -20), QPen(Qt.black)) rect2.moveBy(50, 50) rect2.setRotation(50) rect2.moveBy(-50, -50) print(self.scene.width(), self.scene.height()) self.resize(400, 400)
def __showPixmap(self, pixmap): """ Private method to show a pixmap in the preview pane. @param pixmap pixmap to be shown @type QPixmap """ scene = QGraphicsScene(self.imagePreview) if pixmap.isNull(): self.imagePreview.setBackgroundBrush( self.__imagePreviewStandardBackground) scene.addText(self.tr("Preview not available.")) else: self.imagePreview.setBackgroundBrush(QBrush(self.__tilePixmap)) scene.addPixmap(pixmap) self.imagePreview.setScene(scene)
def __init__(self, parent=None): QGraphicsView.__init__(self, parent) self.setFixedWidth(56) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) # self.setFrameStyle(QFrame.NoFrame) # self.setStyleSheet(""" # QGraphicsView { border: 1px solid black } # """) scene = QGraphicsScene() scene.addSimpleText('nice!!') self.text = scene.addText('hello') scene.addText('world') self.setScene(scene)
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)
class MyGraphicsView(QGraphicsView): zoom_signal = pyqtSignal(bool) def __init__(self, parent=None): super().__init__(parent) self._scene = QGraphicsScene(backgroundBrush=Qt.gray) self._zoom = 0 self.setScene(self._scene) self.setTransformationAnchor(QGraphicsView.NoAnchor) #self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse) self.setResizeAnchor(QGraphicsView.AnchorUnderMouse) self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setBackgroundBrush(QBrush(QColor(30, 30, 30))) self.setFrameShape(QFrame.NoFrame) self.setSizePolicy( QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)) button = MyGraphicsButtonItem() self._scene.addItem(button) text = self._scene.addText('Hello, World!', QFont('Arial', 20)) text.setDefaultTextColor(Qt.white) text.setFlag(QGraphicsItem.ItemIsMovable) # Movable text. self.startPos = None def mousePressEvent(self, event): if event.modifiers() & Qt.ControlModifier and event.button( ) == Qt.LeftButton: self.startPos = event.pos() else: super().mousePressEvent(event) def mouseMoveEvent(self, event): if self.startPos is not None: delta = self.startPos - event.pos() # Get the current transformation (which is a matrix that includes the scaling ratios m11 refers to the horizontal scale, m22 to the vertical scale). transform = self.transform() # Divide the delta by their corresponding ratio. deltaX = delta.x() / transform.m11() deltaY = delta.y() / transform.m22() # Translate the current sceneRect by the delta. self.setSceneRect(self.sceneRect().translated(deltaX, deltaY)) self.startPos = event.pos() else: super().mouseMoveEvent(event) def mouseReleaseEvent(self, event): self.startPos = None super().mouseReleaseEvent(event)
def set_signal(self): indx = self.ui.combobox_signals.currentIndex() if indx != 0: self.ui.inpt.setReadOnly(True) else: self.ui.inpt.setReadOnly(False) self.ui.inpt.setText("10010110") self.decoder_update() return signal = self.signals[indx - 1] pa = ProtocolAnalyzer(signal) pa.get_protocol_from_signal() self.ui.inpt.setText("".join(pa.decoded_proto_bits_str)) tmp_scene = QGraphicsScene() tmp_scene.addText(self.tr("Loading Signal...")) QApplication.setOverrideCursor(Qt.WaitCursor) self.ui.graphicsView_signal.setScene(tmp_scene) QApplication.processEvents() # scene = ZoomableScene() if signal is not None: last_block = pa.blocks[-1] lookup = pa.bit_sample_pos plot_data = signal.qad[lookup[0][0]:lookup[pa.num_blocks - 1][len(last_block) - 1]] self.ui.graphicsView_signal.plot_data(plot_data) # num_samples = len(plot_data) # minimum = -numpy.max(plot_data) # maximum = -numpy.min(plot_data) # scene.setSceneRect(0, minimum, num_samples, maximum - minimum) # scene.setBackgroundBrush(constants.BGCOLOR) # scene.addLine(0, 0, num_samples, 0, constants.AXISCOLOR) # precise_path = path_creator.create_precise_path(plot_data) # for subpath in precise_path: # scene.addPath(subpath, constants.LINECOLOR) # self.ui.graphicsView_signal.setScene(scene) # self.ui.graphicsView_signal.update() # self.ui.graphicsView_signal.scale(1, 1) self.ui.graphicsView_signal.centerOn(0, 0) QApplication.restoreOverrideCursor()
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()
def ItemsInit(self, scene: QGraphicsScene): ic = len(self.Inputs()) oc = len(self.Outputs()) m = max(ic, oc) * 10 self.windowRect.setHeight(m * 2 + 20) ins = self.Inputs() ino = 20 + m - ic * 10 ouo = 20 + m - oc * 10 pix = scene.addPixmap(self.icon) pix.setPos( (self.windowRect.width() - self.icon.width()) * 0.5, 20 + (self.windowRect.height() - 20 - self.icon.height()) * 0.5) pix.setParentItem(self.item) for i in range(0, ic): ti = scene.addText(ins[i]) ti.setPos(0, i * 20 + ino) ti.setParentItem(self.item) ie = scene.addEllipse( QRectF(QPointF(-5, i * 20 + 5 + ino), QSizeF(10, 10))) ie.setParentItem(self.item) ie.setFlag(QGraphicsItem.ItemNegativeZStacksBehindParent) ie.setZValue(-1) ins = self.Outputs() for i in range(0, oc): ti = scene.addText(ins[i]) ti.setPos( QPointF(self.windowRect.width() - ti.boundingRect().width(), i * 20 + ouo)) ti.setParentItem(self.item) ie = scene.addEllipse( QRectF(QPointF(self.windowRect.width() - 5, i * 20 + 5 + ouo), QSizeF(10, 10))) ie.setParentItem(self.item) ie.setFlag(QGraphicsItem.ItemNegativeZStacksBehindParent) ie.setZValue(-1) self.inputs = [] for i in range(0, ic): self.inputs.append(NodeConnector())
def update_pics_with_path(self): self.lineDic.setText(self.FolderPath) self.picsPaths=self.filterImgs(self.picsPaths) widget=QWidget() layout = QGridLayout() widget.setLayout(layout) rows = int((len(self.picsPaths)/3)) if (len(self.picsPaths)%3) > 0: rows+=1 posis = [(j,k) for k in range(3) for j in range(rows)] for pos,picPath,i in zip(posis,self.picsPaths,range(len(self.picsPaths))): #print() picView = QGraphicsView(objectName = "img"+str(i)) picView.setToolTip(self.FolderPath+"/"+picPath) layout.addWidget(picView,*pos) scene = QGraphicsScene() if QPixmap(self.FolderPath+"/"+picPath).isNull() != True: scene.addPixmap(QPixmap(self.FolderPath+"/"+picPath).scaled(140, 140, Qt.KeepAspectRatio)) else: print(picPath) scene.addText("Bild konnte nicht\ngeladen werden",QFont("Times", 10)) picView.setScene(scene) picView.setFixedSize(150,150) layout.setVerticalSpacing(10) self.scroll.setWidget(widget) i = 0 while self.scroll.findChild(QGraphicsView,"img"+str(i)) != None: self.scroll.findChild(QGraphicsView,"img"+str(i)).mouseReleaseEvent=functools.partial(self.buttonReleased,i) i +=1
class Cad2dMainWindow(QMainWindow, Ui_MainWindow): """ Class documentation goes here. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget @type QWidget """ super(Cad2dMainWindow, self).__init__(parent) self.setupUi(self) # 透過繼承 ui_MainWindow 物件, 已經擁有 self.graphicsView 成員物件 self.scene = QGraphicsScene() # 在 scene 中加入繪圖元件 # 字串 ''' self.scene.addText("Hello, world!") # 矩形 self.scene.addRect(QRectF(0, 0, 100, 100)) # 畫直線 self.scene.addItem( QGraphicsLineItem(QLineF(100, 100, 200, 300))) ''' # 將畫面設定在視圖中 self.graphicsView.setScene(self.scene) def mousePressEvent(self, event): self._start = event.pos() self.update() if event.button()==Qt.LeftButton: point=QPointF(event.pos().x(), event.pos().y()) self.scene.addText(str(event.pos().x())+","+str(event.pos().y())).setPos(point) super(Cad2dMainWindow, self).mousePressEvent(event) def mouseReleaseEvent(self, event): print("mouse release event")
def mostrar(self, raiz): scene = QGraphicsScene() elipse = scene.addEllipse(0, 0, 100, 50) elipse.setBrush(QColor(245, 235, 255)) text = scene.addText(raiz.getRaiz()) text1 = scene.addText("RAIZ") self.raiz = Nodo(elipse, [text, text1]) self.conteo = np.zeros(self.controlador.getNAtributos() + 1) self.conteo[0] = 2 if (raiz.getHijos()): self.recurrir(raiz.getHijos(), 0, scene, self.raiz) self.redim(self.raiz, 0, scene) self.unir(self.raiz, scene) self.ui.viewer.setScene(scene) self.ui.viewer.show() self.ui.viewer.verticalScrollBar().setValue(self.ui.viewer.verticalScrollBar().minimum()) self.ui.viewer.horizontalScrollBar().setValue(int(self.ui.viewer.horizontalScrollBar().maximum() / 2))
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())
class MonitorGraphicsView(QGraphicsView, AllowDrop): monitorWin = None SIZE = (50.0, 50.0) FULLSPEED = 512 * 1024 # 512 in kb/s _progressText = None _speedsPolygon = None _speedsPen = None _speedsBrush = None def __init__(self, parent = None): super().__init__(parent) self.monitorWin = parent if self.monitorWin: self.monitorWin.sigTaskUpdating.connect(self.slotTaskUpdate) self.scene = QGraphicsScene(self) self.scene.setSceneRect(0, 0, self.SIZE[0], self.SIZE[1]) self.setScene(self.scene) self._speedsPen = QPen(Qt.white) gradient = QLinearGradient(0, 0, self.SIZE[0], self.SIZE[1]) gradient.setColorAt(0.0, Qt.darkGreen) gradient.setColorAt(1.0, Qt.yellow) self._speedsBrush = QBrush(gradient) # add elements to the scene self._speedsPolygon = self.scene.addPolygon(QPolygonF(), self._speedsPen, self._speedsBrush) self._progressText = self.scene.addText("") self._progressText.setPos(10, 0) self.setupDropSupport() def mousePressEvent(self, qMouseEvent): self.monitorWin.mousePressEvent(qMouseEvent) def mouseMoveEvent(self, qMouseEvent): self.monitorWin.mouseMoveEvent(qMouseEvent) def mouseReleaseEvent(self, qMouseEvent): self.monitorWin.mouseReleaseEvent(qMouseEvent) def _setSpeeds(self, speeds): polygon = QPolygonF() polygon.append(QPointF(0, self.SIZE[1])) # start the polygon nSamples = len(speeds) xPerSample = self.SIZE[0] / nSamples for i, speed in enumerate(speeds): y = self._translateSpeedToPosY(speed) polygon.append(QPointF(xPerSample * i, y)) polygon.append(QPointF(xPerSample * (i+1), y)) polygon.append(QPointF(*self.SIZE)) # close the polygon self._speedsPolygon.setPolygon(polygon) def _setProgress(self, process): # 10000 means 100% if process is None: self._progressText.setPlainText("") else: self._progressText.setPlainText("{:.1f}%".format(process / 100)) def _translateSpeedToPosY(self, speed): return self.SIZE[1] * (1.0 - speed / self.FULLSPEED) @pyqtSlot(dict) def slotTaskUpdate(self, task): if task: self._setProgress(task["progress"]) self._setSpeeds(task["speeds"]) else: self._setProgress(None) self._setSpeeds([0.0])
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
class main_window(QWidget): def __init__(self, parent=None): super().__init__(parent) self.setGeometry(450, 200, 1000, 600) self.setWindowTitle("NRange") self.scene = QGraphicsScene() self.view = QGraphicsView(self.scene) self.interfejs() self.show() def interfejs(self): layout = QHBoxLayout() ### INPUTY PARAMETROW fieldsLayout = QGridLayout() #layout dla prawej części rightHlayout = QVBoxLayout() itemsLayout = QVBoxLayout() # g lowny layout self.Ptx = Parametr("Ptx", 0, 99, 0) self.Gtx = Parametr("Gtx", 0, 99, 0) self.Ftx = Parametr("Ftx", 0, 99, 0) self.Grx = Parametr("Grx", 0, 99, 0) self.Frx = Parametr("Frx", 0, 99, 0) self.SNR = Parametr("SNR", 0, 99, 0) self.bandwitch = Parametr("B", 0, 99, 0) self.Fnoise = Parametr("Fnoise", 0, 99, 0) self.Temp = Parametr("Temp [K]", 0, 999, 0) self.Freq = Parametr("Freq [MHz]", 1, 99999, 1) self.wyborModelu = modelComboBox("Model propagacyjny") fieldsLayout.addItem(self.wyborModelu,0,0) fieldsLayout.addItem(self.Ptx,1,0) fieldsLayout.addItem(self.Gtx,1,1) fieldsLayout.addItem(self.Ftx,1,2) fieldsLayout.addItem(self.Grx,2,0) fieldsLayout.addItem(self.Frx,2,1) fieldsLayout.addItem(self.SNR,2,2) fieldsLayout.addItem(self.bandwitch,3,0) fieldsLayout.addItem(self.Temp,3,1) fieldsLayout.addItem(self.Fnoise,3,2) fieldsLayout.addItem(self.Freq,4,0) fieldsLayout.setSpacing(20) #self.scene = QGraphicsScene() #scene.addText("ddddddddddddddddddddddddddddddddddddddddddddd") #view = QGraphicsView(self.scene) # oblcizanie calculateButton = QPushButton() calculateButton.setText("Oblicz zasięg") calculateButton.clicked.connect(lambda x: self.propagationModel()) fieldsLayout.addWidget(calculateButton, 5, 2) layout.addWidget(self.view) self.view.show() # lewa strona #layout.addWidget(paintContainer) verticalSpacer = QSpacerItem(1, 50, QSizePolicy.Fixed, QSizePolicy.Expanding) fieldsLayout.addItem(verticalSpacer,5,0) fieldsLayout.setRowStretch(0, 1) fieldsLayout.setRowStretch(1, 1) fieldsLayout.setRowStretch(1, 1) itemsLayout.addItem(fieldsLayout) layout.addItem(itemsLayout) # główny layout dzieli obszar na dwie czesci #self.Ptx = self.Ptx.container.text() #self.scene.addText(self.Ptx.container.text()) self.setLayout(layout) def propagationModel(self, name='ddd'): # Lmax = Ptx + Gtx - Ftx + Grx - Frx - S/N - k*T*B - Fnoise - IM Ptx = self.Ptx.returnParameterValues() Gtx = self.Gtx.returnParameterValues() Ftx = self.Ftx.returnParameterValues() Grx = self.Grx.returnParameterValues() Frx = self.Frx.returnParameterValues() SNR = self.SNR.returnParameterValues() bandwitch = self.bandwitch.returnParameterValues() Temp = self.Temp.returnParameterValues() Fnoise = self.Fnoise.returnParameterValues() Freq = self.Freq.returnParameterValues() k = 1.38e-23 Lmax = Ptx + Gtx - Ftx + Grx - Frx - SNR - k * bandwitch * Temp - Fnoise - 2 ### obliczanie zasiegu fdB = 20 * math.log10(Freq) x = Lmax - 32.4 - fdB d = 10**(x/20) if name.lower() == 'wpp': return 0 self.scene.clear() self.scene.addText(str(round(d*1000, 2)))
class panel(QGraphicsView): def __init__(self): super(panel, self).__init__() self.arbolito = None #arbol de entornos self.y = 50 #posicion en y inicial self.escena = QGraphicsScene() #escena de dibujo self.setScene( self.escena) #asignamos la escena al QGraphicsView de la clase # ------------------------------------------------------------------------------------------------- # metodo que verifica cuando se hace click en la escena # ------------------------------------------------------------------------------------------------- def mousePressEvent(self, event): print("clicked") x = event.pos().x() y = event.pos().y() print(x, y) pt = self.mapToScene( event.pos() ) #se escala la posicion de click del QGraphicsView a la escena (QGraphicsScene) root = self.arbolito.get_root() #raiz del arbol if (root != None): rect = QRect( int(pt.x()), int(pt.y()), root.tam, root.tam) # se crea un rectangulo para la colision con el nodo self.__colision(root, rect) # ------------------------------------------------------------------------------------------------- # metodo que verifica si el evento del click se realizo sobre algun nodo # ------------------------------------------------------------------------------------------------- def __colision(self, nodo, rect): #si el nodo entrante fue el clickeado if nodo.rect.intersects(rect): #se muestra un mensaje #con la informacion del nodo-> nombre del procedimiento o funcion msg = QMessageBox() msg.setIcon(QMessageBox.Information) msg.setText("Nombre Ambiente: " + str(nodo.info)) msg.exec_() return True else: #si no se mira si se hizo el click en alguno de los hijos for i in nodo.childrens: self.__colision(i, rect) # ------------------------------------------------------------------------------------------------- # metodo que limpia la escena y llama al metodo de pintado del arbol # ------------------------------------------------------------------------------------------------- def dibujar(self): #self.arbolito.get_root().print_tree() self.escena.clear() self.pintar() # ------------------------------------------------------------------------------------------------- # metodo publico que llama el pintado del arbol y sus lineas desde la razi # ------------------------------------------------------------------------------------------------- def pintar(self): root = self.arbolito.get_root() self.y = 50 self.__pintar_arbol(root, 10, self.y) self.__lineas(root) # ------------------------------------------------------------------------------------------------- # metodo que pinta todos los nodos del arbol # ------------------------------------------------------------------------------------------------- def __pintar_arbol(self, nodo, x, y): pen = QPen(Qt.black) #lapiz de nodo normal pen2 = QPen(Qt.green) #lapiz de nodo actual nodo.x = x #se asigna posicion x al nodo nodo.y = self.y #se asigna posicion y al nodo nodo.rect = QRect( nodo.x, nodo.y, nodo.tam, nodo.tam ) # se crea un rectangulo para el nodo,para los eventos click #print("Pos x : ",nodo.x,"Pos y : ",nodo.y," Dato :",nodo.data," Info : ",nodo.info) xp = nodo.tam / 2 #self.escena.addRect(nodo.rect,pen) if nodo.activo: self.escena.addEllipse(nodo.x, nodo.y, nodo.tam, nodo.tam, pen2) else: self.escena.addEllipse(nodo.x, nodo.y, nodo.tam, nodo.tam, pen) #texto del nodo text = self.escena.addText(str(nodo.data)) text.setPos(QPointF(nodo.x + 2, nodo.y - 3)) x += 50 ##pintar los hijos for i in nodo.childrens: self.y += 40 self.__pintar_arbol(i, x, self.y) # ------------------------------------------------------------------------------------------------- # metodo que pinta las lineas de relacion en el arbol # ------------------------------------------------------------------------------------------------- def __lineas(self, nodo): pen = QPen(Qt.black) xp = nodo.tam / 2 for i in nodo.childrens: xl1_a = nodo.x + nodo.tam + 5 yl1_a = nodo.y + nodo.tam - 5 ylb = i.y + xp self.escena.addLine(nodo.x + nodo.tam, yl1_a, xl1_a, yl1_a) self.escena.addLine(xl1_a, yl1_a, xl1_a, ylb, pen) self.escena.addLine(xl1_a, ylb, i.x, ylb, pen) self.__lineas(i)
class CircuitDiagramView(QGraphicsView): mousePress = pyqtSignal(tuple, tuple, name='mousePress') mouseMove = pyqtSignal(tuple, tuple, name='mouseMove') mouseRelease = pyqtSignal(tuple, tuple, name='mouseRelease') def __init__(self, parent=None): QGraphicsView.__init__(self, parent) self._model = None self.controller = None self.setAcceptDrops(True) # setup & render circuit diagram grid self.scene = QGraphicsScene() self.setScene(self.scene) self._shouldShowSelection = False self._selection = None self._dragging = False self.mousePosition = None self.draggingStart = None self.render() @property def shouldShowSelection(self): return self._shouldShowSelection @shouldShowSelection.setter def shouldShowSelection(self, value): if self.shouldShowSelection is not value and value is not None: self._shouldShowSelection = value self.render() @property def model(self): return self._model @model.setter def model(self, value): self._model = value self.model.modelChanged.connect(self.render) @property def selection(self): return self._selection @selection.setter def selection(self, value): if self.selection is not value: self._selection = value self.render() @property def dragging(self): return self._dragging @dragging.setter def dragging(self, value): self._dragging = value self.render() def componentTypeToImageName(self, componentType): dictionary = { ComponentType.Battery: "assets/battery.png", ComponentType.Resistor: "assets/resistor.png", ComponentType.Voltmeter: "assets/voltmeter.png", ComponentType.Ammeter: "assets/ammeter.png", ComponentType.Switch: "assets/switch-off.png", ComponentType.Bulb: "assets/bulb-off.png", ComponentType.Button: "assets/button-off.png", } return dictionary[componentType] def componentToImage(self, component): if component.type == ComponentType.Wire: image = QPixmap("assets/icon.png").scaled(self.blockSideLength, self.blockSideLength) if component.numberOfConnections() == 1: image = QPixmap("assets/wire-top.png").scaled(self.blockSideLength, self.blockSideLength) if component.connections[Direction.Right] is not None: image = image.transformed(QtGui.QTransform().rotate(90)) elif component.connections[Direction.Bottom] is not None: image = image.transformed(QtGui.QTransform().rotate(180)) elif component.connections[Direction.Left] is not None: image = image.transformed(QtGui.QTransform().rotate(270)) elif component.numberOfConnections() == 2: if component.connections[Direction.Left] is not None and component.connections[Direction.Right] is not None: image = QPixmap("assets/wire-left-right.png").scaled(self.blockSideLength, self.blockSideLength) elif component.connections[Direction.Top] is not None and component.connections[Direction.Bottom] is not None: image = QPixmap("assets/wire-left-right.png").scaled(self.blockSideLength, self.blockSideLength).transformed(QtGui.QTransform().rotate(90)) elif component.connections[Direction.Top] is not None and component.connections[Direction.Right] is not None: image = QPixmap("assets/wire-top-right.png").scaled(self.blockSideLength, self.blockSideLength) elif component.connections[Direction.Top] is not None and component.connections[Direction.Left] is not None: image = QPixmap("assets/wire-top-right.png").scaled(self.blockSideLength, self.blockSideLength).transformed(QtGui.QTransform().rotate(270)) elif component.connections[Direction.Bottom] is not None and component.connections[Direction.Right] is not None: image = QPixmap("assets/wire-top-right.png").scaled(self.blockSideLength, self.blockSideLength).transformed(QtGui.QTransform().rotate(90)) elif component.connections[Direction.Bottom] is not None and component.connections[Direction.Left] is not None: image = QPixmap("assets/wire-top-right.png").scaled(self.blockSideLength, self.blockSideLength).transformed(QtGui.QTransform().rotate(180)) elif component.numberOfConnections() == 3: image = QPixmap("assets/wire-left-top-right.png").scaled(self.blockSideLength, self.blockSideLength) if component.connections[Direction.Left] is None: image = image.transformed(QtGui.QTransform().rotate(90)) elif component.connections[Direction.Top] is None: image = image.transformed(QtGui.QTransform().rotate(180)) elif component.connections[Direction.Right] is None: image = image.transformed(QtGui.QTransform().rotate(270)) return image else: imageName = "assets/wire-right.png" if component.type == ComponentType.Bulb: if component.isOn(): imageName = "assets/bulb-on.png" else: imageName = "assets/bulb-off.png" elif component.type == ComponentType.Switch: if component.closed: imageName = "assets/switch-on.png" else: imageName = "assets/switch-off.png" elif component.type == ComponentType.Button: if component.closed: imageName = "assets/button-on.png" else: imageName = "assets/button-off.png" else: imageName = self.componentTypeToImageName(component.type) return QPixmap(imageName).scaled(self.blockSideLength, self.blockSideLength) def mouseCoordinatesToBlockIndex(self, x, y): if self.model is None or x < self.startingX or y < self.startingY or x > self.startingX + self.model.gridSize * self.blockSideLength or y > self.startingY + self.model.gridSize * self.blockSideLength: return (-1, -1) else: return (int((x - self.startingX) / self.blockSideLength), int((y - self.startingY) / self.blockSideLength)) def blockIndexToCoordinate(self, x, y): return (self.startingX + self.blockSideLength * x, self.startingY + self.blockSideLength * y) def mousePressEvent(self, event): index = self.mouseCoordinatesToBlockIndex(event.x(), event.y()) self.mousePress.emit(index, (event.x(), event.y())) def dragEnterEvent(self, event): event.acceptProposedAction() def dragMoveEvent(self, event): index = self.mouseCoordinatesToBlockIndex(event.pos().x(), event.pos().y()) self.mouseMove.emit(index, (event.pos().x(), event.pos().y())) def dropEvent(self, event): event.acceptProposedAction() index = self.mouseCoordinatesToBlockIndex(event.pos().x(), event.pos().y()) self.mouseRelease.emit(index, (event.pos().x(), event.pos().y())) def mouseMoveEvent(self, event): self.mousePosition = (event.x(), event.y()) if self.dragging: self.render() index = self.mouseCoordinatesToBlockIndex(event.x(), event.y()) self.mouseMove.emit(index, (event.pos().x(), event.pos().y())) def mouseReleaseEvent(self, event): index = self.mouseCoordinatesToBlockIndex(event.x(), event.y()) self.mouseRelease.emit(index, (event.pos().x(), event.pos().y())) def resizeEvent(self, event): self.render() def render(self): if self.model is not None: self.scene.clear() self.renderCircuitDiagramGrid() self.renderComponents() def renderComponents(self): if self.model is not None: for component in self.model.components: pixmap = self.componentToImage(component) pixmapItem = self.scene.addPixmap(pixmap) offset = self.blockIndexToCoordinate(component.position[0],component.position[1]) pixmapItem.setOffset(offset[0],offset[1]) pixmapItem.setTransformationMode(Qt.SmoothTransformation) if component is self.selection: if self.dragging: renderPosition = (self.startingX + self.selection.position[0] * self.blockSideLength + self.mousePosition[0] - self.draggingStart[0], self.startingY + self.selection.position[1] * self.blockSideLength + self.mousePosition[1] - self.draggingStart[1]) pixmapItem.setOffset(renderPosition[0], renderPosition[1]) elif self.shouldShowSelection: pen = QPen(QBrush(QColor(0,0,255,100)), 2, Qt.DashLine) self.scene.addRect(self.startingX + component.position[0] * self.blockSideLength, self.startingY + component.position[1] * self.blockSideLength, self.blockSideLength, self.blockSideLength, pen) if component.type is ComponentType.Ammeter: font = QFont("Arial", self.blockSideLength/3.5) reading = self.scene.addText(str("%.2f" % component.current) + "A", font) offset = self.blockIndexToCoordinate(component.position[0],component.position[1]) reading.setPos(offset[0]+self.blockSideLength/20,offset[1]+self.blockSideLength/4) elif component.type is ComponentType.Voltmeter: font = QFont("Arial", self.blockSideLength/3.5) reading = self.scene.addText(str("%.2f" % component.voltage) + "V", font) offset = self.blockIndexToCoordinate(component.position[0],component.position[1]) reading.setPos(offset[0]+self.blockSideLength/20,offset[1]+self.blockSideLength/4) def renderCircuitDiagramGrid(self): pen = QPen(QBrush(QColor(200,200,200,255)), 1) pen2 = QPen(QBrush(QColor(100,100,100,255)), 3) width = self.width() height = self.height() self.blockSideLength = width / (self.model.gridSize + 2) if width < height else height / (self.model.gridSize + 2) # draw vertical lines currentX = width / 2 self.startingX = currentX - (self.model.gridSize / 2) * self.blockSideLength while currentX - self.blockSideLength >= 0: currentX -= self.blockSideLength while currentX < width: self.scene.addLine(currentX, 1, currentX, height - 1, pen) currentX += self.blockSideLength # draw horizontal lines currentY = height / 2 self.startingY = currentY - (self.model.gridSize / 2) * self.blockSideLength while currentY - self.blockSideLength >= 0: currentY -= self.blockSideLength while currentY < height: self.scene.addLine(1, currentY, width - 1, currentY, pen) currentY += self.blockSideLength self.scene.addLine(self.startingX, self.startingY, self.startingX + self.model.gridSize * self.blockSideLength, self.startingY, pen2) self.scene.addLine(self.startingX, self.startingY + self.model.gridSize * self.blockSideLength, self.startingX + self.model.gridSize * self.blockSideLength, self.startingY + 10 * self.blockSideLength, pen2) self.scene.addLine(self.startingX, self.startingY, self.startingX, self.startingY + self.model.gridSize * self.blockSideLength, pen2) self.scene.addLine(self.startingX + self.model.gridSize * self.blockSideLength, self.startingY, self.startingX + self.model.gridSize * self.blockSideLength, self.startingY + 10 * self.blockSideLength, pen2)
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_()
class RecordsetWindow(QWidget): dataDisplayRequest = pyqtSignal(str, int) dataUpdateRequest = pyqtSignal(str, Base) def __init__(self, manager, recordset: list, parent=None): super().__init__(parent=parent) self.UI = Ui_frmRecordsets() self.UI.setupUi(self) # Internal lists self.sensors = {} # List of sensors objects self.sensors_items = {} # List of QAction corresponding to each sensors self.sensors_graphs = {} # List of graph corresponding to each sensor graph self.sensors_location = [] # List of sensors location in this recordset self.sensors_blocks = {} # Sensor blocks - each block of data for each sensor # Variables self.time_pixmap = False # Flag used to check if we need to repaint the timeline or not self.zoom_level = 1 # Current timeview zoom level # Manually created UI objects self.time_bar = QGraphicsLineItem() # Currently selected timestamp bar self.selection_rec = QGraphicsRectItem() # Section rectangle self.sensors_menu = QMenu(self.UI.btnNewGraph) self.UI.btnNewGraph.setMenu(self.sensors_menu) # Data access informations self.dbMan = manager self.recordsets = recordset # Init temporal browser self.timeScene = QGraphicsScene() self.UI.graphTimeline.setScene(self.timeScene) self.UI.graphTimeline.fitInView(self.timeScene.sceneRect()) self.UI.graphTimeline.time_clicked.connect(self.timeview_clicked) self.UI.graphTimeline.time_selected.connect(self.timeview_selected) self.UI.scrollTimeline.valueChanged.connect(self.timeview_scroll) # Init temporal sensor list self.timeSensorsScene = QGraphicsScene() self.UI.graphSensorsTimeline.setScene(self.timeSensorsScene) self.UI.graphSensorsTimeline.fitInView(self.timeSensorsScene.sceneRect(), Qt.KeepAspectRatio) # Update general informations about recordsets self.update_recordset_infos() # Load sensors for that recordset self.load_sensors() # Connect signals to slots self.UI.btnClearSelection.clicked.connect(self.on_timeview_clear_selection_requested) self.UI.btnTimeZoomSelection.clicked.connect(self.on_timeview_zoom_selection_requested) self.UI.btnZoomReset.clicked.connect(self.on_timeview_zoom_reset_requested) self.UI.btnDisplayTimeline.clicked.connect(self.on_timeview_show_hide_requested) self.UI.btnTileHorizontal.clicked.connect(self.tile_graphs_horizontally) self.UI.btnTileVertical.clicked.connect(self.tile_graphs_vertically) self.UI.btnTileAuto.clicked.connect(self.tile_graphs_auto) self.sensors_menu.triggered.connect(self.sensor_graph_selected) # Initial UI state self.UI.btnZoomReset.setEnabled(False) self.UI.btnTimeZoomSelection.setEnabled(False) self.UI.btnClearSelection.setEnabled(False) self.update_tile_buttons_state() def paintEvent(self, paint_event): if not self.time_pixmap: self.refresh_timeview() self.time_pixmap = True def resizeEvent(self, resize_event): if self.time_pixmap: self.refresh_timeview() def refresh_timeview(self): QGuiApplication.setOverrideCursor(Qt.BusyCursor) # Computes required timescene size min_width = self.UI.graphTimeline.width() - 5 if len(self.recordsets) > 0: num_days = (self.get_recordset_end_day_date() - self.get_recordset_start_day_date()).days # Minimum size for days if num_days * 75 > min_width: min_width = num_days * 75 - 5 # Resize timeScene correctly self.timeScene.clear() self.timeScene.setSceneRect(self.timeScene.itemsBoundingRect()) self.timeScene.addLine(0, 80, min_width, 80, QPen(Qt.transparent)) # Set background color back_brush = QBrush(Qt.lightGray) self.timeScene.setBackgroundBrush(back_brush) self.timeSensorsScene.setBackgroundBrush(back_brush) # Update display self.draw_dates() self.draw_sensors_names() self.draw_recordsets() self.draw_sensors() self.draw_grid() self.draw_timebar() # Adjust splitter sizes self.adjust_timeview_size() # self.UI.frmSensors.hide() QGuiApplication.restoreOverrideCursor() def adjust_timeview_size(self): self.UI.frameScrollSpacer.setFixedWidth(self.UI.graphTimeline.pos().x()) if self.timeScene.itemsBoundingRect().width() * self.zoom_level > self.UI.graphTimeline.width(): self.UI.scrollTimeline.setVisible(True) # self.UI.scrollTimeline.setMinimum(self.UI.graphTimeline.width()/2) self.UI.scrollTimeline.setMinimum(0) self.UI.scrollTimeline.setMaximum(self.timeScene.itemsBoundingRect().width() * self.zoom_level) self.UI.scrollTimeline.setPageStep(self.UI.graphTimeline.width()/2) self.UI.scrollTimeline.setSingleStep(self.UI.graphTimeline.width()/5) else: self.UI.scrollTimeline.setVisible(False) def load_sensors(self): # self.UI.lstSensors.clear() self.sensors = {} self.sensors_items = {} self.sensors_location = [] self.sensors_menu.clear() if len(self.recordsets) > 0: for recordset in self.recordsets: for sensor in self.dbMan.get_sensors(recordset): if sensor.location not in self.sensors_location: self.sensors_location.append(sensor.location) self.sensors_menu.addSection(sensor.location) if sensor.id_sensor not in self.sensors: self.sensors[sensor.id_sensor] = sensor sensor_item = QAction(sensor.name) sensor_item.setCheckable(True) sensor_item.setProperty("sensor_id", sensor.id_sensor) self.sensors_items[sensor.id_sensor] = sensor_item self.sensors_menu.addAction(sensor_item) # Create sensors blocks for display self.load_sensors_blocks() else: self.UI.btnNewGraph.setEnabled(False) def update_recordset_infos(self): if len(self.recordsets) == 0: self.UI.lblTotalValue.setText("Aucune donnée.") self.UI.lblDurationValue.setText("Aucune donnée.") return start_time = self.recordsets[0].start_timestamp end_time = self.recordsets[len(self.recordsets) - 1].end_timestamp # Coverage self.UI.lblTotalValue.setText(start_time.strftime('%d-%m-%Y %H:%M:%S') + " @ " + end_time.strftime( '%d-%m-%Y %H:%M:%S')) # Duration # TODO: format better self.UI.lblDurationValue.setText(str(end_time - start_time)) self.UI.lblCursorTime.setText(start_time.strftime('%d-%m-%Y %H:%M:%S')) def get_recordset_start_day_date(self): if len(self.recordsets) == 0: return None start_time = self.recordsets[0].start_timestamp start_time = (datetime(start_time.year, start_time.month, start_time.day, 0, 0, 0)) return start_time def get_recordset_end_day_date(self): if len(self.recordsets) == 0: return None end_time = self.recordsets[len(self.recordsets) - 1].end_timestamp end_time = (datetime(end_time.year, end_time.month, end_time.day, 0, 0, 0) + timedelta(days=1)) return end_time def get_relative_timeview_pos(self, current_time): # start_time = self.recordsets[0].start_timestamp.timestamp() start_time = self.get_recordset_start_day_date().timestamp() # end_time = self.recordsets[len(self.recordsets) - 1].end_timestamp.timestamp() end_time = self.get_recordset_end_day_date().timestamp() time_span = (end_time - start_time) # Total number of seconds in recordsets # if type(current_time) is datetime: if isinstance(current_time, datetime): current_time = current_time.timestamp() if time_span > 0: # return ((current_time - start_time) / time_span) * self.UI.graphTimeline.width() return ((current_time - start_time) / time_span) * self.timeScene.width() else: return 0 def get_time_from_timeview_pos(self, pos): if len(self.recordsets) == 0: return None; start_time = self.get_recordset_start_day_date().timestamp() end_time = self.get_recordset_end_day_date().timestamp() current_time = (pos / self.timeScene.width()) * (end_time - start_time) + start_time current_time = datetime.fromtimestamp(current_time) return current_time def draw_dates(self): if len(self.recordsets) == 0: return # Computations start_time = self.recordsets[0].start_timestamp end_time = self.recordsets[len(self.recordsets) - 1].end_timestamp # time_span = (end_time - start_time).total_seconds() # Total number of seconds in recordsets current_time = (datetime(start_time.year, start_time.month, start_time.day, 0, 0, 0) + timedelta(days=1)) # Drawing tools black_pen = QPen(Qt.black) blue_brush = QBrush(Qt.darkBlue) # Date background self.timeScene.addRect(0, 0, self.timeScene.width(), 20, black_pen, blue_brush) self.timeSensorsScene.addRect(0, 0, self.timeSensorsScene.width(), 20, black_pen, blue_brush) # First date date_text = self.timeScene.addText(start_time.strftime("%d-%m-%Y")) date_text.setPos(0, 0) # -5 date_text.setDefaultTextColor(Qt.white) date_text.setFlag(QGraphicsItem.ItemIgnoresTransformations, True) # Date separators while current_time <= end_time: pos = self.get_relative_timeview_pos(current_time) date_text = self.timeScene.addText(current_time.strftime("%d-%m-%Y")) date_text.setPos(pos, 0) # -5 date_text.setDefaultTextColor(Qt.white) date_text.setFlag(QGraphicsItem.ItemIgnoresTransformations, True) current_time += timedelta(days=1) # self.UI.graphTimeline.fitInView(self.timeScene.sceneRect(), Qt.KeepAspectRatio) def draw_grid(self): if len(self.recordsets) == 0: return # Computations start_time = self.recordsets[0].start_timestamp end_time = self.recordsets[len(self.recordsets) - 1].end_timestamp # time_span = (end_time - start_time).total_seconds() # Total number of seconds in recordsets current_time = (datetime(start_time.year, start_time.month, start_time.day, 0, 0, 0) + timedelta(days=1)) vgrid_pen = QPen(Qt.gray) hgrid_pen = QPen(Qt.black) vgrid_pen.setCosmetic(True) # Horizontal lines pos = 20 # last_location = "" sensor_location_brush = QBrush(Qt.black) sensor_location_pen = QPen(Qt.transparent) for location in self.sensors_location: # Must create a new location line self.timeScene.addRect(0, pos, self.timeScene.width() - 1, 15, sensor_location_pen, sensor_location_brush) pos += 15 sensors = self.get_sensors_for_location(location) for _ in sensors: self.timeScene.addLine(0, pos, self.timeScene.width() - 1, pos, hgrid_pen) self.timeSensorsScene.addLine(0, pos, self.timeSensorsScene.width(), pos, hgrid_pen) pos += 20 # Final line self.timeScene.addLine(0, pos, self.timeScene.width() - 1, pos, hgrid_pen) self.timeSensorsScene.addLine(0, pos, self.timeSensorsScene.width() - 1, pos, hgrid_pen) # Date separators self.timeScene.addLine(0, 0, 0, self.timeScene.height(), vgrid_pen) # Other dates while current_time <= end_time: pos = self.get_relative_timeview_pos(current_time) self.timeScene.addLine(pos, 0, pos, self.timeScene.height(), vgrid_pen) current_time += timedelta(days=1) def draw_recordsets(self): recordset_brush = QBrush(QColor(212, 247, 192)) # Green recordset_pen = QPen(Qt.transparent) # Recording length for record in self.recordsets: start_pos = self.get_relative_timeview_pos(record.start_timestamp) end_pos = self.get_relative_timeview_pos(record.end_timestamp) span = end_pos - start_pos # print (str(span)) self.timeScene.addRect(start_pos, 21, span, self.timeSensorsScene.height()-21, recordset_pen, recordset_brush) # self.UI.graphTimeline.update() return def draw_sensors_names(self): if len(self.sensors) == 0: return sensor_location_brush = QBrush(Qt.black) sensor_location_pen = QPen(Qt.transparent) # Sensor names pos = 20 for location in self.sensors_location: # Must create a new location space for later pos += 15 sensors = self.get_sensors_for_location(location) for sensor_id in sensors: sensor = self.sensors[sensor_id] # Sensor names label = self.timeSensorsScene.addText(sensor.name) label.setPos(0, pos) label.setDefaultTextColor(Qt.black) # label.setFont(QFont("Times", 10, QFont.Bold)) pos += 20 # Adjust size appropriately self.timeSensorsScene.setSceneRect(self.timeSensorsScene.itemsBoundingRect()) self.UI.graphSensorsTimeline.setMaximumWidth(self.timeSensorsScene.itemsBoundingRect().width()) # Sensor location background pos = 20 for location in self.sensors_location: # Must create a new location line self.timeSensorsScene.addRect(0, pos, self.timeSensorsScene.width(), 15, sensor_location_pen, sensor_location_brush) label = self.timeSensorsScene.addText(location) label.setPos(0, pos) label.setDefaultTextColor(Qt.white) label.setFont(QFont("Times", 7)) pos += 15 sensors = self.get_sensors_for_location(location) for sensor_id in sensors: pos += 20 def draw_sensors(self): if len(self.sensors) == 0: return sensor_brush = QBrush(Qt.darkGreen) sensor_pen = QPen(Qt.transparent) sensors_rects = self.create_sensors_rects() for _, rect in enumerate(sensors_rects): self.timeScene.addRect(rect, sensor_pen, sensor_brush) # Adjust size appropriately self.timeSensorsScene.setSceneRect(self.timeSensorsScene.itemsBoundingRect()) self.UI.graphSensorsTimeline.setMaximumWidth(self.timeSensorsScene.itemsBoundingRect().width()) # self.UI.graphSensorsTimeline.setMaximumHeight(self.timeSensorsScene.itemsBoundingRect().height()) def load_sensors_blocks(self): # Create request tasks tasks = [] for location in self.sensors_location: sensors = self.get_sensors_for_location(location) for sensor_id in sensors: for record in self.recordsets: tasks.append(DBSensorTimesTask(title="Chargement des données temporelles", db_manager=self.dbMan, sensor_id=sensor_id, recordset=record)) QGuiApplication.setOverrideCursor(Qt.BusyCursor) process = BackgroundProcess(tasks) dialog = ProgressDialog(process, "Chargement") process.start() dialog.exec() QGuiApplication.restoreOverrideCursor() # Combine tasks results self.sensors_blocks = {} for task in tasks: for result in task.results: if result['sensor_id'] not in self.sensors_blocks: self.sensors_blocks[result['sensor_id']] = [] start_time = result['start_time'] end_time = result['end_time'] data = {"start_time": start_time, "end_time": end_time} self.sensors_blocks[result['sensor_id']].append(data) def create_sensors_rects(self): rects = [] pos = 20 for location in self.sensors_location: # Must create a new location space for later pos += 15 sensors = self.get_sensors_for_location(location) for sensor_id in sensors: # sensor = self.sensors[sensor_id] # for record in self.recordsets: # datas = self.dbMan.get_all_sensor_data(sensor=sensor, recordset=record, channel=sensor.channels[0]) # for data in datas: # start_pos = self.get_relative_timeview_pos(data.timestamps.start_timestamp) # end_pos = self.get_relative_timeview_pos(data.timestamps.end_timestamp) # span = max(end_pos - start_pos, 1) # rects.append(QRectF(start_pos, pos + 3, span, 14)) if sensor_id in self.sensors_blocks: for block in self.sensors_blocks[sensor_id]: start_pos = self.get_relative_timeview_pos(block['start_time']) end_pos = self.get_relative_timeview_pos(block['end_time']) span = max(end_pos - start_pos, 1) rects.append(QRectF(start_pos, pos + 3, span, 14)) pos += 20 return rects def draw_timebar(self): line_pen = QPen(Qt.cyan) line_pen.setWidth(2) self.time_bar = self.timeScene.addLine(1, 21, 1, self.timeScene.height()-1, line_pen) # self.time_bar = self.timeScene.addLine(0, 1, 0, self.timeScene.height() - 1, line_pen) self.time_bar.setFlag(QGraphicsItem.ItemIgnoresTransformations, True) def get_sensors_for_location(self, location): sensors_id = [] for sensor in self.sensors.values(): if sensor.location == location: sensors_id.append(sensor.id_sensor) return sensors_id @staticmethod def get_sensor_graph_type(sensor): if sensor.id_sensor_type == SensorType.ACCELEROMETER \ or sensor.id_sensor_type == SensorType.GYROMETER \ or sensor.id_sensor_type == SensorType.BATTERY \ or sensor.id_sensor_type == SensorType.LUX \ or sensor.id_sensor_type == SensorType.CURRENT \ or sensor.id_sensor_type == SensorType.BAROMETER \ or sensor.id_sensor_type == SensorType.MAGNETOMETER \ or sensor.id_sensor_type == SensorType.TEMPERATURE \ or sensor.id_sensor_type == SensorType.HEARTRATE \ or sensor.id_sensor_type == SensorType.ORIENTATION \ or sensor.id_sensor_type == SensorType.FSR: return GraphType.LINECHART if sensor.id_sensor_type == SensorType.GPS: return GraphType.MAP return GraphType.UNKNOWN @pyqtSlot(Sensor, datetime, datetime) def query_sensor_data(self, sensor: Sensor, start_time: datetime, end_time: datetime): timeseries = self.get_sensor_data(sensor, start_time, end_time)[0] if self.sensors_graphs[sensor.id_sensor]: graph_type = self.get_sensor_graph_type(sensor) graph_window = self.sensors_graphs[sensor.id_sensor] if graph_type == GraphType.LINECHART: series_id = 0 for series in timeseries: # Filter times that don't fit in the range y_range = series['y'] x_range = series['x'] y_range = y_range[x_range >= start_time.timestamp()] x_range = x_range[x_range >= start_time.timestamp()] y_range = y_range[x_range <= end_time.timestamp()] x_range = x_range[x_range <= end_time.timestamp()] if len(x_range)>0 and len(y_range)>0: graph_window.graph.update_data(x_range, y_range, series_id) series_id += 1 return @pyqtSlot(QAction) # @timing def sensor_graph_selected(self, sensor_item): sensor_id = sensor_item.property("sensor_id") sensor = self.sensors[sensor_id] sensor_label = sensor.name + " (" + sensor.location + ")" if sensor_item.isChecked(): # Choose the correct display for each sensor graph_window = None timeseries, channel_data = self.get_sensor_data(sensor) # Fetch all sensor data # Color map for curves colors = [Qt.blue, Qt.green, Qt.yellow, Qt.red] graph_type = self.get_sensor_graph_type(sensor) graph_window = GraphWindow(graph_type, sensor, self.UI.mdiArea) graph_window.setStyleSheet(self.styleSheet() + graph_window.styleSheet()) if graph_type == GraphType.LINECHART: # Add series for series in timeseries: graph_window.graph.add_data(series['x'], series['y'], color=colors.pop(), legend_text=series['label']) graph_window.graph.set_title(sensor_label) if graph_type == GraphType.MAP: for data in channel_data: gps = GPSGeodetic() gps.from_bytes(data.data) if gps.latitude != 0 and gps.longitude != 0: graph_window.graph.addPosition(data.timestamps.start_timestamp, gps.latitude / 1e7, gps.longitude / 1e7) graph_window.setCursorPositionFromTime(data.timestamps.start_timestamp) if graph_window is not None: self.UI.mdiArea.addSubWindow(graph_window).setWindowTitle(sensor_label) self.sensors_graphs[sensor.id_sensor] = graph_window # self.UI.displayContents.layout().insertWidget(0,graph) graph_window.show() QApplication.instance().processEvents() graph_window.aboutToClose.connect(self.graph_was_closed) graph_window.requestData.connect(self.query_sensor_data) graph_window.graph.cursorMoved.connect(self.graph_cursor_changed) graph_window.graph.selectedAreaChanged.connect(self.graph_selected_area_changed) graph_window.graph.clearedSelectionArea.connect(self.on_timeview_clear_selection_requested) graph_window.zoomAreaRequested.connect(self.graph_zoom_area) graph_window.zoomResetRequested.connect(self.graph_zoom_reset) self.UI.mdiArea.tileSubWindows() else: # Remove from display try: if self.sensors_graphs[sensor.id_sensor] is not None: self.UI.mdiArea.removeSubWindow(self.sensors_graphs[sensor.id_sensor].parent()) self.sensors_graphs[sensor.id_sensor].hide() del self.sensors_graphs[sensor.id_sensor] self.UI.mdiArea.tileSubWindows() except KeyError: pass self.update_tile_buttons_state() # @timing def get_sensor_data(self, sensor, start_time=None, end_time=None): QGuiApplication.setOverrideCursor(Qt.BusyCursor) task = DBSensorAllDataTask("Chargement des données...", self.dbMan, sensor, start_time, end_time, self.recordsets) process = BackgroundProcess([task]) dialog = ProgressDialog(process, "Traitement") process.start() dialog.exec() QGuiApplication.restoreOverrideCursor() return task.results['timeseries'], task.results['channel_data'] def update_tile_buttons_state(self): if self.sensors_graphs.keys().__len__() > 1: self.UI.btnTileAuto.setEnabled(True) self.UI.btnTileHorizontal.setEnabled(True) self.UI.btnTileVertical.setEnabled(True) else: self.UI.btnTileAuto.setEnabled(False) self.UI.btnTileHorizontal.setEnabled(False) self.UI.btnTileVertical.setEnabled(False) @pyqtSlot(QObject) def graph_was_closed(self, graph): for sensor_id, sensor_graph in self.sensors_graphs.items(): if sensor_graph == graph: # self.sensors_graphs[sensor_id] = None del self.sensors_graphs[sensor_id] self.sensors_items[sensor_id].setChecked(False) break self.UI.mdiArea.tileSubWindows() self.update_tile_buttons_state() @pyqtSlot(float) def graph_cursor_changed(self, timestamp): current_time = timestamp / 1000 for graph in self.sensors_graphs.values(): if graph is not None: graph.setCursorPositionFromTime(current_time, False) pos = self.get_relative_timeview_pos(current_time) self.time_bar.setPos(pos,0) # Ensure time bar is visible if scrollable self.ensure_time_bar_visible(pos) self.UI.lblCursorTime.setText(datetime.fromtimestamp(current_time).strftime('%d-%m-%Y %H:%M:%S')) def ensure_time_bar_visible(self, pos): if self.UI.scrollTimeline.isVisible(): max_visible_x = self.UI.graphTimeline.mapToScene(self.UI.graphTimeline.rect()).boundingRect().x() \ + self.UI.graphTimeline.mapToScene(self.UI.graphTimeline.rect()).boundingRect().width() min_visible_x = self.UI.graphTimeline.mapToScene(self.UI.graphTimeline.rect()).boundingRect().x() if pos < min_visible_x or pos > max_visible_x: self.UI.scrollTimeline.setValue(pos) @pyqtSlot(datetime, datetime) def graph_zoom_area(self, start_time, end_time): for graph in self.sensors_graphs.values(): if graph is not None: graph.zoomAreaRequestTime(start_time, end_time) @pyqtSlot() def graph_zoom_reset(self): for graph in self.sensors_graphs.values(): if graph is not None: graph.zoomResetRequest(False) @pyqtSlot(float, float) def graph_selected_area_changed(self, start_timestamp, end_timestamp): # Update timeview selection area start_pos = self.get_relative_timeview_pos(start_timestamp / 1000) end_pos = self.get_relative_timeview_pos(end_timestamp / 1000) self.timeview_selected(start_pos, end_pos) # Ensure time bar is visible if scrollable self.ensure_time_bar_visible(start_pos) # Update selection for each graph for graph in self.sensors_graphs.values(): if graph is not None: graph.setSelectionAreaFromTime(start_timestamp, end_timestamp) @pyqtSlot(int) def timeview_scroll(self, pos): self.UI.graphTimeline.centerOn(pos / self.zoom_level, 0) @pyqtSlot(float) def timeview_clicked(self, x): self.time_bar.setPos(x, 0) if len(self.recordsets)==0: return # Find time corresponding to that position timestamp = self.get_time_from_timeview_pos(x) self.UI.lblCursorTime.setText(timestamp.strftime('%d-%m-%Y %H:%M:%S')) for graph in self.sensors_graphs.values(): if graph is not None: # try: graph.setCursorPositionFromTime(timestamp, False) # except AttributeError: # continue @pyqtSlot(float, float) def timeview_selected(self, start_x, end_x): selection_brush = QBrush(QColor(153, 204, 255, 128)) selection_pen = QPen(Qt.transparent) self.timeScene.removeItem(self.selection_rec) self.selection_rec = self.timeScene.addRect(start_x, 20, end_x-start_x, self.timeScene.height()-20, selection_pen, selection_brush) self.UI.btnClearSelection.setEnabled(True) self.UI.btnTimeZoomSelection.setEnabled(True) # Update selection for each graph for graph in self.sensors_graphs.values(): if graph is not None: graph.setSelectionAreaFromTime(self.get_time_from_timeview_pos(start_x), self.get_time_from_timeview_pos(end_x)) @pyqtSlot() def on_timeview_clear_selection_requested(self): self.timeScene.removeItem(self.selection_rec) self.UI.btnClearSelection.setEnabled(False) self.UI.btnTimeZoomSelection.setEnabled(False) # Clear all selected areas in graphs for graph in self.sensors_graphs.values(): graph.clearSelectionArea() @pyqtSlot() def on_timeview_zoom_selection_requested(self): self.UI.graphTimeline.scale(1 / self.zoom_level, 1) # zoom_value = (self.timeScene.width() / (self.selection_rec.rect().width())) zoom_value = (self.UI.graphTimeline.width() / (self.selection_rec.rect().width())) self.zoom_level = zoom_value self.UI.graphTimeline.scale(zoom_value, 1) self.UI.btnZoomReset.setEnabled(True) self.adjust_timeview_size() # self.UI.graphTimeline.ensureVisible(self.selection_rec.rect(), 0, 0) # self.UI.graphTimeline.centerOn(self.selection_rec.rect().x() + self.selection_rec.rect().width() / 2, 0) self.UI.scrollTimeline.setValue((self.selection_rec.rect().x() + self.selection_rec.rect().width() / 2) * self.zoom_level) self.on_timeview_clear_selection_requested() @pyqtSlot() def on_timeview_zoom_reset_requested(self): self.UI.graphTimeline.scale(1 / self.zoom_level, 1) self.zoom_level = 1 self.UI.btnZoomReset.setEnabled(False) self.adjust_timeview_size() self.UI.scrollTimeline.setValue(0) @pyqtSlot() def on_timeview_show_hide_requested(self): visible = not self.UI.frameTimeline.isVisible() self.UI.frameTimeline.setVisible(visible) self.UI.frameTimelineControls.setVisible(visible) # self.UI.lblCursorTime.setVisible(visible) @pyqtSlot() def on_process_recordset(self): # Display Process Window window = ProcessSelectWindow(self.dbMan, self.recordsets) window.setStyleSheet(self.styleSheet()) if window.exec() == QDialog.Accepted: self.dataUpdateRequest.emit("result", window.processed_data) self.dataDisplayRequest.emit("result", window.processed_data.id_processed_data) @pyqtSlot() def tile_graphs_horizontally(self): self.tile_graphs(True) @pyqtSlot() def tile_graphs_vertically(self): self.tile_graphs(False) def tile_graphs(self, horizontal: bool): if self.UI.mdiArea.subWindowList() is None: return position = QPoint(0, 0) for window in self.UI.mdiArea.subWindowList(): if horizontal: rect = QRect(0, 0, self.UI.mdiArea.width() / len(self.UI.mdiArea.subWindowList()), self.UI.mdiArea.height()) else: rect = QRect(0, 0, self.UI.mdiArea.width(), self.UI.mdiArea.height() / len(self.UI.mdiArea.subWindowList())) window.setGeometry(rect) window.move(position) if horizontal: position.setX(position.x() + window.width()) else: position.setY(position.y() + window.height()) @pyqtSlot() def tile_graphs_auto(self): self.UI.mdiArea.tileSubWindows()
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
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
class Airspeed_Tape(QGraphicsView): def __init__(self, parent=None): super(Airspeed_Tape, self).__init__(parent) self.setStyleSheet("border: 0px") self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setRenderHint(QPainter.Antialiasing) self.setFocusPolicy(Qt.NoFocus) self._airspeed = 0 def resizeEvent(self, event): # V Speeds Vs = 45 Vs0 = 40 Vno = 125 Vne = 140 Va = 120 Vfe = 70 w = self.width() h = self.height() self.pph = 10 f = QFont() f.setPixelSize(20) fontMetrics = QFontMetricsF(f) speed_pixel = 1500 + h dialPen = QPen(QColor(Qt.white)) dialPen.setWidth(2) vnePen = QPen(QColor(Qt.red)) vneBrush = QBrush(QColor(Qt.red)) vnePen.setWidth(8) vsoPen = QPen(QColor(Qt.white)) vsoPen.setWidth(8) vnoPen = QPen(QColor(Qt.green)) vnoPen.setWidth(8) yellowPen = QPen(QColor(Qt.yellow)) yellowPen.setWidth(8) self.scene = QGraphicsScene(0, 0, w, speed_pixel) self.scene.addRect(0, 0, w, speed_pixel, QPen(QColor(Qt.black)), QBrush(QColor(Qt.black))) for i in range(150, -1, -5): if i % 10 == 0: self.scene.addLine(0, (-i * 10) + 1500 + h / 2, w / 2, (-i * 10) + 1500 + h / 2, dialPen) t = self.scene.addText(str(i)) t.setFont(f) self.scene.setFont(f) t.setDefaultTextColor(QColor(Qt.white)) t.setX(w - t.boundingRect().width()) t.setY(((-i * 10) + 1500 + h / 2) - t.boundingRect().height() / 2) else: self.scene.addLine(0, (-i * 10) + 1500 + h / 2, w / 2 - 20, (-i * 10) + 1500 + h / 2, dialPen) #Add Markings self.scene.addLine(4, Vs0 * -self.pph + 1500 + self.height() / 2 - 4, 4, Vfe * -self.pph + 1500 + self.height() / 2 + 4, vsoPen) self.scene.addLine(4, Vfe * -self.pph + 1500 + self.height() / 2 - 4, 4, Vno * -self.pph + 1500 + self.height() / 2 + 4, vnoPen) self.scene.addLine(4, Vne * -self.pph + 1500 + self.height() / 2 - 4, 4, Vno * -self.pph + 1500 + self.height() / 2 + 4, yellowPen) self.scene.addLine(4, Vne * -self.pph + 1500 + self.height() / 2 - 4, 4, 150 * -self.pph + 1500 + self.height() / 2 + 4, vnePen) self.setScene(self.scene) def redraw(self): self.resetTransform() self.centerOn(self.scene.width() / 2, -self._airspeed * self.pph + 1500 + self.height() / 2) def getAirspeed(self): return self._airspeed def setAirspeed(self, airspeed): print(airspeed) if airspeed != self._airspeed: self._airspeed = airspeed self.redraw() airspeed = property(getAirspeed, setAirspeed)