def _toPrinterAdaptorByIntegralMMSize(self, pageLayout, printerAdaptor): ''' Set my values on printerAdaptor (and whatever printer it is adapting) by setting size. Take integral size, convert to float. ''' # Even a Custom paper has a size, even if it is defaulted. newPaperSizeMM = QSizeF(pageLayout.paper.integralOrientedSizeMM(pageLayout.orientation)) assert newPaperSizeMM.isValid() # use overload QPrinter.setPaperSize(QPagedPaintDevice.PageSize, Units) printerAdaptor.setPaperSize(newPaperSizeMM, QPageLayout.Millimeter)
def boundingRect(self, arg): tp = type(arg) if tp==QRect: rect = arg tileWidth = self.map().tileWidth() tileHeight = self.map().tileHeight() return QRect(rect.x() * tileWidth, rect.y() * tileHeight, rect.width() * tileWidth, rect.height() * tileHeight) elif tp==MapObject: object = arg bounds = object.bounds() boundingRect = QRectF() if (not object.cell().isEmpty()): bottomLeft = bounds.topLeft() tile = object.cell().tile imgSize = tile.image().size() tileOffset = tile.offset() objectSize = object.size() scale = QSizeF(objectSize.width() / imgSize.width(), objectSize.height() / imgSize.height()) boundingRect = QRectF(bottomLeft.x() + (tileOffset.x() * scale.width()), bottomLeft.y() + (tileOffset.y() * scale.height() - objectSize.height()), objectSize.width(), objectSize.height()).adjusted(-1, -1, 1, 1) else: extraSpace = max(self.objectLineWidth(), 1.0) x = object.shape() if x==MapObject.Ellipse or x==MapObject.Rectangle: if (bounds.isNull()): boundingRect = bounds.adjusted(-10 - extraSpace, -10 - extraSpace, 10 + extraSpace + 1, 10 + extraSpace + 1) else: boundingRect = bounds.adjusted(-extraSpace, -extraSpace, extraSpace + 1, extraSpace + 1) elif x==MapObject.Polygon or x==MapObject.Polyline: # Make some more room for the starting dot extraSpace += self.objectLineWidth() * 4 pos = object.position() polygon = object.polygon().translated(pos) screenPolygon = self.pixelToScreenCoords_(polygon) boundingRect = screenPolygon.boundingRect().adjusted(-extraSpace, -extraSpace, extraSpace + 1, extraSpace + 1) return boundingRect
def setSize(self, *args): l = len(args) if l==1: size = args[0] self.mSize = QSizeF(size) elif l==2: width, height = args self.setSize(QSizeF(width, height))
def _toPrinterAdaptorByFloatInchSize(self, pageLayout, printerAdaptor): ''' Set my values on printerAdaptor (and whatever printer it is adapting) by setting size. Floating inch size. ''' # TODO oriented, other inch unit sizes if pageLayout.paper.value == QPageLayout.Legal: newPaperSizeInch = QSizeF(8.5, 14) elif pageLayout.paper.value == QPageLayout.Letter: newPaperSizeInch = QSizeF(8.5, 11) else: return assert newPaperSizeInch.isValid() # use overload QPrinter.setPaperSize(QPagedPaintDevice.PageSize, Units) #print("setPaperSize(Inch)", newPaperSizeInch) printerAdaptor.setPaperSize(newPaperSizeInch, QPageLayout.Inch)
def boundingRect(self, arg): tp = type(arg) if tp == QRect: rect = arg tileWidth = self.map().tileWidth() tileHeight = self.map().tileHeight() originX = int(self.map().height() * tileWidth / 2) pos = QPoint((rect.x() - (rect.y() + rect.height())) * tileWidth / 2 + originX, (rect.x() + rect.y()) * tileHeight / 2) side = rect.height() + rect.width() size = QSize(side * tileWidth / 2, side * tileHeight / 2) return QRect(pos, size) elif tp == MapObject: object = arg if (not object.cell().isEmpty()): bottomCenter = self.pixelToScreenCoords_(object.position()) tile = object.cell().tile imgSize = tile.image().size() tileOffset = tile.offset() objectSize = object.size() scale = QSizeF(objectSize.width() / imgSize.width(), objectSize.height() / imgSize.height()) return QRectF(bottomCenter.x() + (tileOffset.x() * scale.width()) - objectSize.width() / 2, bottomCenter.y() + (tileOffset.y() * scale.height()) - objectSize.height(), objectSize.width(), objectSize.height()).adjusted(-1, -1, 1, 1) elif (not object.polygon().isEmpty()): extraSpace = max(self.objectLineWidth(), 1.0) # Make some more room for the starting dot extraSpace += self.objectLineWidth() * 4 pos = object.position() polygon = object.polygon().translated(pos) screenPolygon = self.pixelToScreenCoords_(polygon) return screenPolygon.boundingRect().adjusted(-extraSpace, -extraSpace - 1, extraSpace, extraSpace) else: # Take the bounding rect of the projected object, and then add a few # pixels on all sides to correct for the line width. base = self.pixelRectToScreenPolygon(object.bounds()).boundingRect() extraSpace = max(self.objectLineWidth() / 2, 1.0) return base.adjusted(-extraSpace, -extraSpace - 1, extraSpace, extraSpace)
def __init__(self, *args): super().__init__(Object.MapObjectType) self.mPolygon = QPolygonF() self.mName = QString() self.mPos = QPointF() self.mCell = Cell() self.mType = QString() self.mId = 0 self.mShape = MapObject.Rectangle self.mObjectGroup = None self.mRotation = 0.0 self.mVisible = True l = len(args) if l==0: self.mSize = QSizeF(0, 0) elif l==4: name, _type, pos, size = args self.mName = name self.mType = _type self.mPos = pos self.mSize = QSizeF(size)
def __init__(self, width, height, parent=None): """Prepare the lines to be drawn and set up the animation Parameters ---------- width: float Width of the box height: float Height of the box parent: object Pass into QGraphicsWidget init method """ super().__init__(parent) self.width = width self.height = height self.half_circumference = width + height self.freeze = False self.setMinimumSize(QSizeF(width, height)) #self.setMaximumSize(QSizeF(width, height)) self.size_policy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) self.size_policy.setHeightForWidth(True) self.setSizePolicy(self.size_policy) # Set up a default pen for drawing self.default_pen = QPen() self.default_pen.setColor(Qt.white) self.default_pen.setWidth(5) # The 4 lines to construct the box self.left = QLineF(0, 0, 0, self.height) self.down = QLineF(0, self.height, self.width, self.height) self.right = QLineF(self.width, self.height, self.width, 0) self.up = QLineF(self.width, 0, 0, 0) self.line_order = [self.up, self.right, self.down, self.left] self.length = 0 # Set up the length to be animated self.anim = QPropertyAnimation(self, b'length') self.anim.setDuration(800) # Animation speed self.anim.setStartValue(0) for t in range(1, 10): self.anim.setKeyValueAt(t / 10, self.half_circumference * t / 10) self.anim.setEndValue(self.half_circumference)
def __init__(self, parent=None): super(VideoPlayer, self).__init__(parent) self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.videoItem = QGraphicsVideoItem() self.videoItem.setSize(QSizeF(640, 480)) scene = QGraphicsScene(self) graphicsView = QGraphicsView(scene) scene.addItem(self.videoItem) rotateSlider = QSlider(Qt.Horizontal) rotateSlider.setRange(-180, 180) rotateSlider.setValue(0) rotateSlider.valueChanged.connect(self.rotateVideo) openButton = QPushButton("Open...") openButton.clicked.connect(self.openFile) self.playButton = QPushButton() self.playButton.setEnabled(False) self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay)) self.playButton.clicked.connect(self.play) self.positionSlider = QSlider(Qt.Horizontal) self.positionSlider.setRange(0, 0) self.positionSlider.sliderMoved.connect(self.setPosition) controlLayout = QHBoxLayout() controlLayout.setContentsMargins(0, 0, 0, 0) controlLayout.addWidget(openButton) controlLayout.addWidget(self.playButton) controlLayout.addWidget(self.positionSlider) layout = QVBoxLayout() layout.addWidget(graphicsView) layout.addWidget(rotateSlider) layout.addLayout(controlLayout) self.setLayout(layout) self.mediaPlayer.setVideoOutput(self.videoItem) self.mediaPlayer.stateChanged.connect(self.mediaStateChanged) self.mediaPlayer.positionChanged.connect(self.positionChanged) self.mediaPlayer.durationChanged.connect(self.durationChanged)
def handlePaintRequest(self, printer): document = QTextDocument() document.setPageSize(QSizeF(printer.pageRect().size())) cursor = QTextCursor(document) tableFormat = QTextTableFormat() TableText = QTextCharFormat() TableText.setLayoutDirection(Qt.RightToLeft) # tableFormat.setAlignment(Qt.AlignCenter) tableFormat.setBackground(QColor('#d3fbf5')) tableFormat.setCellPadding(3) tableFormat.setCellSpacing(4) tableFormat.setLayoutDirection(Qt.RightToLeft) tableFormat.setBorderStyle(QTextTableFormat.BorderStyle_Double) TitrFormat = QTextCharFormat() fontTitr = QFont() fontTitr.setBold(True) TitrFormat.setFont(fontTitr) SotonFormat = QTextCharFormat() TitrFormat.setLayoutDirection(Qt.RightToLeft) # SotonFormat.setBackground(QColor('#EEF9C9')) SotonFormat.setFont(fontTitr) cursor.insertText(self.TableTitr + "\n", TitrFormat) model = self.ui.tableView_result.model() table = cursor.insertTable(model.rowCount() + 1, model.columnCount(), tableFormat) headers = [ 'پلاک', 'بخش', 'تعداد جلد', 'تعداد صفحات', 'نوع', 'همکار تقاضاکننده', 'تحویل گیرنده', 'علت درخواست', 'توضیحات', 'تاریخ تحویل', 'ساعت تحویل', 'تاریخ بازگشت', 'ساعت بازگشت' ] self.tableResult.insertRows(10, 10) for header in reversed(headers): cursor.insertText(header, SotonFormat) cursor.movePosition(QTextCursor.NextCell) for row in range(table.rows()): for column in reversed(range(table.columns())): cursor.insertText( self.tableResult.data(self.tableResult.index(row, column)), TableText) cursor.movePosition(QTextCursor.NextCell) cursor.movePosition(QTextCursor.NextBlock) cursor.insertText('- سامانه بایگانی ثبت ماسال -', TitrFormat) # printer.setFullPage(True) document.print_(printer)
def __init__(self, parent=None, direction=Qt.LeftToRight, node=None, icon=None, iconSize=None, **args): QGraphicsWidget.__init__(self, parent, **args) self.setAcceptedMouseButtons(Qt.NoButton) self.__direction = direction self.setLayout(QGraphicsLinearLayout(Qt.Horizontal)) # Set the maximum size, otherwise the layout can't grow beyond its # sizeHint (and we need it to grow so the widget can grow and keep the # contents centered vertically. self.layout().setMaximumSize(QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX)) self.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) self.__iconSize = iconSize or QSize(64, 64) self.__icon = icon self.__iconItem = QGraphicsPixmapItem(self) self.__iconLayoutItem = GraphicsItemLayoutItem(item=self.__iconItem) self.__channelLayout = QGraphicsGridLayout() self.__channelAnchors = [] if self.__direction == Qt.LeftToRight: self.layout().addItem(self.__iconLayoutItem) self.layout().addItem(self.__channelLayout) channel_alignemnt = Qt.AlignRight else: self.layout().addItem(self.__channelLayout) self.layout().addItem(self.__iconLayoutItem) channel_alignemnt = Qt.AlignLeft self.layout().setAlignment(self.__iconLayoutItem, Qt.AlignCenter) self.layout().setAlignment(self.__channelLayout, Qt.AlignVCenter | channel_alignemnt) if node is not None: self.setSchemeNode(node)
def boundingRect(self): """ Return the bounding rectangle size :return: QRectF """ if not self.source or not self.destination: return QRectF() pen_width = 1.0 extra = (pen_width + self.arrow_size) / 2.0 return QRectF( self.source_point, QSizeF(self.destination_point.x() - self.source_point.x(), self.destination_point.y() - self.source_point.y())).normalized().adjusted( -extra, -extra, extra, extra)
def paintEvent(self, event: QPaintEvent) -> None: if self.__image is None: super().paintEvent(event) else: painter = QPainter(self) # Draw image target_size = QSizeF(self.__image.size()) * self.__scale_factor target_rect = QRectF(QPointF(0, 0), target_size) source_rect = QRectF(self.__image.rect()) painter.drawImage(target_rect, self.__image, source_rect) # Draw lines for line_set in self.__lines: line_set.draw(painter, self.__scale_factor)
def findConnectionAt(self, pos): items = self.scene.items( QRectF(pos - QPointF(DB, DB), QSizeF(2 * DB, 2 * DB))) for c in items: if isinstance(c, Connection): points = [c.pos1] for el in c.connPoints: points.append(el) points.append(c.pos2) N = len(points) for n in range(0, N - 1): p1 = points[n] p2 = points[n + 1] rect = QRectF(p1 - QPointF(DB, DB), p2 + QPointF(DB, DB)) if rect.contains(pos): return c return None
def imprimer(self, type_imp, *args): self.fenetre.Button9.setDisabled(True) imprimante = QPrinter(QPrinter.PrinterResolution) imprimante.setDuplex(False) imprimante.setPaperSource(imprimante.Auto) imprimante.setPaperSize(QSizeF(4,6), imprimante.Inch) imprimante.setPageMargins(20.0, 60.0, 10.0, 10.0, imprimante.Millimeter) imprimante.setOrientation(imprimante.Landscape) imprimante.setColorMode(imprimante.Color) painter = QPainter() painter.begin(imprimante) police = self.fenetre.fontComboBox.currentFont() police.setPixelSize(18) painter.setFont(police) painter.drawText(0,0,imprimante.width(),imprimante.height(), Qt.AlignLeft+Qt.TextWordWrap, self.fenetre.plainTextEdit.toPlainText()) painter.end() self.fenetre.Button9.setDisabled(False)
def itemAt(self, pos): rect = QRectF(pos + QPointF(-DB, -DB), QSizeF(2 * DB, 2 * DB)) items = self.scene.items(rect) for item in items: if isinstance(self.findBlockAt(pos), Block): return item for item in items: if isinstance(self.findOutPortAt(pos), OutPort): return item for item in items: if isinstance(self.findInPortAt(pos), InPort): return (item) for item in items: if isinstance(self.findConnectionAt(pos), Connection): return (item) return None
def __init__(self, bargraph, tableWidget): super(GraphDataGenerator, self).__init__() self.m_graph = bargraph self.m_tableWidget = tableWidget self.m_graph.setBarThickness(1.0) self.m_graph.setBarSpacing(QSizeF(0.2, 0.2)) self.m_graph.setSelectionMode(QAbstract3DGraph.SelectionItemAndRow | QAbstract3DGraph.SelectionSlice) self.m_graph.activeTheme().setType(Q3DTheme.ThemeDigia) self.m_graph.activeTheme().setFont(QFont('Impact', 20)) self.m_graph.scene().activeCamera().setCameraPreset( Q3DCamera.CameraPresetFront)
def __init__(self, parent=None): QMainWindow.__init__(self, parent) # make frame self.frame = QFrame() self.centralWidget = QWidget(self) gridlayout = QGridLayout(self.centralWidget) gridlayout.setContentsMargins(0, 0, 0, 0) gridlayout.setHorizontalSpacing(0) gridlayout.setVerticalSpacing(0) self.setCentralWidget(self.centralWidget) self.left_top_panel = QVBoxLayout() self.left_btm_panel = QVBoxLayout() self.right_top_panel = QVBoxLayout() self.right_btm_panel = QVBoxLayout() gridlayout.addLayout(self.left_top_panel, 0, 0, 1, 1) gridlayout.addLayout(self.left_btm_panel, 0, 1, 1, 1) gridlayout.addLayout(self.right_top_panel, 1, 0, 1, 1) gridlayout.addLayout(self.right_btm_panel, 1, 1, 1, 1) lt_pane = ImagePane() lb_pane = ImagePane('arrow') rt_pane = ImagePane('cube') rb_pane = ImagePane('sphere') self.left_top_panel.addWidget(lt_pane.get_widget()) self.left_btm_panel.addWidget(lb_pane.get_widget()) self.right_top_panel.addWidget(rt_pane.get_widget()) self.right_btm_panel.addWidget(rb_pane.get_widget()) desktop = QDesktopWidget() screen_width = desktop.screenGeometry().width() screen_height = desktop.screenGeometry().height() self.resize((QSizeF(screen_width, screen_height)).toSize()) self.setWindowTitle('pyqt-vtk-practice') self.show() lt_pane.intial() lb_pane.intial() rt_pane.intial() rb_pane.intial() self.centralWidget.setLayout(gridlayout)
def __init__(self, rainfall): super(RainfallGraph, self).__init__() self.m_graph = rainfall self.m_mapping = None self.m_dataSet = None # In the data file the months are in numeric format, so create a custom # list. self.m_numericMonths = [str(m) for m in range(1, 12 + 1)] self.m_columnCount = len(self.m_numericMonths) self.m_years = [str(y) for y in range(2000, 2012 + 1)] self.m_rowCount = len(self.m_years) self.m_proxy = VariantBarDataProxy() series = QBar3DSeries(self.m_proxy) series.setMesh(QAbstract3DSeries.MeshCylinder) self.m_graph.addSeries(series) self.m_graph.setBarThickness(1.0) self.m_graph.setBarSpacing(QSizeF(0.2, 0.2)) self.m_graph.rowAxis().setTitle("Year") self.m_graph.columnAxis().setTitle("Month") self.m_graph.valueAxis().setTitle("rainfall") self.m_graph.valueAxis().setLabelFormat("%d mm") self.m_graph.valueAxis().setSegmentCount(5) self.m_graph.rowAxis().setLabels(self.m_years) self.m_graph.columnAxis().setLabels(self.months) self.m_graph.setShadowQuality(QAbstract3DGraph.ShadowQualityMedium) self.m_graph.setSelectionMode(QAbstract3DGraph.SelectionItemAndColumn | QAbstract3DGraph.SelectionSlice) self.m_graph.activeTheme().setType(Q3DTheme.ThemeArmyBlue) self.m_graph.activeTheme().setFont(QFont('Century Gothic', 30)) self.m_graph.activeTheme().setLabelBackgroundEnabled(False) self.m_graph.scene().activeCamera().setCameraPreset( Q3DCamera.CameraPresetIsometricRightHigh) self.m_graph.setTitle("Monthly rainfall in Northern Finland")
def resizeEvent(self, event): self.scene().setSceneRect(0, 0, event.size().width(), event.size().height()) self.player.setSize(QSizeF(event.size().width(), event.size().height())) self.bar.setGeometry(0, event.size().height() - self.bar.height(), event.size().width(), self.bar.height()) self.subtitleitem.setPos( QPointF((event.size().width() - self.subtitleitem.document().size().width()) / 2, event.size().height() - 150)) self.cc_dialog.setGeometry( event.size().width() - self.cc_dialog.width() - 30, event.size().height() - self.cc_dialog.height() - (20 + self.bar.height()), self.cc_dialog.width(), self.cc_dialog.height())
def paintEvent(self, event): background = QRadialGradient(QPointF(self.rect().topLeft()), 500, QPointF(self.rect().bottomRight())) background.setColorAt(0, self.backgroundColor1) background.setColorAt(1, self.backgroundColor2) painter = QPainter() painter.begin(self) painter.setRenderHint(QPainter.Antialiasing) painter.fillRect(event.rect(), QBrush(background)) painter.setPen(self.pen) for bubble in self.bubbles: if QRectF(bubble.position - QPointF(bubble.radius, bubble.radius), QSizeF(2 * bubble.radius, 2 * bubble.radius)).intersects( QRectF(event.rect())): bubble.drawBubble(painter) if self.newBubble: self.newBubble.drawBubble(painter) painter.end()
def Bqdy_func(self): html1 = self.Spgl_splr_ylxg.toHtml() p = QPrinterInfo.defaultPrinter() # 获取默认打印机 print_device = QPrinter(p) document = QTextDocument() lift_margin = self.Spgl_splr_pagelift_margin.text() right_margin = self.Spgl_splr_pageright_margin.text() print_device.setPageMargins(float(lift_margin), float(right_margin), 0, 0, QPrinter.Millimeter) document.setPageSize(QSizeF(print_device.pageRect().size())) document.setHtml(html1) #实现按数量打印标签 SPSL = self.Spgl_spsl.text() a = 1 while a <= int(SPSL): document.print(print_device) a = a + 1 self.Spgl_splr_ylxg.clear()
def updateResizeHandles(self): self.offset = self.resizeHandleSize * (self.scene().view().mapToScene( 1, 0) - self.scene().view().mapToScene(0, 1)).x() tmp = QRectF(QPointF(0.0, 0.0), QSizeF(self.offset, self.offset)) tmp.moveCenter(self.rect().topLeft()) self.handleTopLeft = ResizeHandle(tmp, self, cursor=Qt.SizeFDiagCursor, updateCB=self.updateTopLeft) tmp.moveCenter(self.rect().bottomRight()) self.handleBottomRight = ResizeHandle(tmp, self, cursor=Qt.SizeFDiagCursor, updateCB=self.updateBottomRight) self.handleTopLeft.setPen(Qt.red) self.handleBottomRight.setPen(Qt.red)
def mouseMoveEvent(self, event): if self.myMode == self.InsertLine and self.line: newLine = QLineF(self.line.line().p1(), event.scenePos()) self.line.setLine(newLine) elif self.myMode == self.MoveItem: super(DiagramScene, self).mouseMoveEvent(event) elif self.myMode == self.InsertItem: if self.virtualRect is None: self.virtualRect = VirtualRect() self.addItem(self.virtualRect) self.virtualRect.setPos(event.scenePos()) else: self.virtualRect.setPos(event.scenePos()) elif self.myMode == self.SelectItem: v = event.scenePos() - self.selectPoint rect = QRectF(self.selectPoint, QSizeF(v.x(), v.y())) newRect = rect.normalized() self.selectRect.setRect(newRect)
def ScalePicture(self): if self.isStripModel: self.graphicsItem.setPos(0, 0) rect = QRectF(self.graphicsItem.pos(), QSizeF( self.pixMap.size())) flags = Qt.KeepAspectRatio unity = self.graphicsView.transform().mapRect(QRectF(0, 0, 1, 1)) width = unity.width() height = unity.height() if width <= 0 or height <= 0: return self.graphicsView.scale(1 / width, 1 / height) viewRect = self.graphicsView.viewport().rect() sceneRect = self.graphicsView.transform().mapRect(rect) if sceneRect.width() <= 0 or sceneRect.height() <= 0: return x_ratio = viewRect.width() / sceneRect.width() y_ratio = viewRect.height() / sceneRect.height() if not self.isStripModel: x_ratio = y_ratio = min(x_ratio, y_ratio) else: x_ratio = y_ratio = max(x_ratio, y_ratio) # self.graphicsItem.setPos(p.x(), p.y()+height3) # self.graphicsView.move(p.x(), p.y()+height2) # self.graphicsView.move(p.x(), p.y()+height3) self.graphicsView.scale(x_ratio, y_ratio) if self.isStripModel: height2 = self.pixMap.size().height() / 2 height3 = self.graphicsView.size().height()/2 # height4 = self.graphicsView.geometry().height()/2 # height5 = self.graphicsView.frameGeometry().height()/2 height3 = height3/x_ratio # pos = height2 p = self.graphicsItem.pos() # self.graphicsItem.setPos(0, 0) self.graphicsItem.setPos(p.x(), p.y()+height2-height3) self.graphicsView.centerOn(rect.center()) for _ in range(abs(self.scaleCnt)): if self.scaleCnt > 0: self.graphicsView.scale(1.1, 1.1) else: self.graphicsView.scale(1/1.1, 1/1.1)
def print_proof(self): printer = QPrinter(96) printer.setOrientation(QPrinter.Landscape) printer.setOutputFileName('tmp.pdf') printer.setPageMargins(16, 12, 20, 12, QPrinter.Millimeter) text = "Date:\n{}\n\n".format(time.strftime("%d/%m/%Y")) text += "Address:\n{}\n\n".format(self.api.get_main_address()) text += "Current Blockhash:\n{}".format(self.api.get_actual_hash()) document = QTextDocument() document.setPageSize(QSizeF(printer.pageRect().size())) document.setDefaultFont(QFont("Arial", 30)) document.setPlainText(text) dialog = QPrintDialog() if dialog.exec_() == QDialog.Accepted: dialog.printer().setOrientation(QPrinter.Landscape) document.print_(dialog.printer())
def item_at(self, pos, type_or_tuple=None, buttons=0): """Return the item at `pos` that is an instance of the specified type (`type_or_tuple`). If `buttons` (`Qt.MouseButtons`) is given only return the item if it is the top level item that would accept any of the buttons (`QGraphicsItem.acceptedMouseButtons`). """ rect = QRectF(pos, QSizeF(1, 1)) items = self.items(rect) if buttons: items = itertools.dropwhile( lambda item: not item.acceptedMouseButtons() & buttons, items) items = list(items)[:1] if type_or_tuple: items = [i for i in items if isinstance(i, type_or_tuple)] return items[0] if items else None
def save_img(self, img_fpath): if img_fpath.endswith('.png'): self.image.save(img_fpath, 'png') else: assert img_fpath.endswith('.pdf') w, h = self.canvasSize printer = QPrinter(QPrinter.HighResolution) printer.setPageSizeMM(QSizeF(w / 15, h / 15)) printer.setFullPage(True) printer.setPageMargins(0.0, 0.0, 0.0, 0.0, QPrinter.Millimeter) printer.setColorMode(QPrinter.Color) printer.setOutputFormat(QPrinter.PdfFormat) printer.setOutputFileName(img_fpath) pixmap = self.grab().scaledToHeight( printer.pageRect( QPrinter.DevicePixel).size().toSize().height() * 2) painter = QPainter(printer) painter.drawPixmap(0, 0, pixmap) painter.end()
def Print_clicked(self): try: #self.printer.setPageMargins(3,3,3,3,QPrinter.Millimeter) page_size = QSizeF() page_size.setHeight(self.printer.height()) page_size.setWidth(self.printer.width()) text_document = self.ui.plainTextEdit.document().clone() text_document.setPageSize(page_size) text_document.setDocumentMargin(0.0) text_document.print(self.printer) except Exception as err: self._process_error(err)
def render_drop_shadow_frame(pixmap, shadow_rect, shadow_color, offset, radius, rect_fill_color): pixmap.fill(QColor(0, 0, 0, 0)) scene = QGraphicsScene() rect = QGraphicsRectItem(shadow_rect) rect.setBrush(QColor(rect_fill_color)) rect.setPen(QPen(Qt.NoPen)) scene.addItem(rect) effect = QGraphicsDropShadowEffect(color=shadow_color, blurRadius=radius, offset=offset) rect.setGraphicsEffect(effect) scene.setSceneRect(QRectF(QPointF(0, 0), QSizeF(pixmap.size()))) painter = QPainter(pixmap) scene.render(painter) painter.end() scene.clear() scene.deleteLater() return pixmap
def exportToPDF(self, path=None): if path is None: desktop = QStandardPaths.standardLocations( QStandardPaths.DesktopLocation) path = os.path.join(desktop[0], "metricsWindow.pdf") printer = QPrinter(QPrinter.ScreenResolution) printer.setOutputFileName(path) printer.setOutputFormat(QPrinter.PdfFormat) printer.setFullPage(True) printer.setPaperSize(QSizeF(self.size()), QPrinter.DevicePixel) painter = QPainter() painter.begin(printer) painter.setRenderHint(QPainter.Antialiasing) if self._rightToLeft: self.paintRightToLeft(painter, self.geometry()) else: self.paintLeftToRight(painter, self.geometry()) painter.end()
def resizePixmap(self, sz): # https://github.com/linuxdeepin/dtkwidget/blob/master/src/widgets/dwaterprogress.cpp#L192 # resize water waterWidth = 500 * sz.width() / 100 waterHeight = 110 * sz.height() / 100 waterSize = QSizeF(waterWidth, waterHeight).toSize() if self.waterFrontImage.size() != waterSize: image = QImage(waterWidth, waterHeight, QImage.Format_ARGB32) image.fill(Qt.transparent) waterPainter = QPainter(image) self.waterFrontSvg.render(waterPainter) self.waterFrontImage = image if self.waterBackImage.size() != waterSize: image = QImage(waterWidth, waterHeight, QImage.Format_ARGB32) image.fill(Qt.transparent) # partly transparent red-ish background waterPainter = QPainter(image) self.waterBackSvg.render(waterPainter) self.waterBackImage = image
def save_widget_icon( background, icon: str, outname: str, export_size=QSize(100, 100), format="png", ): # create fake windget and category descriptions widget_description = WidgetDescription("", "", icon=icon, qualified_name="orangecanvas") category = CategoryDescription(background=background) item = NodeItem(widget_description) item.setWidgetCategory(category) iconItem = item.icon_item shapeItem = item.shapeItem shapeSize = export_size iconSize = QSize(export_size.width() * 3 / 4, export_size.height() * 3 / 4) rect = QRectF(QPointF(-shapeSize.width() / 2, -shapeSize.height() / 2), QSizeF(shapeSize)) shapeItem.setShapeRect(rect) iconItem.setIconSize(iconSize) iconItem.setPos(-iconSize.width() / 2, -iconSize.height() / 2) image = QImage(export_size, QImage.Format_ARGB32) image.fill(QColor("#00FFFFFF")) painter = QPainter(image) painter.setRenderHint(QPainter.Antialiasing, 1) scene = QGraphicsScene() scene.addItem(shapeItem) scene.render(painter, QRectF(image.rect()), scene.sceneRect()) painter.end() if not image.save(outname, format, 80): print("Failed to save " + outname)
def insertBoundingRectangle(self, pos): print("Inserting item at {} {}".format(pos.x(), pos.y())) defaultWidth = 0.05 * self.pixmapItem.pixmap().width() defaultHeight = 0.05 * self.pixmapItem.pixmap().height() rect = QRectF(QPointF(), QSizeF(defaultWidth, defaultHeight)) rect.moveCenter(pos) label = self.dialogGetLabel() if label is not None: rectItem = RectangleLabelItem(rect=rect, parent=self.pixmapItem, label=label) if label not in self.labelsCache: self.labelsCache.append(label) print("Labels cache is now {}".format(self.labelsCache)) self.emitLabelsChanged()
def getLinePoint(self, end): #rect = QRectF(self.pos(), QPoint(self.pos().x()+120, self.pos().y()+60)) rect = QRectF(self.pos(), QSizeF(120, 60)) #calculate center points left = QPointF(rect.topLeft().x(), rect.center().y()) right = QPointF(rect.bottomRight().x(), rect.center().y()) top = QPointF(rect.center().x(), rect.topLeft().y()) bottom = QPointF(rect.center().x(), rect.bottomRight().y()) if rect.topLeft().x() < end.x(): #point is not left from rect if rect.bottomRight().x() < end.x(): y1 = GeoHelper.getY(-1, rect.bottomRight().x(), rect.topLeft().y(), end.x()) if end.y() < y1: return "top", top y1 = GeoHelper.getY(1, rect.bottomRight().x(), rect.bottomRight().y(), end.x()) if end.y() < y1: return "right", right return "bottom", bottom elif rect.center().y() < end.y(): return "bottom", bottom else: return "top", top else: #point is left from rect y1 = GeoHelper.getY(1, rect.topLeft().x(), rect.topLeft().y(), end.x()) if end.y() < y1: return "top", top y1 = GeoHelper.getY(-1, rect.topLeft().x(), rect.bottomRight().y(), end.x()) if end.y() < y1: return "left", left return "bottom", bottom
def __init__(self, parent=None): super().__init__(parent) #调用父类构造函数,创建窗体 self.ui = Ui_MainWindow() #创建UI对象 self.ui.setupUi(self) #构造UI界面 self.player = QMediaPlayer(self) #创建视频播放器 self.player.setNotifyInterval(1000) #信息更新周期, ms scene = QGraphicsScene(self) self.ui.graphicsView.setScene(scene) self.videoItem = QGraphicsVideoItem() #视频显示画面 self.videoItem.setSize(QSizeF(320, 220)) self.videoItem.setFlag(QGraphicsItem.ItemIsMovable) self.videoItem.setFlag(QGraphicsItem.ItemIsSelectable) self.videoItem.setFlag(QGraphicsItem.ItemIsFocusable) scene.addItem(self.videoItem) self.player.setVideoOutput(self.videoItem) #设置视频显示图形项 self.textItem = QGraphicsTextItem("面朝大海,春暖花开") #弹幕文字 font = self.textItem.font() font.setPointSize(20) self.textItem.setFont(font) self.textItem.setDefaultTextColor(Qt.red) self.textItem.setPos(100, 220) self.textItem.setFlag(QGraphicsItem.ItemIsMovable) self.textItem.setFlag(QGraphicsItem.ItemIsSelectable) self.textItem.setFlag(QGraphicsItem.ItemIsFocusable) scene.addItem(self.textItem) self.ui.btnText.setCheckable(True) #弹幕文字按钮 self.ui.btnText.setChecked(True) self.__duration = "" self.__curPos = "" self.player.stateChanged.connect(self.do_stateChanged) self.player.positionChanged.connect(self.do_positionChanged) self.player.durationChanged.connect(self.do_durationChanged)
def add_svg_ann(layerId, path, feature, parent): QgsMessageLog.logMessage('layerId: ' + layerId + ', path: ' + path, 'Lanzen', level=Qgis.Info) currentLayer = QgsProject.instance().mapLayer(layerId) svgAnnotation = QgsSvgAnnotation(iface.mapCanvas()) svgAnnotation.setMapLayer(currentLayer) symbol = QgsMarkerSymbol() symbol.setSize(0) svgAnnotation.setMarkerSymbol(symbol) svgAnnotation.setHasFixedMapPosition(True) svgAnnotation.setMapPosition(feature.geometry().asPoint()) svgAnnotation.setFrameSize(QSizeF(80, 64)) svgAnnotation.setFilePath(path) QgsProject.instance().annotationManager().addAnnotation(svgAnnotation) # If caching is enabled, a simple canvas refresh might not be sufficient # to trigger a redraw and you must clear the cached image for the layer if iface.mapCanvas().isCachingEnabled(): currentLayer.triggerRepaint() else: iface.mapCanvas().refresh() return
def drawMapObject(self, painter, object, color): painter.save() pen = QPen(Qt.black) pen.setCosmetic(True) cell = object.cell() if (not cell.isEmpty()): tile = cell.tile imgSize = tile.size() pos = self.pixelToScreenCoords_(object.position()) tileOffset = tile.offset() CellRenderer(painter).render(cell, pos, object.size(), CellRenderer.BottomCenter) if (self.testFlag(RenderFlag.ShowTileObjectOutlines)): rect = QRectF(QPointF(pos.x() - imgSize.width() / 2 + tileOffset.x(), pos.y() - imgSize.height() + tileOffset.y()), QSizeF(imgSize)) pen.setStyle(Qt.SolidLine) painter.setPen(pen) painter.drawRect(rect) pen.setStyle(Qt.DotLine) pen.setColor(color) painter.setPen(pen) painter.drawRect(rect) else: lineWidth = self.objectLineWidth() scale = self.painterScale() x = 1 if lineWidth != 0: x = lineWidth shadowOffset = x / scale brushColor = QColor(color) brushColor.setAlpha(50) brush = QBrush(brushColor) pen.setJoinStyle(Qt.RoundJoin) pen.setCapStyle(Qt.RoundCap) pen.setWidth(lineWidth) colorPen = QPen(pen) colorPen.setColor(color) painter.setPen(pen) painter.setRenderHint(QPainter.Antialiasing) # TODO: Do something sensible to make null-sized objects usable x = object.shape() if x==MapObject.Ellipse: polygon = self.pixelRectToScreenPolygon(object.bounds()) tw = self.map().tileWidth() th = self.map().tileHeight() transformScale = QPointF(1, 1) if (tw > th): transformScale = QPointF(1, th/tw) else: transformScale = QPointF(tw/th, 1) l1 = polygon.at(1) - polygon.at(0) l2 = polygon.at(3) - polygon.at(0) trans = QTransform() trans.scale(transformScale.x(), transformScale.y()) trans.rotate(45) iTrans, ok = trans.inverted() l1x = iTrans.map(l1) l2x = iTrans.map(l2) ellipseSize = QSizeF(l1x.manhattanLength(), l2x.manhattanLength()) if (ellipseSize.width() > 0 and ellipseSize.height() > 0): painter.save() painter.setPen(pen) painter.translate(polygon.at(0)) painter.scale(transformScale.x(), transformScale.y()) painter.rotate(45) painter.drawEllipse(QRectF(QPointF(0, 0), ellipseSize)) painter.restore() painter.setBrush(Qt.NoBrush) painter.drawPolygon(polygon) painter.setPen(colorPen) painter.setBrush(Qt.NoBrush) painter.translate(QPointF(0, -shadowOffset)) painter.drawPolygon(polygon) painter.setBrush(brush) if (ellipseSize.width() > 0 and ellipseSize.height() > 0): painter.save() painter.translate(polygon.at(0)) painter.scale(transformScale.x(), transformScale.y()) painter.rotate(45) painter.drawEllipse(QRectF(QPointF(0, 0), ellipseSize)) painter.restore() elif x==MapObject.Rectangle: polygon = self.pixelRectToScreenPolygon(object.bounds()) painter.drawPolygon(polygon) painter.setPen(colorPen) painter.setBrush(brush) polygon.translate(0, -shadowOffset) painter.drawPolygon(polygon) elif x==MapObject.Polygon: pos = object.position() polygon = object.polygon().translated(pos) screenPolygon = self.pixelToScreenCoords_(polygon) thickPen = QPen(pen) thickColorPen = QPen(colorPen) thickPen.setWidthF(thickPen.widthF() * 4) thickColorPen.setWidthF(thickColorPen.widthF() * 4) painter.drawPolygon(screenPolygon) painter.setPen(thickPen) painter.drawPoint(screenPolygon.first()) painter.setPen(colorPen) painter.setBrush(brush) screenPolygon.translate(0, -shadowOffset) painter.drawPolygon(screenPolygon) painter.setPen(thickColorPen) painter.drawPoint(screenPolygon.first()) elif x==MapObject.Polyline: pos = object.position() polygon = object.polygon().translated(pos) screenPolygon = self.pixelToScreenCoords_(polygon) thickPen = QPen(pen) thickColorPen = QPen(colorPen) thickPen.setWidthF(thickPen.widthF() * 4) thickColorPen.setWidthF(thickColorPen.widthF() * 4) painter.drawPolyline(screenPolygon) painter.setPen(thickPen) painter.drawPoint(screenPolygon.first()) painter.setPen(colorPen) screenPolygon.translate(0, -shadowOffset) painter.drawPolyline(screenPolygon) painter.setPen(thickColorPen) painter.drawPoint(screenPolygon.first()) painter.restore()
class MapObject(Object): ## # Enumerates the different object shapes. Rectangle is the default shape. # When a polygon is set, the shape determines whether it should be # interpreted as a filled polygon or a line. ## Rectangle, Polygon, Polyline, Ellipse = range(4) def __init__(self, *args): super().__init__(Object.MapObjectType) self.mPolygon = QPolygonF() self.mName = QString() self.mPos = QPointF() self.mCell = Cell() self.mType = QString() self.mId = 0 self.mShape = MapObject.Rectangle self.mObjectGroup = None self.mRotation = 0.0 self.mVisible = True l = len(args) if l==0: self.mSize = QSizeF(0, 0) elif l==4: name, _type, pos, size = args self.mName = name self.mType = _type self.mPos = pos self.mSize = QSizeF(size) ## # Returns the id of this object. Each object gets an id assigned that is # unique for the map the object is on. ## def id(self): return self.mId ## # Sets the id of this object. ## def setId(self, id): self.mId = id ## # Returns the name of this object. The name is usually just used for # identification of the object in the editor. ## def name(self): return self.mName ## # Sets the name of this object. ## def setName(self, name): self.mName = name ## # Returns the type of this object. The type usually says something about # how the object is meant to be interpreted by the engine. ## def type(self): return self.mType ## # Sets the type of this object. ## def setType(self, type): self.mType = type ## # Returns the position of this object. ## def position(self): return QPointF(self.mPos) ## # Sets the position of this object. ## def setPosition(self, pos): self.mPos = pos ## # Returns the x position of this object. ## def x(self): return self.mPos.x() ## # Sets the x position of this object. ## def setX(self, x): self.mPos.setX(x) ## # Returns the y position of this object. ## def y(self): return self.mPos.y() ## # Sets the x position of this object. ## def setY(self, y): self.mPos.setY(y) ## # Returns the size of this object. ## def size(self): return self.mSize ## # Sets the size of this object. ## def setSize(self, *args): l = len(args) if l==1: size = args[0] self.mSize = QSizeF(size) elif l==2: width, height = args self.setSize(QSizeF(width, height)) ## # Returns the width of this object. ## def width(self): return self.mSize.width() ## # Sets the width of this object. ## def setWidth(self, width): self.mSize.setWidth(width) ## # Returns the height of this object. ## def height(self): return self.mSize.height() ## # Sets the height of this object. ## def setHeight(self, height): self.mSize.setHeight(height) ## # Sets the polygon associated with this object. The polygon is only used # when the object shape is set to either Polygon or Polyline. # # \sa setShape() ## def setPolygon(self, polygon): self.mPolygon = polygon ## # Returns the polygon associated with this object. Returns an empty # polygon when no polygon is associated with this object. ## def polygon(self): return QPolygonF(self.mPolygon) ## # Sets the shape of the object. ## def setShape(self, shape): self.mShape = shape ## # Returns the shape of the object. ## def shape(self): return self.mShape ## # Shortcut to getting a QRectF from position() and size(). ## def bounds(self): return QRectF(self.mPos, self.mSize) ## # Shortcut to getting a QRectF from position() and size() that uses cell tile if present. ## def boundsUseTile(self): if (self.mCell.isEmpty()): # No tile so just use regular bounds return self.bounds() # Using the tile for determing boundary # Note the position given is the bottom-left corner so correct for that return QRectF(QPointF(self.mPos.x(), self.mPos.y() - self.mCell.tile.height()), self.mCell.tile.size()) ## # Sets the tile that is associated with this object. The object will # display as the tile image. # # \warning The object shape is ignored for tile objects! ## def setCell(self, cell): self.mCell = cell ## # Returns the tile associated with this object. ## def cell(self): return self.mCell ## # Returns the object group this object belongs to. ## def objectGroup(self): return self.mObjectGroup ## # Sets the object group this object belongs to. Should only be called # from the ObjectGroup class. ## def setObjectGroup(self, objectGroup): self.mObjectGroup = objectGroup ## # Returns the rotation of the object in degrees. ## def rotation(self): return self.mRotation ## # Sets the rotation of the object in degrees. ## def setRotation(self, rotation): self.mRotation = rotation ## # This is somewhat of a workaround for dealing with the ways different objects # align. # # Traditional rectangle objects have top-left alignment. # Tile objects have bottom-left alignment on orthogonal maps, but # bottom-center alignment on isometric maps. # # Eventually, the object alignment should probably be configurable. For # backwards compatibility, it will need to be configurable on a per-object # level. ## def alignment(self): if (self.mCell.isEmpty()): return Alignment.TopLeft elif (self.mObjectGroup): map = self.mObjectGroup.map() if map: if (map.orientation() == Map.Orientation.Isometric): return Alignment.Bottom return Alignment.BottomLeft def isVisible(self): return self.mVisible def setVisible(self, visible): self.mVisible = visible ## # Flip this object in the given \a direction. This doesn't change the size # of the object. ## def flip(self, direction): if (not self.mCell.isEmpty()): if (direction == FlipDirection.FlipHorizontally): self.mCell.flippedHorizontally = not self.mCell.flippedHorizontally elif (direction == FlipDirection.FlipVertically): self.mCell.flippedVertically = not self.mCell.flippedVertically if (not self.mPolygon.isEmpty()): center2 = self.mPolygon.boundingRect().center() * 2 if (direction == FlipDirection.FlipHorizontally): for i in range(self.mPolygon.size()): # oh, QPointF mPolygon returned is a copy of internal object self.mPolygon[i] = QPointF(center2.x() - self.mPolygon[i].x(), self.mPolygon[i].y()) elif (direction == FlipDirection.FlipVertically): for i in range(self.mPolygon.size()): self.mPolygon[i] = QPointF(self.mPolygon[i].x(), center2.y() - self.mPolygon[i].y()) ## # Returns a duplicate of this object. The caller is responsible for the # ownership of this newly created object. ## def clone(self): o = MapObject(self.mName, self.mType, self.mPos, self.mSize) o.setProperties(self.properties()) o.setPolygon(self.mPolygon) o.setShape(self.mShape) o.setCell(self.mCell) o.setRotation(self.mRotation) return o
def render(self, cell, pos, cellSize, origin): if (self.mTile != cell.tile): self.flush() image = cell.tile.currentFrameImage() size = image.size() if cellSize == QSizeF(0,0): objectSize = size else: objectSize = cellSize scale = QSizeF(objectSize.width() / size.width(), objectSize.height() / size.height()) offset = cell.tile.offset() sizeHalf = QPointF(objectSize.width() / 2, objectSize.height() / 2) fragment = QPainter.PixmapFragment() fragment.x = pos.x() + (offset.x() * scale.width()) + sizeHalf.x() fragment.y = pos.y() + (offset.y() * scale.height()) + sizeHalf.y() - objectSize.height() fragment.sourceLeft = 0 fragment.sourceTop = 0 fragment.width = size.width() fragment.height = size.height() if cell.flippedHorizontally: fragment.scaleX = -1 else: fragment.scaleX = 1 if cell.flippedVertically: fragment.scaleY = -1 else: fragment.scaleY = 1 fragment.rotation = 0 fragment.opacity = 1 flippedHorizontally = cell.flippedHorizontally flippedVertically = cell.flippedVertically if (origin == CellRenderer.BottomCenter): fragment.x -= sizeHalf.x() if (cell.flippedAntiDiagonally): fragment.rotation = 90 flippedHorizontally = cell.flippedVertically flippedVertically = not cell.flippedHorizontally # Compensate for the swap of image dimensions halfDiff = sizeHalf.y() - sizeHalf.x() fragment.y += halfDiff if (origin != CellRenderer.BottomCenter): fragment.x += halfDiff if flippedHorizontally: x = -1 else: x = 1 fragment.scaleX = scale.width() * x if flippedVertically: x = -1 else: x = 1 fragment.scaleY = scale.height() * x if (self.mIsOpenGL or (fragment.scaleX > 0 and fragment.scaleY > 0)): self.mTile = cell.tile self.mFragments.append(fragment) return # The Raster paint engine as of Qt 4.8.4 / 5.0.2 does not support # drawing fragments with a negative scaling factor. self.flush() # make sure we drew all tiles so far oldTransform = self.mPainter.transform() transform = oldTransform transform.translate(fragment.x, fragment.y) transform.rotate(fragment.rotation) transform.scale(fragment.scaleX, fragment.scaleY) target = QRectF(fragment.width * -0.5, fragment.height * -0.5, fragment.width, fragment.height) source = QRectF(0, 0, fragment.width, fragment.height) self.mPainter.setTransform(transform) self.mPainter.drawPixmap(target, image, source) self.mPainter.setTransform(oldTransform)
def load(self, path): if path == self._path: return self._path = path with open(os.path.join(self._path, "theme.json")) as f: Logger.log("d", "Loading theme file: %s", os.path.join(self._path, "theme.json")) data = json.load(f) self._initializeDefaults() if "colors" in data: for name, color in data["colors"].items(): c = QColor(color[0], color[1], color[2], color[3]) self._colors[name] = c fontsdir = os.path.join(self._path, "fonts") if os.path.isdir(fontsdir): for file in os.listdir(fontsdir): if "ttf" in file: QFontDatabase.addApplicationFont(os.path.join(fontsdir, file)) if "fonts" in data: for name, font in data["fonts"].items(): f = QFont() f.setFamily(font.get("family", QCoreApplication.instance().font().family())) f.setBold(font.get("bold", False)) f.setLetterSpacing(QFont.AbsoluteSpacing, font.get("letterSpacing", 0)) f.setItalic(font.get("italic", False)) f.setPixelSize(font.get("size", 1) * self._em_height) f.setCapitalization(QFont.AllUppercase if font.get("capitalize", False) else QFont.MixedCase) self._fonts[name] = f if "sizes" in data: for name, size in data["sizes"].items(): s = QSizeF() s.setWidth(round(size[0] * self._em_width)) s.setHeight(round(size[1] * self._em_height)) self._sizes[name] = s iconsdir = os.path.join(self._path, "icons") if os.path.isdir(iconsdir): for icon in os.listdir(iconsdir): name = os.path.splitext(icon)[0] self._icons[name] = QUrl.fromLocalFile(os.path.join(iconsdir, icon)) imagesdir = os.path.join(self._path, "images") if os.path.isdir(imagesdir): for image in os.listdir(imagesdir): name = os.path.splitext(image)[0] self._images[name] = QUrl.fromLocalFile(os.path.join(imagesdir, image)) styles = os.path.join(self._path, "styles.qml") if os.path.isfile(styles): c = QQmlComponent(self._engine, styles) context = QQmlContext(self._engine, self._engine) context.setContextProperty("Theme", self) self._styles = c.create(context) if c.isError(): for error in c.errors(): Logger.log("e", error.toString()) Logger.log("d", "Loaded theme %s", self._path) self.themeLoaded.emit()
def updateResizingSingleItem(self, resizingOrigin, screenPos, modifiers): renderer = self.mapDocument().renderer() object = self.mMovingObjects.first() mapObject = object.item.mapObject() ## The resizingOrigin, screenPos and mStart are affected by the ObjectGroup # offset. We will un-apply it to these variables since the resize for # single items happens in local coordinate space. ## offset = mapObject.objectGroup().offset() ## These transformations undo and redo the object rotation, which is always # applied in screen space. ## unrotate = rotateAt(object.oldItemPosition, -object.oldRotation) rotate = rotateAt(object.oldItemPosition, object.oldRotation) origin = (resizingOrigin - offset) * unrotate pos = (screenPos - offset) * unrotate start = (self.mStart - offset) * unrotate oldPos = object.oldItemPosition ## In order for the resizing to work somewhat sanely in isometric mode, # the resizing is performed in pixel space except for tile objects, which # are not affected by isometric projection apart from their position. ## pixelSpace = resizeInPixelSpace(mapObject) preserveAspect = modifiers & Qt.ControlModifier if (pixelSpace): origin = renderer.screenToPixelCoords_(origin) pos = renderer.screenToPixelCoords_(pos) start = renderer.screenToPixelCoords_(start) oldPos = object.oldPosition newPos = oldPos newSize = object.oldSize ## In case one of the anchors was used as-is, the desired size can be # derived directly from the distance from the origin for rectangle # and ellipse objects. This allows scaling up a 0-sized object without # dealing with infinite scaling factor issues. # # For obvious reasons this can't work on polygons or polylines, nor when # preserving the aspect ratio. ## if (self.mClickedResizeHandle.resizingOrigin() == resizingOrigin and (mapObject.shape() == MapObject.Rectangle or mapObject.shape() == MapObject.Ellipse) and not preserveAspect): newBounds = QRectF(newPos, newSize) newBounds = align(newBounds, mapObject.alignment()) x = self.mClickedResizeHandle.anchorPosition() if x==AnchorPosition.LeftAnchor or x==AnchorPosition.TopLeftAnchor or x==AnchorPosition.BottomLeftAnchor: newBounds.setLeft(min(pos.x(), origin.x())) elif x==AnchorPosition.RightAnchor or x==AnchorPosition.TopRightAnchor or x==AnchorPosition.BottomRightAnchor: newBounds.setRight(max(pos.x(), origin.x())) else: # nothing to do on this axis pass x = self.mClickedResizeHandle.anchorPosition() if x==AnchorPosition.TopAnchor or x==AnchorPosition.TopLeftAnchor or x==AnchorPosition.TopRightAnchor: newBounds.setTop(min(pos.y(), origin.y())) elif x==AnchorPosition.BottomAnchor or x==AnchorPosition.BottomLeftAnchor or x==AnchorPosition.BottomRightAnchor: newBounds.setBottom(max(pos.y(), origin.y())) else: # nothing to do on this axis pass newBounds = unalign(newBounds, mapObject.alignment()) newSize = newBounds.size() newPos = newBounds.topLeft() else: relPos = pos - origin startDiff = start - origin try: newx = relPos.x() / startDiff.x() except: newx = 0 try: newy = relPos.y() / startDiff.y() except: newy = 0 scalingFactor = QSizeF(max(0.01, newx), max(0.01, newy)) if not math.isfinite(scalingFactor.width()): scalingFactor.setWidth(1) if not math.isfinite(scalingFactor.height()): scalingFactor.setHeight(1) if (self.mResizingLimitHorizontal): if preserveAspect: scalingFactor.setWidth(scalingFactor.height()) else: scalingFactor.setWidth(1) elif (self.mResizingLimitVertical): if preserveAspect: scalingFactor.setHeight(scalingFactor.width()) else: scalingFactor.setHeight(1) elif (preserveAspect): scale = min(scalingFactor.width(), scalingFactor.height()) scalingFactor.setWidth(scale) scalingFactor.setHeight(scale) oldRelPos = oldPos - origin newPos = origin + QPointF(oldRelPos.x() * scalingFactor.width(), oldRelPos.y() * scalingFactor.height()) newSize.setWidth(newSize.width() * scalingFactor.width()) newSize.setHeight(newSize.height() * scalingFactor.height()) if (not object.oldPolygon.isEmpty()): newPolygon = QPolygonF(object.oldPolygon.size()) for n in range(object.oldPolygon.size()): point = object.oldPolygon[n] newPolygon[n] = QPointF(point.x() * scalingFactor.width(), point.y() * scalingFactor.height()) mapObject.setPolygon(newPolygon) if (pixelSpace): newPos = renderer.pixelToScreenCoords_(newPos) newPos = renderer.screenToPixelCoords_(newPos * rotate) mapObject.setSize(newSize) mapObject.setPosition(newPos) self.mapDocument().mapObjectModel().emitObjectsChanged(self.changingObjects())
def load(self, path): self._path = path with open(os.path.join(self._path, "theme.json")) as f: data = json.load(f) self._initializeDefaults() if "colors" in data: for name, color in data["colors"].items(): c = QColor(color[0], color[1], color[2], color[3]) self._colors[name] = c fontsdir = os.path.join(self._path, "fonts") if os.path.isdir(fontsdir): for file in os.listdir(fontsdir): if "ttf" in file: QFontDatabase.addApplicationFont(os.path.join(fontsdir, file)) if "fonts" in data: for name, font in data["fonts"].items(): f = QFont() if not sys.platform == "win32": # Excluding windows here as a workaround for bad font rendering f.setFamily(font.get("family", QCoreApplication.instance().font().family())) f.setStyleName(font.get("style", "Regular")) f.setBold(font.get("bold", False)) f.setItalic(font.get("italic", False)) f.setPixelSize(font.get("size", 1) * self._em_height) f.setCapitalization(QFont.AllUppercase if font.get("capitalize", False) else QFont.MixedCase) self._fonts[name] = f if "sizes" in data: for name, size in data["sizes"].items(): s = QSizeF() s.setWidth(size[0] * self._em_width) s.setHeight(size[1] * self._em_height) self._sizes[name] = s styles = os.path.join(self._path, "styles.qml") if os.path.isfile(styles): c = QQmlComponent(self._engine, styles) self._styles = c.create() if c.isError(): for error in c.errors(): Logger.log("e", error.toString()) iconsdir = os.path.join(self._path, "icons") if os.path.isdir(iconsdir): for icon in os.listdir(iconsdir): name = os.path.splitext(icon)[0] self._icons[name] = QUrl.fromLocalFile(os.path.join(iconsdir, icon)) imagesdir = os.path.join(self._path, "images") if os.path.isdir(imagesdir): for image in os.listdir(imagesdir): name = os.path.splitext(image)[0] self._images[name] = QUrl.fromLocalFile(os.path.join(imagesdir, image)) Logger.log("d", "Loaded theme %s", self._path) self.themeLoaded.emit()
def load(self, path: str, is_first_call: bool = True) -> None: if path == self._path: return with open(os.path.join(path, "theme.json"), encoding = "utf-8") as f: Logger.log("d", "Loading theme file: %s", os.path.join(path, "theme.json")) data = json.load(f) # Iteratively load inherited themes try: theme_id = data["metadata"]["inherits"] self.load(Resources.getPath(Resources.Themes, theme_id), is_first_call = False) except FileNotFoundError: Logger.log("e", "Could not find inherited theme %s", theme_id) except KeyError: pass # No metadata or no inherits keyword in the theme.json file if "colors" in data: for name, color in data["colors"].items(): c = QColor(color[0], color[1], color[2], color[3]) self._colors[name] = c fonts_dir = os.path.join(path, "fonts") if os.path.isdir(fonts_dir): for file in os.listdir(fonts_dir): if "ttf" in file: QFontDatabase.addApplicationFont(os.path.join(fonts_dir, file)) if "fonts" in data: system_font_size = QCoreApplication.instance().font().pointSize() for name, font in data["fonts"].items(): q_font = QFont() q_font.setFamily(font.get("family", QCoreApplication.instance().font().family())) if font.get("bold"): q_font.setBold(font.get("bold", False)) else: q_font.setWeight(font.get("weight", 50)) q_font.setLetterSpacing(QFont.AbsoluteSpacing, font.get("letterSpacing", 0)) q_font.setItalic(font.get("italic", False)) q_font.setPointSize(int(font.get("size", 1) * system_font_size)) q_font.setCapitalization(QFont.AllUppercase if font.get("capitalize", False) else QFont.MixedCase) self._fonts[name] = q_font if "sizes" in data: for name, size in data["sizes"].items(): s = QSizeF() s.setWidth(round(size[0] * self._em_width)) s.setHeight(round(size[1] * self._em_height)) self._sizes[name] = s iconsdir = os.path.join(path, "icons") if os.path.isdir(iconsdir): for icon in os.listdir(iconsdir): name = os.path.splitext(icon)[0] self._icons[name] = QUrl.fromLocalFile(os.path.join(iconsdir, icon)) imagesdir = os.path.join(path, "images") if os.path.isdir(imagesdir): for image in os.listdir(imagesdir): name = os.path.splitext(image)[0] self._images[name] = QUrl.fromLocalFile(os.path.join(imagesdir, image)) styles = os.path.join(path, "styles.qml") if os.path.isfile(styles): c = QQmlComponent(self._engine, styles) context = QQmlContext(self._engine, self._engine) context.setContextProperty("Theme", self) self._styles = c.create(context) if c.isError(): for error in c.errors(): Logger.log("e", error.toString()) Logger.log("d", "Loaded theme %s", path) self._path = path # only emit the theme loaded signal once after all the themes in the inheritance chain have been loaded if is_first_call: self.themeLoaded.emit()