def __init__(self, graphWidget, name=None): super(Node, self).__init__() self.graph = graphWidget self.edgeList = [] self.newPos = QPointF() self.name = name self.state = State.TRANSITION self.nodesToUpdate = [] font = QFont() font.setBold(True) font.setPointSize(self._draw_size * 0.2) self.name_tag = QLabel(self.name) self.name_tag.setGeometry(-self._draw_size * (0.55 + len(name) * 0.07), -self._draw_size * 0.9, self._draw_size, self._draw_size * 0.5) self.name_tag.setAttribute(Qt.WA_TranslucentBackground) self.name_tag.setFont(font) QGraphicsProxyWidget(self).setWidget(self.name_tag) font.setBold(False) self.condition_tag = QLabel("") self.condition_tag.setGeometry(-self._draw_size * 0.55, -self._draw_size * 0.55, self._draw_size, self._draw_size * 0.5) self.condition_tag.setAttribute(Qt.WA_TranslucentBackground) self.condition_tag.setFont(font) QGraphicsProxyWidget(self).setWidget(self.condition_tag) self.setFlag(QGraphicsItem.ItemIsMovable) self.setFlag(QGraphicsItem.ItemSendsGeometryChanges) self.setCacheMode(QGraphicsItem.DeviceCoordinateCache) self.setZValue(1)
def show_select_area_at_default_position(self): trimming_data = Project.latest_trimming_data() if trimming_data.position: self.start_position = QPoint(trimming_data.position[0], trimming_data.position[1]) rect = QRectF(trimming_data.position[0], trimming_data.position[1], self.width, self.height) else: self.start_position = QPoint((self.w - self.width) // 2, (self.h - self.height) // 2) rect = QRectF((self.w - self.width) // 2, (self.h - self.height) // 2, self.width, self.height) self.select_area = QGraphicsRectItem(rect) self.select_area.setZValue(1) pen = QPen(QColor('#ffa00e')) pen.setWidth(4) pen.setJoinStyle(Qt.RoundJoin) self.select_area.setPen(pen) self.select_area.setFlag(QGraphicsItem.ItemIsMovable, True) self.original_image_scene.addItem(self.select_area) self.select_area_label_proxy = QGraphicsProxyWidget(self.select_area) self.select_area_label = SelectAreaLabel() self.select_area_label.set_label() self.select_area_label_proxy.setWidget(self.select_area_label) self.select_area_label_proxy.setPos( self.select_area.boundingRect().left() + 2, self.select_area.boundingRect().bottom() - self.select_area_label.height() - 2)
def __init__(self, link: Link, parent=None): super().__init__(link, parent) print("creating test link") self.name = "Outcome" self._widget_proxy = QGraphicsProxyWidget(self) self._widget = QTestLinkProxy() print("proxy widget created") self.name_edit = QLabelEdit(self._widget) self.name_edit.setCallback(self.set_name) self.name_edit.setText(self.name) self.name_edit.setFixedWidth(80) self.name_edit.setAlignment(Qt.AlignCenter) self.name_edit.setFont(QFont("Arial", 10)) print("name edit initialized") _start = self.get_start() _end = self.get_end() _center = [(_start[0] + _end[0]) * 0.5, (_start[1] + _end[1]) * 0.5] _size = [80, 25] print("center position found") self._widget.setGeometry(_center[0] - _size[0] * 0.5, _center[1] - _size[1] * 0.5, _size[0], _size[1]) print("name edit geometry set") self._widget_proxy.setWidget(self._widget) print("widget set to proxy")
def __init__(self, x, y, place): QGraphicsProxyWidget.__init__(self) self.setPos(x, y) self.place = place list = QListWidget() list.setGeometry(x, y, 100, 100) list.addItem(self.FIRST) list.addItem(self.SECOND) list.addItem(self.THIRD) self.setWidget(list)
def _InitContent(self, nodeContent: Optional[JNodeContent]): # nodeContent = None if nodeContent is not None: self._graphicsNodeContent = QGraphicsProxyWidget(self) nodeContent.setGeometry( int(self._nodeEdgeSize), int(self._nodeTitleHeight + self._nodeEdgeSize), int(self._nodeWidth - 2 * self._nodeEdgeSize), int(self._nodeHeight - 2 * self._nodeEdgeSize - self._nodeTitleHeight), ) self._graphicsNodeContent.setWidget(nodeContent)
class HighScoreDisplayer(QGraphicsObject): def __init__(self, parent=None): super().__init__(parent=parent) self.size = 25 self.icon_size = 25 self.board_size = 250 self.box_pen = QPen() self.box_pen.setColor(Qt.white) self.pen_width = 3 self.box_pen.setWidth(self.pen_width) self.widget_proxy = QGraphicsProxyWidget(parent=self) self.scoreboard_widget = scb.HighScoreBoard(self.board_size, self.board_size) self.widget_proxy.setWidget(self.scoreboard_widget) self.widget_proxy.setPos(-self.board_size, -self.board_size) self.scoreboard_widget.setVisible(False) self.setAcceptHoverEvents(True) self.selected = False def set_disabled(self, state): self.setAcceptHoverEvents(not state) def show_board(self, state): self.scoreboard_widget.setVisible(state) self.scoreboard_widget.show_scores(state) self.prepareGeometryChange() if state: self.size = self.board_size else: self.size = self.icon_size def boundingRect(self): return QRectF(-self.size, -self.size, self.size, self.size) def paint(self, painter, style, widget=None): painter.setPen(self.box_pen) painter.drawRect(self.boundingRect()) if not self.selected: painter.fillRect(-self.icon_size / 4, -self.icon_size / 4, -self.icon_size / 2, -self.icon_size / 2, Qt.white) def hoverEnterEvent(self, ev): self.show_board(True) def hoverLeaveEvent(self, ev): self.show_board(False)
def addStreamTable(self, pos=QPointF(0, 0), table=None): """ build stream table at pos with table, if table is not passed, builds a blank table """ self.streamTable = table if table else streamTable(self.labelItems, canvas=self) self.streamTableRect = moveRect() self.streamTableRect.setFlags(moveRect.ItemIsMovable | moveRect.ItemIsSelectable) self.streamTableProxy = QGraphicsProxyWidget(self.streamTableRect) self.streamTableProxy.setWidget(self.streamTable) self.painter.addItem(self.streamTableRect) self.streamTableRect.setPos(pos)
def __init__(self, index): super().__init__() self._index = index ## Box of the year self.box = Box(self) ## Progress bar appearing in upper part box <PyQt5.QtWidgets.QProgressBar> self.progress_bar = QProgressBar() self.progress_bar.setTextVisible(False) self.progress_bar.setMinimum(0) self.progress_bar.setMaximum(100) ## Progress bar proxy <PyQt5.QtWidgets.QGraphicsProxyWidget> self.proxy = QGraphicsProxyWidget(self) self.proxy.setWidget(self.progress_bar) self.proxy.setGeometry( QRectF(self.boundingRect().topLeft(), self.boundingRect().topRight() + QPointF(0, 30))) self.progress_bar.setVisible(False) self.setAcceptedMouseButtons(Qt.LeftButton) self.setFlag(QGraphicsItem.ItemIsMovable) self.setFlag(QGraphicsItem.ItemSendsGeometryChanges) self.setFlag(QGraphicsItem.ItemIsSelectable) self.setCursor(Qt.ArrowCursor) ## Help action <PyQt5.QtWidgets.QAction> self.help_action = QAction( QWidget().style().standardIcon(QStyle.SP_MessageBoxQuestion), 'Help', None) self.dashed_pen = QPen(Qt.black, 1, Qt.DashLine) ## Node label <str> self.label = '' ## Node category <str> self.category = '' ## Node state (among NOT_CONFIGURED, READY, SUCCESS, FAIL) self.state = Node.NOT_CONFIGURED ## Node message <str> self.message = '' ## Input and Output Ports list <[Port]> self.ports = [] ## Links set <set(Link)> self.links = set()
def __init__(self, name, login, pos, color, password, mainWindow, id): super().__init__() self._width = 270.0 self._height = 157.0 self._color = color self._pos = pos self._name = name self._login = login self._password = password self._mainWindow = mainWindow self._id = id self.widget = ServiceCardWidget(name, login, self._color, parent=self) self.proxyWidget = QGraphicsProxyWidget(self) self.proxyWidget.setWidget(self.widget) self.anim = QPropertyAnimation(self.proxyWidget, b'geometry')
def __init__(self): super().__init__(":/images/dashboard.png") self.magatamas = [ QPixmap(":/images/magatamas/{id}.png".format(id=i)) for i in range(5) ] sort_type = QComboBox() sort_type.addItem(self.tr("No sort")) sort_type.addItem(self.tr("Sort by suit")) sort_type.addItem(self.tr("Sort by type")) sort_type.move(0, 32) sort_widget = QGraphicsProxyWidget(self) sort_widget.setWidget(sort_type) sort_type.currentIndexChanged.connect(self.sortCards) self.cards = list() self.general = General() self.avatar = None
def set_digits(self): """ Draw side number tiles """ for i in range(0, 12): if i <= self.board_size - 1: xpos = Cons.RACK_XTILE[0] ypos = Cons.RACK_YTILE + i * 55 + (12 - self.board_size) * 55 // 2 box = QLabel() box.setGeometry(xpos, ypos, Cons.TILE_WIDTH, Cons.TILE_HEIGHT) box.setStyleSheet("border: 2px solid black") box.setAlignment(Qt.AlignCenter) proxy = QGraphicsProxyWidget() proxy.persistent = False proxy.setWidget(box) proxy.digit = Cons.DIGITS[i] proxy.setPos(xpos, ypos) self.scene.addItem(proxy) proxy.show() tile = Tile(self.digits[i], self.scene) tile.cell = "new" tile.draw_tile(QPoint(xpos, ypos))
def __init__(self, parent=None): super().__init__(parent=parent) self.size = 25 self.icon_size = 25 self.board_size = 250 self.box_pen = QPen() self.box_pen.setColor(Qt.white) self.pen_width = 3 self.box_pen.setWidth(self.pen_width) self.widget_proxy = QGraphicsProxyWidget(parent=self) self.scoreboard_widget = scb.HighScoreBoard(self.board_size, self.board_size) self.widget_proxy.setWidget(self.scoreboard_widget) self.widget_proxy.setPos(-self.board_size, -self.board_size) self.scoreboard_widget.setVisible(False) self.setAcceptHoverEvents(True) self.selected = False
def keyPressEvent(self, ev): if ev.key() == Qt.Key_Shift: self._shift = True if (ev.key() == Qt.Key_Enter or ev.key() == Qt.Key_Return) and self._shift: x = PFSUndoSetText(self._activity, self._item.toPlainText(), self.scene()) x.setText("Mover") self.scene()._net.undoStack.push(x) self._activity.setSelected(False) self._scene.inserted.emit() self._scene.removeItem(self) return if ev.key() == Qt.Key_Escape: self._scene.inserted.emit() self._scene.removeItem(self) return QGraphicsProxyWidget.keyPressEvent(self, ev) r = self._item.fontMetrics().size(Qt.TextExpandTabs, self._item.toPlainText()) self._item.setMinimumSize(r.width() + 20, r.height() + 20) self._item.resize(r.width() + 20, r.height() + 20)
def __init__(self, aProductionProcess, aToolkitTypes): super().__init__() self.process = aProductionProcess self.col = 0 self.row = 0 self.inputs = [] self.outputs = [] icon = QGraphicsPixmapItem(aToolkitTypes.GetTypePixmap(self.process.scheme.schemeId, 32), self) icon.setPos(2, 2) width = 250 space = 40 inputOffset = 40 outputOffset = 40 for inp in self.process.inputs: inputOffset = inputOffset + space self.inputs.append(InputGraphic(inp, self, QPointF(0, inputOffset), aToolkitTypes)) for out in self.process.outputs: outputOffset = outputOffset + space self.outputs.append(OutputGraphic(out, self, QPointF(width, outputOffset), aToolkitTypes)) self.rect = QRectF(0, 0, width, max(outputOffset, inputOffset) + space) spinbox = QSpinBox() spinbox.setRange(0, 1000000) spinbox.setValue(self.process.runs) spinbox.valueChanged.connect(self.OnRunChanged) proxy = QGraphicsProxyWidget(self) proxy.setWidget(spinbox) proxy.setPos(QPointF(width / 2 - spinbox.width() / 2, 40)) self.runs = proxy self.spinbox = spinbox
def __init__(self, node_ref: node.Node, parent: QWidget = None): """Inits the components needed for the Node graphic.""" super().__init__(parent) self.node: node.Node = node_ref self.content: node_content_widget.NodeContentWidget = self.node.content self._title: str = self.node.title # flag variables self.hovered: bool = False self._was_moved: bool = False self._last_selected_state: bool = False # settings self.width: int = 180 self.height: int = 240 self.edge_roundness: float = 10.0 self.edge_padding: float = 20.0 self.title_height: float = 24.0 self.title_horizontal_padding: float = 4.0 self.title_vertical_padding: float = 4.0 # create components self.__set_colors() self.__set_title_item() # content self.graphics_content: QGraphicsProxyWidget = QGraphicsProxyWidget( self) self.content.setGeometry( self.edge_padding, self.title_height + self.edge_padding, self.width - 2 * self.edge_padding, self.height - 2 * self.edge_padding - self.title_height) self.graphics_content.setWidget(self.content) # set object flags self.setFlag(QGraphicsItem.ItemIsSelectable) self.setFlag(QGraphicsItem.ItemIsMovable) self.setAcceptHoverEvents(True)
class JGraphicNode(QGraphicsItem): def __init__( self, parent: Optional[QGraphicsItem] = None, nodeId: str = "", title: str = "Base Node", nodeContent: Optional[JNodeContent] = None, ) -> None: super().__init__(parent=parent) self._nodeId: str = nodeId self._nodeTitle: str = title self._nodeContent: Optional[JNodeContent] = nodeContent self._nodeSocketManager: JNodeSocketManager = JNodeSocketManager( self, self._nodeId ) self._nodeTitleText: QGraphicsTextItem = QGraphicsTextItem(self) self.initUI() self._InitContent(nodeContent) @property def nodeTitle(self): return self._nodeTitle @property def nodeWidth(self): return self._nodeWidth @property def nodeHeight(self): return self._nodeHeight @nodeTitle.setter def nodeTitle(self, value: str) -> None: self._nodeTitle = value self._nodeTitleText.setPlainText(value) @property def nodeId(self): return self._nodeId @property def socketManager(self) -> JNodeSocketManager: return self._nodeSocketManager def initUI(self): self.setZValue(1) self.setFlag(QGraphicsItem.ItemIsSelectable, True) self.setFlag(QGraphicsItem.ItemIsMovable, True) self.setFlag(QGraphicsItem.ItemIsFocusable, True) # * node dimension self._nodeWidth: int = JCONSTANTS.GRNODE.NODE_WIDHT self._nodeHeight: int = JCONSTANTS.GRNODE.NODE_HEIGHT self._nodeEdgeSize: float = JCONSTANTS.GRNODE.NODE_PADDING self._nodePenDefault: QtGui.QPen = QtGui.QPen( QtGui.QColor(JCONSTANTS.GRNODE.COLOR_DEFAULT) ) self._nodePenSelected: QtGui.QPen = QtGui.QPen( QtGui.QColor(JCONSTANTS.GRNODE.COLOR_SELECTED) ) self._nodeBrushBackground: QtGui.QBrush = QtGui.QBrush( QtGui.QColor(JCONSTANTS.GRNODE.COLOR_BACKGROUND) ) # * title self._nodeTitleColor = QtCore.Qt.black self._nodeTitleFont: QtGui.QFont = QtGui.QFont( JCONSTANTS.GRNODE.TITLE_FONT, JCONSTANTS.GRNODE.TITLE_FONT_SIZE ) self._nodeTitleFont.setItalic(True) self._nodeTitleFont.setBold(True) self._nodeTitlePadding: int = JCONSTANTS.GRNODE.TITLE_PADDING self._nodeTitleHeight: float = JCONSTANTS.GRNODE.TITLE_HEIGHT self._nodeTitleBrush: QtGui.QBrush = QtGui.QBrush( QtGui.QColor(JCONSTANTS.GRNODE.COLOR_TITLE) ) self._nodeTitleText.setDefaultTextColor(self._nodeTitleColor) self._nodeTitleText.setFont(self._nodeTitleFont) self._nodeTitleText.setPos(3 * self._nodeTitlePadding, 0) self._nodeTitleText.setTextWidth(self._nodeWidth - 2 * self._nodeTitlePadding) self._nodeTitleText.setPlainText(self._nodeTitle) def boundingRect(self) -> QtCore.QRectF: return QtCore.QRectF( 0, 0, self._nodeWidth, self._nodeHeight, ) def paint( self, painter: QtGui.QPainter, option: QStyleOptionGraphicsItem, widget: Optional[QWidget], ) -> None: # * title titlePath = QtGui.QPainterPath() titlePath.setFillRule(QtCore.Qt.WindingFill) titlePath.addRoundedRect( 0, 0, self._nodeWidth, self._nodeTitleHeight, self._nodeEdgeSize, self._nodeEdgeSize, ) titlePath.addRect( 0, self._nodeTitleHeight - self._nodeEdgeSize, self._nodeEdgeSize, self._nodeEdgeSize, ) titlePath.addRect( self._nodeWidth - self._nodeEdgeSize, self._nodeTitleHeight - self._nodeEdgeSize, self._nodeEdgeSize, self._nodeEdgeSize, ) painter.setPen(QtCore.Qt.NoPen) painter.setBrush(self._nodeTitleBrush) painter.drawPath(titlePath.simplified()) # ? content ContentPath = QtGui.QPainterPath() ContentPath.setFillRule(QtCore.Qt.WindingFill) ContentPath.addRoundedRect( 0, self._nodeTitleHeight, self._nodeWidth, self._nodeHeight - self._nodeTitleHeight, self._nodeEdgeSize, self._nodeEdgeSize, ) ContentPath.addRect( 0, self._nodeTitleHeight, self._nodeEdgeSize, self._nodeEdgeSize ) ContentPath.addRect( self._nodeWidth - self._nodeEdgeSize, self._nodeTitleHeight, self._nodeEdgeSize, self._nodeEdgeSize, ) painter.setPen(QtCore.Qt.NoPen) painter.setBrush(self._nodeBrushBackground) painter.drawPath(ContentPath.simplified()) # ? outline outline = QtGui.QPainterPath() outline.addRoundedRect( 0, 0, self._nodeWidth, self._nodeHeight, self._nodeEdgeSize, self._nodeEdgeSize, ) painter.setPen( self._nodePenDefault if not self.isSelected() else self._nodePenSelected ) painter.setBrush(QtCore.Qt.NoBrush) painter.drawPath(outline.simplified()) def _InitContent(self, nodeContent: Optional[JNodeContent]): # nodeContent = None if nodeContent is not None: self._graphicsNodeContent = QGraphicsProxyWidget(self) nodeContent.setGeometry( int(self._nodeEdgeSize), int(self._nodeTitleHeight + self._nodeEdgeSize), int(self._nodeWidth - 2 * self._nodeEdgeSize), int(self._nodeHeight - 2 * self._nodeEdgeSize - self._nodeTitleHeight), ) self._graphicsNodeContent.setWidget(nodeContent) def Serialize(self) -> OrderedDict: node = OrderedDict( { "nodeId": self._nodeId, "posX": self.pos().x(), "posY": self.pos().y(), } ) node.update(self._nodeSocketManager.Serialize()) return node @classmethod def Deserialize(cls, data: Dict): instance = cls(nodeId=data["nodeId"]) instance.setPos(QtCore.QPointF(data["posX"], data["posY"])) for _, socket in data["socketInfo"].items(): instance.socketManager.AddSocket( socket["socketId"], socket["socketType"], socket["multiConnection"] ) return instance
class canvas(CustomView): """ Defines the work area for a single sheet. Contains a QGraphicScene along with necessary properties for context menu and dialogs. """ def __init__(self, parent=None, size='A0', ppi='72', parentMdiArea=None, parentFileWindow=None, landscape=True): super(canvas, self).__init__(parent=parent) #Store values for the canvas dimensions for ease of access, these are here just to be # manipulated by the setters and getters self._ppi = ppi self._canvasSize = size self._landscape = landscape self.streamTable = None #Create area for the graphic items to be placed, this is just here right now for the future # when we will draw items on this, this might be changed if QGraphicScene is subclassed. #set layout and background color self.painter = CustomScene() self.painter.labelAdded.connect(self.updateStreamTable) self.painter.setBackgroundBrush(QBrush( Qt.white)) #set white background self.setScene(self.painter) #set initial paper size for the scene self.painter.setSceneRect(0, 0, *paperSizes[self._canvasSize][self._ppi]) self.parentMdiArea = parentMdiArea self.parentFileWindow = parentFileWindow self.customContextMenuRequested.connect(self.sideViewContextMenu) def addStreamTable(self, pos=QPointF(0, 0), table=None): """ build stream table at pos with table, if table is not passed, builds a blank table """ self.streamTable = table if table else streamTable(self.labelItems, canvas=self) self.streamTableRect = moveRect() self.streamTableRect.setFlags(moveRect.ItemIsMovable | moveRect.ItemIsSelectable) self.streamTableProxy = QGraphicsProxyWidget(self.streamTableRect) self.streamTableProxy.setWidget(self.streamTable) self.painter.addItem(self.streamTableRect) self.streamTableRect.setPos(pos) def updateStreamTable(self, item): """ updates stream table with any new line labels added """ if self.streamTable: self.streamTable.model.insertColumn(item=item) def sideViewContextMenu(self, pos): """ shows the context menu for the side view """ self.parentFileWindow.sideViewContextMenu( self.mapTo(self.parentFileWindow, pos)) def resizeView(self, w, h): #helper function to resize canvas self.painter.setSceneRect(0, 0, w, h) def adjustView(self): #utitily to adjust current diagram view width, height = self.dimensions frameWidth = self.frameWidth() #update view size self.setSceneRect(0, 0, width - frameWidth * 2, height) def setCanvasSize(self, size): """ extended setter for dialog box """ self.canvasSize = size def setCanvasPPI(self, ppi): """ extended setter for dialog box """ self.ppi = ppi @property def dimensions(self): #returns the dimension of the current scene return self.painter.sceneRect().width(), self.painter.sceneRect( ).height() @property def items(self): # generator to filter out certain items for i in self.painter.items(): yield i @property def labelItems(self): return [i for i in self.items if isinstance(i, shapes.LineLabel)] @property def canvasSize(self): return self._canvasSize @property def ppi(self): return self._ppi @property def landscape(self): return self._landscape @canvasSize.setter def canvasSize(self, size): self._canvasSize = size if self.painter: self.resizeView(*(sorted(paperSizes[self.canvasSize][self.ppi], reverse=self.landscape))) @ppi.setter def ppi(self, ppi): self._ppi = ppi if self.painter: self.resizeView(*(sorted(paperSizes[self.canvasSize][self.ppi], reverse=self.landscape))) @landscape.setter def landscape(self, bool): self._landscape = bool if self.painter: self.resizeView(*(sorted(paperSizes[self.canvasSize][self.ppi], reverse=self.landscape))) #following 2 methods are defined for correct pickling of the scene. may be changed to json or xml later so as # to not have a binary file. def __getstate__(self) -> dict: return { "_classname_": self.__class__.__name__, "ppi": self._ppi, "canvasSize": self._canvasSize, "ObjectName": self.objectName(), "symbols": [ i for i in self.painter.items() if isinstance(i, shapes.NodeItem) ], "lines": sorted([ i for i in self.painter.items() if isinstance(i, shapes.Line) ], key=lambda x: 1 if x.refLine else 0), "landscape": self.landscape, "streamTable": [ self.streamTable, (self.streamTableRect.pos().x(), self.streamTableRect.pos().y()) ] if self.streamTable else False } def __setstate__(self, dict): self._ppi = dict['ppi'] self._canvasSize = dict['canvasSize'] self.landscape = dict['landscape'] self.setObjectName(dict['ObjectName']) #load symbols from the file, while building the memory map as well. for item in dict['symbols']: graphic = getattr(shapes, item['_classname_'])() graphic.__setstate__(dict=item) self.painter.addItem(graphic) graphic.setPos(*item['pos']) graphic.updateLineGripItem() graphic.updateSizeGripItem() for gripitem in item['lineGripItems']: memMap[gripitem[0]] = (graphic, gripitem[1]) if item['label']: graphicLabel = shapes.ItemLabel( pos=QPointF(*item['label']['pos']), parent=graphic) graphicLabel.__setstate__(item['label']) self.painter.addItem(graphicLabel) graphic.rotation = item['rotation'] graphic.flipH, graphic.flipV = item['flipstate'] #load lines from the file, while using and building the memory map. for item in dict['lines']: line = shapes.Line(QPointF(*item['startPoint']), QPointF(*item['endPoint'])) memMap[item['id']] = line line.__setstate__(dict=item) self.painter.addItem(line) graphic, index = memMap[item['startGripItem']] line.startGripItem = graphic.lineGripItems[index] graphic.lineGripItems[index].lines.append(line) if item['endGripItem']: graphic, index = memMap[item['endGripItem']] line.endGripItem = graphic.lineGripItems[index] graphic.lineGripItems[index].lines.append(line) else: line.refLine = memMap[item['refLine']] memMap[item['refLine']].midLines.append(line) line.refIndex = item['refIndex'] for label in item['label']: labelItem = shapes.LineLabel(QPointF(*label['pos']), line) line.label.append(labelItem) labelItem.__setstate__(label) self.painter.addItem(labelItem) line.updateLine() line.addGrabber() # add streamtable if it existed in the scene. if dict['streamTable']: table = streamTable(self.labelItems, self) self.addStreamTable(QPointF(*dict['streamTable'][1]), table) table.__setstate__(dict['streamTable'][0]) memMap.clear( ) #clear out memory map as we now have no use for it. Hopefully garbage collected self.painter.advance() #request collision detection
web.load(QtCore.QUrl("http://www.enib.fr")) # web.load(QtCore.QUrl("https://pythonspot.com/pyqt5-browser/")) self.proxy = WebProxy() self.proxy.setWidget(web) self.addItem(self.proxy) def mouseMoveEvent(self, event): if (event.buttons() & QtCore.Qt.LeftButton): delta = QtCore.QPointF(event.scenePos() - event.lastScenePos()) rotation = delta.x() self.proxy.set_rotate(rotation + self.proxy.get_rotate()) matrix = QtGui.QTransform() matrix.translate(self.proxy.widget().width() / 2.0, self.proxy.widget().height() / 2.0) matrix.rotate(self.proxy.get_rotate(), QtCore.Qt.ZAxis) self.proxy.setTransform(matrix) if __name__ == "__main__": app = QApplication(sys.argv) scene = Scene() button = QPushButton("Quit application") button.move(100, 100) button.clicked.connect(qApp.quit) proxy = QGraphicsProxyWidget() proxy.setWidget(button) scene.addItem(proxy) view = QGraphicsView(scene) view.setWindowTitle("Ma scene WEB") view.show() sys.exit(app.exec_())
if __name__ == '__main__': import sys app = QApplication(sys.argv) # Text edit and button. edit = QTextEdit() edit.setText("asdf lkjha yuoiqwe asd iuaysd u iasyd uiy " "asdf lkjha yuoiqwe asd iuaysd u iasyd uiy " "asdf lkjha yuoiqwe asd iuaysd u iasyd uiy " "asdf lkjha yuoiqwe asd iuaysd u iasyd uiy!") button = QPushButton() buttonProxy = QGraphicsProxyWidget() buttonProxy.setWidget(button) editProxy = QGraphicsProxyWidget() editProxy.setWidget(edit) box = QGroupBox() box.setFlat(True) box.setTitle("Options") layout2 = QVBoxLayout() box.setLayout(layout2) layout2.addWidget(QRadioButton("Herring")) layout2.addWidget(QRadioButton("Blue Parrot")) layout2.addWidget(QRadioButton("Petunias")) layout2.addStretch()
def keyReleaseEvent(self, ev): if ev.key() == Qt.Key_Shift: self._shift = False QGraphicsProxyWidget.keyReleaseEvent(self, ev)
def createItem(minimum, preferred, maximum, name): w = QGraphicsProxyWidget() w.setWidget(QPushButton(name)) w.setMinimumSize(minimum) w.setPreferredSize(preferred) w.setMaximumSize(maximum) w.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) return w
def boundingRect(self): return QGraphicsProxyWidget.boundingRect(self).adjusted(0, 0, 10, 10)
class Node(QGraphicsItem): """! Node representing a tool with its state, ports, ... (in Mono tab) """ # Node status labels <str> NOT_CONFIGURED, READY, SUCCESS, FAIL = 'Not configured', 'Ready', 'Success', 'Fail' ## Node status colors <{str: PyQt5.QtGui.QColor}> COLOR = { NOT_CONFIGURED: QColor(220, 255, 255, 255), READY: QColor(250, 220, 165, 255), SUCCESS: QColor(180, 250, 165, 255), FAIL: QColor(255, 160, 160, 255) } def __init__(self, index): super().__init__() self._index = index ## Box of the year self.box = Box(self) ## Progress bar appearing in upper part box <PyQt5.QtWidgets.QProgressBar> self.progress_bar = QProgressBar() self.progress_bar.setTextVisible(False) self.progress_bar.setMinimum(0) self.progress_bar.setMaximum(100) ## Progress bar proxy <PyQt5.QtWidgets.QGraphicsProxyWidget> self.proxy = QGraphicsProxyWidget(self) self.proxy.setWidget(self.progress_bar) self.proxy.setGeometry( QRectF(self.boundingRect().topLeft(), self.boundingRect().topRight() + QPointF(0, 30))) self.progress_bar.setVisible(False) self.setAcceptedMouseButtons(Qt.LeftButton) self.setFlag(QGraphicsItem.ItemIsMovable) self.setFlag(QGraphicsItem.ItemSendsGeometryChanges) self.setFlag(QGraphicsItem.ItemIsSelectable) self.setCursor(Qt.ArrowCursor) ## Help action <PyQt5.QtWidgets.QAction> self.help_action = QAction( QWidget().style().standardIcon(QStyle.SP_MessageBoxQuestion), 'Help', None) self.dashed_pen = QPen(Qt.black, 1, Qt.DashLine) ## Node label <str> self.label = '' ## Node category <str> self.category = '' ## Node state (among NOT_CONFIGURED, READY, SUCCESS, FAIL) self.state = Node.NOT_CONFIGURED ## Node message <str> self.message = '' ## Input and Output Ports list <[Port]> self.ports = [] ## Links set <set(Link)> self.links = set() def index(self): return self._index def set_index(self, index): self._index = index def name(self): return ' '.join(self.label.split()) def add_port(self, port): self.ports.append(port) port.setParentItem(self) def add_link(self, link): self.links.add(link) def remove_link(self, link): self.links.remove(link) def update_links(self): for link in self.links: link.update_nodes() def boundingRect(self): pos = self.box.rect().topLeft() return QRectF(pos.x() - 5 - Port.WIDTH, pos.y() - 20, Box.WIDTH + 2 * Port.WIDTH + 10, Box.HEIGHT + 2 * Port.WIDTH + 20) def paint(self, painter, options, widget=None): painter.fillRect(self.box.rect(), Node.COLOR[self.state]) painter.drawText(self.box.rect().topLeft() + QPointF(4, -3), self.state) painter.setPen(QPen(QColor(0, 0, 0))) painter.drawText(self.box.rect(), Qt.AlignCenter, self.label) if self.isSelected(): painter.setPen(self.dashed_pen) painter.drawRect(self.boundingRect()) def mousePressEvent(self, event): self.setCursor(Qt.ClosedHandCursor) super().mousePressEvent(event) def mouseReleaseEvent(self, event): self.setCursor(Qt.OpenHandCursor) super().mouseReleaseEvent(event) self.update_links() def mouseMoveEvent(self, event): super().mouseMoveEvent(event) if self.x() < Port.WIDTH: self.setX(Port.WIDTH) elif self.x() + self.boundingRect().width() > self.scene().width(): self.setX(self.scene().width() - self.boundingRect().width()) if self.y() < Port.WIDTH: self.setY(Port.WIDTH) elif self.y() + self.boundingRect().height() > self.scene().height(): self.setY(self.scene().height() - self.boundingRect().height()) def itemChange(self, change, value): result = super().itemChange(change, value) if change == QGraphicsItem.ItemPositionHasChanged: self.update_links() return result def contextMenuEvent(self, event): menu = QMenu() menu.addAction(self.help_action) menu.exec_(event.screenPos()) def get_option_panel(self): return QWidget() def ready_to_run(self): pass def configure(self, check=None): """Execute configure dialog and check if accepted""" configure_dialog = ConfigureDialog(self.get_option_panel(), self.name(), check) configure_dialog.message_field.appendPlainText(self.message) if configure_dialog.exec_() == QDialog.Accepted: self.state = Node.READY self.message = '' self.update() return True return False def reconfigure(self): self.message = '' if self.state != Node.NOT_CONFIGURED: self.state = Node.READY self.update() def reconfigure_downward(self): for port in self.ports: if port.type == Port.OUTPUT: for child in port.children: child.parentItem().reconfigure() def run_upward(self): return True def run_downward(self): """Try to run current Node and check if succeeded""" if self.ready_to_run() and self.state != Node.SUCCESS: self.run() if self.state != Node.SUCCESS: return False return True def run(self): pass def construct_mesh(self, mesh): five_percent = 0.05 * mesh.nb_triangles nb_processed = 0 current_percent = 0 for i, j, k in mesh.ikle: t = Polygon([mesh.points[i], mesh.points[j], mesh.points[k]]) mesh.triangles[i, j, k] = t mesh.index.insert(i, t.bounds, obj=(i, j, k)) nb_processed += 1 if nb_processed > five_percent: nb_processed = 0 current_percent += 5 self.progress_bar.setValue(current_percent) QApplication.processEvents() self.progress_bar.setValue(0) QApplication.processEvents() def save(self): return '|'.join([ self.category, self.name(), str(self.index()), str(self.pos().x()), str(self.pos().y()), '' ]) def load(self, options): self.state = Node.READY def success(self, message=''): self.progress_bar.setVisible(False) self.state = Node.SUCCESS self.update() self.message = 'Successful. ' + message def fail(self, message): self.progress_bar.setVisible(False) self.state = Node.FAIL self.update() self.message = 'Failed: ' + message
def initContent(self): self.grContent = QGraphicsProxyWidget(self) self.content.setGeometry(self.edge_size, self.title_height + self.edge_size, self.width - 2 * self.edge_size, self.height - 2 * self.edge_size - self.title_height) self.grContent.setWidget(self.content)
class QDMGraphicsNode(QGraphicsItem): def __init__(self, node, parent=None): super().__init__(parent) self.node = node self.content = self.node.content self._title_color = Qt.white self._title_font = QFont("Arial", 12) self.width = 180 self.height = 240 self.edge_size = 10 self.title_height = 24 self._padding = 4 self._pen_default = QPen(QColor(self.get_outline_color())) self._pen_selected = QPen(QColor("#e18b32")) self._title_brush = QBrush(QColor(self.get_title_color())) self._background_brush = QBrush(QColor(self.get_background_color())) self.initTitle() self.title = self.node.title # init content self.initContent() # init sockets #self.initSockets() self.setFlag(QGraphicsItem.ItemIsFocusable, True) self.initUI() def boundingRect(self): return QRectF( 0, 0, self.width, self.height ).normalized() def initUI(self): self.setFlag(QGraphicsItem.ItemIsSelectable) self.setFlag(QGraphicsItem.ItemIsMovable) def initTitle(self): self.title_item = QGraphicsTextItem(self) self.title_item.setDefaultTextColor(self._title_color) self.title_item.setFont(self._title_font) self.title_item.setTextWidth(self.width - 2 * self._padding) self.title_item.setX(self._padding) def get_title_color(self): return "#954a4a" def get_background_color(self): return "#2b2b2b" def get_outline_color(self): return "#181818" def initSockets(self): self.content.drawSocketItems() def initContent(self): self.grContent = QGraphicsProxyWidget(self) self.content.setGeometry(self.edge_size, self.title_height + self.edge_size, self.width - 2 * self.edge_size, self.height - 2 * self.edge_size - self.title_height) self.grContent.setWidget(self.content) @property def title(self): return self._title @title.setter def title(self, value): self._title = value self.title_item.setPlainText(self._title) def paint(self, painter, option, widget=None): # title path_title = QPainterPath() path_title.setFillRule(Qt.WindingFill) path_title.addRoundedRect(0, 0, self.width, self.title_height, self.edge_size, self.edge_size) path_title.addRect(0, self.title_height - self.edge_size, self.edge_size, self.edge_size) path_title.addRect(self.width - self.edge_size, self.title_height - self.edge_size, self.edge_size, self.edge_size) painter.setPen(Qt.NoPen) painter.setBrush(self._title_brush) painter.drawPath(path_title.simplified()) # content path_content = QPainterPath() path_content.setFillRule(Qt.WindingFill) path_content.addRoundedRect(0, self.title_height, self.width, self.height - self.title_height, self.edge_size, self.edge_size) path_content.addRect(0, self.title_height, self.edge_size, self.edge_size) path_content.addRect(self.width - self.edge_size, self.title_height, self.edge_size, self.edge_size) painter.setPen(Qt.NoPen) painter.setBrush(self._background_brush) painter.drawPath(path_content.simplified()) # outline path_outline = QPainterPath() path_outline.addRoundedRect(0, 0, self.width, self.height, self.edge_size, self.edge_size) painter.setPen(self._pen_default if not self.isSelected() else self._pen_selected) painter.setBrush(Qt.NoBrush) painter.drawPath(path_outline.simplified()) def mouseMoveEvent(self, event): super().mouseMoveEvent(event) self.node.update_linked_sockets() def keyReleaseEvent(self, event): super().keyReleaseEvent(event) if not self.hasFocus(): return if event.key() == Qt.Key_Backspace or event.key() == Qt.Key_Delete: self.node.scene.removeNode(self.node)
class ServiceSticker(QGraphicsItem): def __init__(self, name, login, pos, color, password, mainWindow, id): super().__init__() self._width = 270.0 self._height = 157.0 self._color = color self._pos = pos self._name = name self._login = login self._password = password self._mainWindow = mainWindow self._id = id self.widget = ServiceCardWidget(name, login, self._color, parent=self) self.proxyWidget = QGraphicsProxyWidget(self) self.proxyWidget.setWidget(self.widget) self.anim = QPropertyAnimation(self.proxyWidget, b'geometry') ''' Method returns rectangle containing a position of the card on graphics scene. ''' def boundingRect(self): # getting rect of graphics view on main window viewRect = QRectF(self.mainWindow().graphicsView.geometry()) min_x_padding = 20.0 # determining how much cards can it be in a row items_per_line, remainder = self.remainder_div( viewRect.width(), self._width + min_x_padding) x_padding = remainder / (items_per_line - 1) y_padding = 40.0 # number of row y_counter = 0 # item's position from top top left corner to bottom right corner # from left to right line_pos = self._pos + 1 while True: if items_per_line - line_pos >= 0: x_counter = line_pos - 1 break else: line_pos -= items_per_line y_counter += 1 return QRectF(x_counter * (self._width + x_padding + min_x_padding), y_counter * (y_padding + self._height), self._width, self._height) ''' This method sets position of a proxy widget ''' def paint(self, painter, option, widget): self.proxyWidget.setPos(self.boundingRect().x(), self.boundingRect().y()) def data(self): return { 'name': self._name, 'id': self._id, 'pos': self._pos, 'login': self._login, 'color': self._color, 'password': self._password } def mainWindow(self): return self._mainWindow def getWidget(self): return self.widget @staticmethod def remainder_div(a, b): return (math.floor(a / b), a % b)
import sys from PyQt5 import QtCore, QtGui from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QGraphicsProxyWidget from PyQt5.QtWidgets import QGraphicsScene, QGraphicsView, QGraphicsItem app = QApplication(sys.argv) scene = QGraphicsScene() rect = scene.addRect(QtCore.QRectF(0, 0, 100, 100)) rect.setFlag(QGraphicsItem.ItemIsMovable) button = QPushButton("Un bouton") proxy = QGraphicsProxyWidget() proxy.setWidget(button) scene.addItem(proxy) scene.setSceneRect(0, 0, 300, 300) matrix = QtGui.QTransform() matrix.rotate(45) matrix.translate(100, 0) matrix.scale(1, 2) proxy.setTransform(matrix) # print("proxy->x() : ",proxy->x()) # print("proxy->y() : ",proxy->y()) # proxy.setTransform(matrix); view = QGraphicsView(scene) #view.resize(500,300) #view.move(500, 500) view.show() sys.exit(app.exec_())
def __init__(self, size, parent=None): super(PadNavigator, self).__init__(parent) self.form = Ui_Form() splash = SplashItem() splash.setZValue(1) pad = FlippablePad(size) flipRotation = QGraphicsRotation(pad) xRotation = QGraphicsRotation(pad) yRotation = QGraphicsRotation(pad) flipRotation.setAxis(Qt.YAxis) xRotation.setAxis(Qt.YAxis) yRotation.setAxis(Qt.XAxis) pad.setTransformations([flipRotation, xRotation, yRotation]) backItem = QGraphicsProxyWidget(pad) widget = QWidget() self.form.setupUi(widget) self.form.hostName.setFocus() backItem.setWidget(widget) backItem.setVisible(False) backItem.setFocus() backItem.setCacheMode(QGraphicsItem.ItemCoordinateCache) r = backItem.rect() backItem.setTransform(QTransform().rotate(180, Qt.YAxis).translate( -r.width() / 2, -r.height() / 2)) selectionItem = RoundRectItem(QRectF(-60, -60, 120, 120), QColor(Qt.gray), pad) selectionItem.setZValue(0.5) smoothSplashMove = QPropertyAnimation(splash) smoothSplashOpacity = QPropertyAnimation(splash) smoothSplashMove.setEasingCurve(QEasingCurve.InQuad) smoothSplashMove.setDuration(250) smoothSplashOpacity.setDuration(250) smoothXSelection = QPropertyAnimation(selectionItem) smoothYSelection = QPropertyAnimation(selectionItem) smoothXRotation = QPropertyAnimation(xRotation) smoothYRotation = QPropertyAnimation(yRotation) smoothXSelection.setDuration(125) smoothYSelection.setDuration(125) smoothXRotation.setDuration(125) smoothYRotation.setDuration(125) smoothXSelection.setEasingCurve(QEasingCurve.InOutQuad) smoothYSelection.setEasingCurve(QEasingCurve.InOutQuad) smoothXRotation.setEasingCurve(QEasingCurve.InOutQuad) smoothYRotation.setEasingCurve(QEasingCurve.InOutQuad) smoothFlipRotation = QPropertyAnimation(flipRotation) smoothFlipScale = QPropertyAnimation(pad) smoothFlipXRotation = QPropertyAnimation(xRotation) smoothFlipYRotation = QPropertyAnimation(yRotation) flipAnimation = QParallelAnimationGroup(self) smoothFlipScale.setDuration(500) smoothFlipRotation.setDuration(500) smoothFlipXRotation.setDuration(500) smoothFlipYRotation.setDuration(500) smoothFlipScale.setEasingCurve(QEasingCurve.InOutQuad) smoothFlipRotation.setEasingCurve(QEasingCurve.InOutQuad) smoothFlipXRotation.setEasingCurve(QEasingCurve.InOutQuad) smoothFlipYRotation.setEasingCurve(QEasingCurve.InOutQuad) smoothFlipScale.setKeyValueAt(0, 1.0) smoothFlipScale.setKeyValueAt(0.5, 0.7) smoothFlipScale.setKeyValueAt(1, 1.0) flipAnimation.addAnimation(smoothFlipRotation) flipAnimation.addAnimation(smoothFlipScale) flipAnimation.addAnimation(smoothFlipXRotation) flipAnimation.addAnimation(smoothFlipYRotation) setVariablesSequence = QSequentialAnimationGroup() setFillAnimation = QPropertyAnimation(pad) setBackItemVisibleAnimation = QPropertyAnimation(backItem) setSelectionItemVisibleAnimation = QPropertyAnimation(selectionItem) setFillAnimation.setDuration(0) setBackItemVisibleAnimation.setDuration(0) setSelectionItemVisibleAnimation.setDuration(0) setVariablesSequence.addPause(250) setVariablesSequence.addAnimation(setBackItemVisibleAnimation) setVariablesSequence.addAnimation(setSelectionItemVisibleAnimation) setVariablesSequence.addAnimation(setFillAnimation) flipAnimation.addAnimation(setVariablesSequence) stateMachine = QStateMachine(self) splashState = QState(stateMachine) frontState = QState(stateMachine) historyState = QHistoryState(frontState) backState = QState(stateMachine) frontState.assignProperty(pad, "fill", False) frontState.assignProperty(splash, "opacity", 0.0) frontState.assignProperty(backItem, "visible", False) frontState.assignProperty(flipRotation, "angle", 0.0) frontState.assignProperty(selectionItem, "visible", True) backState.assignProperty(pad, "fill", True) backState.assignProperty(backItem, "visible", True) backState.assignProperty(xRotation, "angle", 0.0) backState.assignProperty(yRotation, "angle", 0.0) backState.assignProperty(flipRotation, "angle", 180.0) backState.assignProperty(selectionItem, "visible", False) stateMachine.addDefaultAnimation(smoothXRotation) stateMachine.addDefaultAnimation(smoothYRotation) stateMachine.addDefaultAnimation(smoothXSelection) stateMachine.addDefaultAnimation(smoothYSelection) stateMachine.setInitialState(splashState) anyKeyTransition = QEventTransition(self, QEvent.KeyPress, splashState) anyKeyTransition.setTargetState(frontState) anyKeyTransition.addAnimation(smoothSplashMove) anyKeyTransition.addAnimation(smoothSplashOpacity) enterTransition = QKeyEventTransition(self, QEvent.KeyPress, Qt.Key_Enter, backState) returnTransition = QKeyEventTransition(self, QEvent.KeyPress, Qt.Key_Return, backState) backEnterTransition = QKeyEventTransition(self, QEvent.KeyPress, Qt.Key_Enter, frontState) backReturnTransition = QKeyEventTransition(self, QEvent.KeyPress, Qt.Key_Return, frontState) enterTransition.setTargetState(historyState) returnTransition.setTargetState(historyState) backEnterTransition.setTargetState(backState) backReturnTransition.setTargetState(backState) enterTransition.addAnimation(flipAnimation) returnTransition.addAnimation(flipAnimation) backEnterTransition.addAnimation(flipAnimation) backReturnTransition.addAnimation(flipAnimation) columns = size.width() rows = size.height() stateGrid = [] for y in range(rows): stateGrid.append([QState(frontState) for _ in range(columns)]) frontState.setInitialState(stateGrid[0][0]) selectionItem.setPos(pad.iconAt(0, 0).pos()) for y in range(rows): for x in range(columns): state = stateGrid[y][x] rightTransition = QKeyEventTransition(self, QEvent.KeyPress, Qt.Key_Right, state) leftTransition = QKeyEventTransition(self, QEvent.KeyPress, Qt.Key_Left, state) downTransition = QKeyEventTransition(self, QEvent.KeyPress, Qt.Key_Down, state) upTransition = QKeyEventTransition(self, QEvent.KeyPress, Qt.Key_Up, state) rightTransition.setTargetState(stateGrid[y][(x + 1) % columns]) leftTransition.setTargetState( stateGrid[y][((x - 1) + columns) % columns]) downTransition.setTargetState(stateGrid[(y + 1) % rows][x]) upTransition.setTargetState(stateGrid[((y - 1) + rows) % rows][x]) icon = pad.iconAt(x, y) state.assignProperty(xRotation, "angle", -icon.x() / 6.0) state.assignProperty(yRotation, "angle", icon.y() / 6.0) state.assignProperty(selectionItem, "x", icon.x()) state.assignProperty(selectionItem, "y", icon.y()) frontState.assignProperty(icon, "visible", True) backState.assignProperty(icon, "visible", False) setIconVisibleAnimation = QPropertyAnimation(icon) setIconVisibleAnimation.setDuration(0) setVariablesSequence.addAnimation(setIconVisibleAnimation) scene = QGraphicsScene(self) scene.setBackgroundBrush( QBrush(QPixmap(":/images/blue_angle_swirl.jpg"))) scene.setItemIndexMethod(QGraphicsScene.NoIndex) scene.addItem(pad) scene.setSceneRect(scene.itemsBoundingRect()) self.setScene(scene) sbr = splash.boundingRect() splash.setPos(-sbr.width() / 2, scene.sceneRect().top() - 2) frontState.assignProperty(splash, "y", splash.y() - 100.0) scene.addItem(splash) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setMinimumSize(50, 50) self.setViewportUpdateMode(QGraphicsView.FullViewportUpdate) self.setCacheMode(QGraphicsView.CacheBackground) self.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform | QPainter.TextAntialiasing) if QGLFormat.hasOpenGL(): self.setViewport(QGLWidget(QGLFormat(QGL.SampleBuffers))) stateMachine.start()
class QGraphicsResizableRectItem(QGraphicsRectItem): def __init__(self, min_height, min_width, *args): super().__init__(*args) # Diverse parameters for drawing self.handleSelected = None self.handles = {} self.min_width = min_width self.min_height = min_height self.initSizes() self.initContent() self.initAssets() self.initUI() self.initTitle() def initUI(self): # set flags self.setAcceptHoverEvents(True) self.setFlag(QGraphicsItem.ItemSendsGeometryChanges, True) self.setFlag(QGraphicsItem.ItemIsFocusable, True) self.updateHandles() self.setFlag(QGraphicsItem.ItemIsMovable, True) self.setFlag(QGraphicsItem.ItemIsSelectable, True) def initContent(self): self.content = NodeContentWidget(None) self.grContent = QGraphicsProxyWidget(self) self.setContentGeometry() self.grContent.setWidget(self.content) def initAssets(self): self._title_color = Qt.white self._title_font = QFont('Ubuntu', 8) self._color = QColor("#7F00000") self._color_selected = QColor("#FFFFA637") self._color_hovered = QColor("#FF37A6FF") self._pen_default = QPen(self._color) self._pen_default.setWidthF(OUTLINE_WIDTH) self._pen_selected = QPen(self._color_selected) self._pen_selected.setWidthF(OUTLINE_WIDTH) self._pen_hovered = QPen(self._color_hovered) self._pen_hovered.setWidthF(OUTLINE_WIDTH + 1) self._brush_title = QBrush(QColor("#FF313131")) self._brush_background = QBrush(QColor("#E3212121")) def initSizes(self): # self.width = 180 # self.height = 240 # Diverse parameters for drawing self.handleSize = 5 self.edge_roundness = 15. self.edge_padding = 10. self.title_height = 24 self.title_horizontal_padding = 5. self.title_vertical_padding = 4. def setContentGeometry(self): self.content.setGeometry( self.edge_roundness, self.title_height + self.edge_roundness, self.width - 2 * self.edge_roundness, self.height - 2 * self.edge_roundness - self.title_height) def initTitle(self): # Draw the _title self._title_color = Qt.white self._title_font = QFont('Ubuntu', 10) self._padding = 5. self.title_height = 24 self.title_item = QGraphicsTextItem(self) # self.title_item.node = self.node self.title_item.setDefaultTextColor(self._title_color) self.title_item.setFont(self._title_font) self.title_item.setPos(self._padding, 0) self.title_item.setTextWidth(self.width - 2 * self._padding) self.title_item.setPlainText('Resizeable node') @property def height(self): return self.rect().height() @property def width(self): return self.rect().width() def updateHandles(self): rect = self.boundingRect() left, width, top, height = rect.left(), rect.width(), rect.top( ), rect.height() offset = self.handleSize self.handles[Handle.TopLeft] = QRectF(left, top, offset, offset) self.handles[Handle.TopMiddle] = QRectF(left + offset, top, width - 2 * offset, offset) self.handles[Handle.TopRight] = QRectF(left + width - offset, top, offset, offset) self.handles[Handle.BottomLeft] = QRectF(left, top + height - offset, offset, offset) self.handles[Handle.MiddleLeft] = QRectF(left, top + offset, offset, height - 2 * offset) self.handles[Handle.BottomRight] = QRectF(left + width - offset, top + height - offset, offset, offset) self.handles[Handle.MiddleRight] = QRectF(left + width - offset, top + offset, offset, height - 2 * offset) self.handles[Handle.BottomMiddle] = QRectF(left + offset, top + height - offset, width - 2 * offset, offset) def boundingRect(self): # Return rectangle for selection detection return self.rect().normalized() def handleAt(self, point): for handle, rect in self.handles.items(): if rect.contains(point): if DEBUG: print(handle, rect) return handle else: return None def hoverMoveEvent(self, event: 'QGraphicsSceneHoverEvent') -> None: # if self.isSelected(): handle = self.handleAt(event.pos()) if handle is not None: self.setCursor(handleCursors[handle]) else: self.setCursor(Qt.ArrowCursor) super().hoverMoveEvent(event) def hoverLeaveEvent(self, event: 'QGraphicsSceneHoverEvent') -> None: # if self.isSelected(): self.setCursor(Qt.ArrowCursor) super().hoverLeaveEvent(event) def mousePressEvent(self, event: 'QGraphicsSceneMouseEvent') -> None: """ Executed when the mouse is pressed on the item. """ try: self.handleSelected = self.handleAt(event.pos()) if self.handleSelected: # record the position where the mouse was pressed self.currentPos = event.pos() # current rectangle at mouse pressed self.currentRect = self.boundingRect() super().mousePressEvent(event) except Exception as e: print(e) def mouseReleaseEvent(self, event: 'QGraphicsSceneMouseEvent') -> None: """ Executed when the mouse is released from the item. """ super().mouseReleaseEvent(event) self.handleSelected = None self.currentPos = None self.currentRect = None self.update() def mouseMoveEvent(self, event: 'QGraphicsSceneMouseEvent') -> None: """ Executed when the mouse is being moved over the item while being pressed. """ if self.handleSelected is not None: self.resize(event.pos()) else: super().mouseMoveEvent(event) def resize(self, pos): """Update rectangle and bounding rectangle""" rect = self.rect() boundingRect = self.boundingRect() from_left = self.currentRect.left() from_right = self.currentRect.right() from_top = self.currentRect.top() from_bottom = self.currentRect.bottom() to_left = from_left + pos.x() - self.currentPos.x() to_right = from_right + pos.x() - self.currentPos.x() to_top = from_top + pos.y() - self.currentPos.y() to_bottom = from_bottom + pos.y() - self.currentPos.y() self.prepareGeometryChange() update_left, update_top, update_right, update_bottom = handleUpdate[ self.handleSelected] if update_left: if from_right - to_left <= self.min_width: boundingRect.setLeft(from_right - self.min_width) else: boundingRect.setLeft(to_left) rect.setLeft(boundingRect.left()) if update_top: if from_bottom - to_top <= self.min_height: boundingRect.setTop(from_bottom - self.min_height) else: boundingRect.setTop(to_top) rect.setTop(boundingRect.top()) if update_bottom: if to_bottom - from_top <= self.min_height: boundingRect.setBottom(from_top + self.min_height) else: boundingRect.setBottom(to_bottom) rect.setBottom(boundingRect.bottom()) if update_right: if to_right - from_left <= self.min_width: boundingRect.setRight(from_left + self.min_width) else: boundingRect.setRight(to_right) rect.setRight(boundingRect.right()) self.setRect(rect) self.updateHandles() self.setContentGeometry() def shape(self): """ Returns the shape of this item as a QPainterPath in local coordinates. """ path = QPainterPath() # path.addRoundedRect(self.rect(), self.edge_size, self.edge_size) path.addRect(self.rect()) return path def paint(self, painter: QPainter, option: 'QStyleOptionGraphicsItem', widget: Optional[QWidget] = ...) -> None: # content rect = self.rect() path_content = QPainterPath() path_content.setFillRule(Qt.WindingFill) path_content.addRoundedRect(rect, self.edge_roundness, self.edge_roundness) painter.setPen(Qt.NoPen) painter.setBrush(self._brush_background) painter.drawPath(path_content.simplified()) # outline path_outline = QPainterPath() path_outline.addRoundedRect(rect, self.edge_roundness, self.edge_roundness) painter.setPen( self._pen_default if not self.isSelected() else self._pen_selected) painter.setBrush(Qt.NoBrush) painter.drawPath(path_outline.simplified()) for handle in self.handles.values(): path_handle = QPainterPath() path_handle.addRect(handle) painter.drawPath(path_handle)
def initContent(self): self.content = NodeContentWidget(None) self.grContent = QGraphicsProxyWidget(self) self.setContentGeometry() self.grContent.setWidget(self.content)
def __init__(self, size, parent=None): super(PadNavigator, self).__init__(parent) self.form = Ui_Form() splash = SplashItem() splash.setZValue(1) pad = FlippablePad(size) flipRotation = QGraphicsRotation(pad) xRotation = QGraphicsRotation(pad) yRotation = QGraphicsRotation(pad) flipRotation.setAxis(Qt.YAxis) xRotation.setAxis(Qt.YAxis) yRotation.setAxis(Qt.XAxis) pad.setTransformations([flipRotation, xRotation, yRotation]) backItem = QGraphicsProxyWidget(pad) widget = QWidget() self.form.setupUi(widget) self.form.hostName.setFocus() backItem.setWidget(widget) backItem.setVisible(False) backItem.setFocus() backItem.setCacheMode(QGraphicsItem.ItemCoordinateCache) r = backItem.rect() backItem.setTransform(QTransform().rotate(180, Qt.YAxis).translate(-r.width()/2, -r.height()/2)) selectionItem = RoundRectItem(QRectF(-60, -60, 120, 120), QColor(Qt.gray), pad) selectionItem.setZValue(0.5) smoothSplashMove = QPropertyAnimation(splash, b'y') smoothSplashOpacity = QPropertyAnimation(splash, b'opacity') smoothSplashMove.setEasingCurve(QEasingCurve.InQuad) smoothSplashMove.setDuration(250) smoothSplashOpacity.setDuration(250) smoothXSelection = QPropertyAnimation(selectionItem, b'x') smoothYSelection = QPropertyAnimation(selectionItem, b'y') smoothXRotation = QPropertyAnimation(xRotation, b'angle') smoothYRotation = QPropertyAnimation(yRotation, b'angle') smoothXSelection.setDuration(125) smoothYSelection.setDuration(125) smoothXRotation.setDuration(125) smoothYRotation.setDuration(125) smoothXSelection.setEasingCurve(QEasingCurve.InOutQuad) smoothYSelection.setEasingCurve(QEasingCurve.InOutQuad) smoothXRotation.setEasingCurve(QEasingCurve.InOutQuad) smoothYRotation.setEasingCurve(QEasingCurve.InOutQuad) smoothFlipRotation = QPropertyAnimation(flipRotation, b'angle') smoothFlipScale = QPropertyAnimation(pad, b'scale') smoothFlipXRotation = QPropertyAnimation(xRotation, b'angle') smoothFlipYRotation = QPropertyAnimation(yRotation, b'angle') flipAnimation = QParallelAnimationGroup(self) smoothFlipScale.setDuration(500) smoothFlipRotation.setDuration(500) smoothFlipXRotation.setDuration(500) smoothFlipYRotation.setDuration(500) smoothFlipScale.setEasingCurve(QEasingCurve.InOutQuad) smoothFlipRotation.setEasingCurve(QEasingCurve.InOutQuad) smoothFlipXRotation.setEasingCurve(QEasingCurve.InOutQuad) smoothFlipYRotation.setEasingCurve(QEasingCurve.InOutQuad) smoothFlipScale.setKeyValueAt(0, 1.0) smoothFlipScale.setKeyValueAt(0.5, 0.7) smoothFlipScale.setKeyValueAt(1, 1.0) flipAnimation.addAnimation(smoothFlipRotation) flipAnimation.addAnimation(smoothFlipScale) flipAnimation.addAnimation(smoothFlipXRotation) flipAnimation.addAnimation(smoothFlipYRotation) setVariablesSequence = QSequentialAnimationGroup() setFillAnimation = QPropertyAnimation(pad, b'fill') setBackItemVisibleAnimation = QPropertyAnimation(backItem, b'visible') setSelectionItemVisibleAnimation = QPropertyAnimation(selectionItem, b'visible') setFillAnimation.setDuration(0) setBackItemVisibleAnimation.setDuration(0) setSelectionItemVisibleAnimation.setDuration(0) setVariablesSequence.addPause(250) setVariablesSequence.addAnimation(setBackItemVisibleAnimation) setVariablesSequence.addAnimation(setSelectionItemVisibleAnimation) setVariablesSequence.addAnimation(setFillAnimation) flipAnimation.addAnimation(setVariablesSequence) stateMachine = QStateMachine(self) splashState = QState(stateMachine) frontState = QState(stateMachine) historyState = QHistoryState(frontState) backState = QState(stateMachine) frontState.assignProperty(pad, "fill", False) frontState.assignProperty(splash, "opacity", 0.0) frontState.assignProperty(backItem, "visible", False) frontState.assignProperty(flipRotation, "angle", 0.0) frontState.assignProperty(selectionItem, "visible", True) backState.assignProperty(pad, "fill", True) backState.assignProperty(backItem, "visible", True) backState.assignProperty(xRotation, "angle", 0.0) backState.assignProperty(yRotation, "angle", 0.0) backState.assignProperty(flipRotation, "angle", 180.0) backState.assignProperty(selectionItem, "visible", False) stateMachine.addDefaultAnimation(smoothXRotation) stateMachine.addDefaultAnimation(smoothYRotation) stateMachine.addDefaultAnimation(smoothXSelection) stateMachine.addDefaultAnimation(smoothYSelection) stateMachine.setInitialState(splashState) anyKeyTransition = QEventTransition(self, QEvent.KeyPress, splashState) anyKeyTransition.setTargetState(frontState) anyKeyTransition.addAnimation(smoothSplashMove) anyKeyTransition.addAnimation(smoothSplashOpacity) enterTransition = QKeyEventTransition(self, QEvent.KeyPress, Qt.Key_Enter, backState) returnTransition = QKeyEventTransition(self, QEvent.KeyPress, Qt.Key_Return, backState) backEnterTransition = QKeyEventTransition(self, QEvent.KeyPress, Qt.Key_Enter, frontState) backReturnTransition = QKeyEventTransition(self, QEvent.KeyPress, Qt.Key_Return, frontState) enterTransition.setTargetState(historyState) returnTransition.setTargetState(historyState) backEnterTransition.setTargetState(backState) backReturnTransition.setTargetState(backState) enterTransition.addAnimation(flipAnimation) returnTransition.addAnimation(flipAnimation) backEnterTransition.addAnimation(flipAnimation) backReturnTransition.addAnimation(flipAnimation) columns = size.width() rows = size.height() stateGrid = [] for y in range(rows): stateGrid.append([QState(frontState) for _ in range(columns)]) frontState.setInitialState(stateGrid[0][0]) selectionItem.setPos(pad.iconAt(0, 0).pos()) for y in range(rows): for x in range(columns): state = stateGrid[y][x] rightTransition = QKeyEventTransition(self, QEvent.KeyPress, Qt.Key_Right, state) leftTransition = QKeyEventTransition(self, QEvent.KeyPress, Qt.Key_Left, state) downTransition = QKeyEventTransition(self, QEvent.KeyPress, Qt.Key_Down, state) upTransition = QKeyEventTransition(self, QEvent.KeyPress, Qt.Key_Up, state) rightTransition.setTargetState(stateGrid[y][(x + 1) % columns]) leftTransition.setTargetState(stateGrid[y][((x - 1) + columns) % columns]) downTransition.setTargetState(stateGrid[(y + 1) % rows][x]) upTransition.setTargetState(stateGrid[((y - 1) + rows) % rows][x]) icon = pad.iconAt(x, y) state.assignProperty(xRotation, "angle", -icon.x() / 6.0) state.assignProperty(yRotation, "angle", icon.y() / 6.0) state.assignProperty(selectionItem, "x", icon.x()) state.assignProperty(selectionItem, "y", icon.y()) frontState.assignProperty(icon, "visible", True) backState.assignProperty(icon, "visible", False) setIconVisibleAnimation = QPropertyAnimation(icon, b'visible') setIconVisibleAnimation.setDuration(0) setVariablesSequence.addAnimation(setIconVisibleAnimation) scene = QGraphicsScene(self) scene.setBackgroundBrush(QBrush(QPixmap(":/images/blue_angle_swirl.jpg"))) scene.setItemIndexMethod(QGraphicsScene.NoIndex) scene.addItem(pad) scene.setSceneRect(scene.itemsBoundingRect()) self.setScene(scene) sbr = splash.boundingRect() splash.setPos(-sbr.width() / 2, scene.sceneRect().top() - 2) frontState.assignProperty(splash, "y", splash.y() - 100.0) scene.addItem(splash) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setMinimumSize(50, 50) self.setViewportUpdateMode(QGraphicsView.FullViewportUpdate) self.setCacheMode(QGraphicsView.CacheBackground) self.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform | QPainter.TextAntialiasing) if QGLFormat.hasOpenGL(): self.setViewport(QGLWidget(QGLFormat(QGL.SampleBuffers))) stateMachine.start()
import sys from PyQt5 import QtCore, QtGui from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QGraphicsProxyWidget from PyQt5.QtWidgets import QGraphicsScene, QGraphicsView, QGraphicsItem #from PyQt5.QtWebKitWidgets import QWebView from PyQt5.QtWebEngineWidgets import QWebEngineView as QWebView, QWebEnginePage as QWebPage from PyQt5.QtWebEngineWidgets import QWebEngineSettings as QWebSettings app = QApplication(sys.argv) scene = QGraphicsScene() web = QWebView() web.load(QtCore.QUrl("http://www.developpez.com")) rect = scene.addRect(QtCore.QRectF(0, 0, 100, 100)) proxy = QGraphicsProxyWidget() proxy.setWidget(web) scene.addItem(proxy) view = QGraphicsView(scene) view.resize(500, 300) view.move(500, 500) view.show() sys.exit(app.exec_())