def printpdf(self, html): url = self.url().toString() pdfName = str(int(round(time.time() * 1000))) + ".pdf" print('save [%d bytes %s] to [%s]' % (len(html), url, pdfName)) self.printToPdf( pdfName, QtGui.QPageLayout(QtGui.QPageSize(QtGui.QPageSize.A4), QtGui.QPageLayout.Portrait, QtCore.QMarginsF(0, 0, 0, 0)))
def do_export_pdf(self): pdf_file = '%s.pdf' % self.title() filename = QtWidgets.QFileDialog.getSaveFileName( self, self.tr('export PDF as ...'), pdf_file, 'PDF files (*.pdf)', ) if isinstance(filename, tuple): filename = filename[0] if filename: pageLayout = QtGui.QPageLayout(QtGui.QPageSize(QtGui.QPageSize.A4), QtGui.QPageLayout.Portrait, QtCore.QMarginsF(15, 15, 15, 15), QtGui.QPageLayout.Millimeter) self.page().printToPdf(filename, pageLayout)
def nearestSnaps(self, snap_dist, excludePt=None): '''Return a list of (equally) closest snap-tuples, in scene coordinates. Parameters are in scene coordinates. Returned tuples are (distance squared, QPointF p from self, QPointF q from other) ''' # This never seems to take more than a couple dozen ms, but nevertheless # performance is very sluggish, because Qt5 sends all mouse events # without compression no matter how long it takes to respond. search_timer = QtCore.QElapsedTimer() search_timer.start() snap_margins = QtCore.QMarginsF(snap_dist * 1.001, snap_dist * 1.001, snap_dist * 1.001, snap_dist * 1.001) nearest_dist2 = snap_dist**2 # Use squared distances to avoid calling sqrt nearest = [] # list of nearby pairs of points # It's distinctly faster to let QGraphicsScene compare each child tile with # other tiles than to ask it to compare all child points with other tiles, # though this still ends up O(n*n) when dragging many tiles over many tiles. for child in self.childItems(): snap_search_rect = child.sceneBoundingRect().marginsAdded( snap_margins) nearby_items = self.scene().items(snap_search_rect) nearby_tiles = [ it for it in nearby_items if hasattr(it, "sceneSnapPoints") and not it.isSelected() ] if nearby_tiles: self._log.trace('{} nearby tiles', len(nearby_tiles)) for other_tile in nearby_tiles: for p in child.sceneSnapPoints(): assert isinstance(p, QtCore.QPointF) if excludePt is None or QtCore.QLineF( p, excludePt).length() > snap_dist / 100.0: for q in other_tile.sceneSnapPoints(): assert isinstance(q, QtCore.QPointF) if excludePt is None or QtCore.QLineF( q, excludePt).length( ) > snap_dist / 100.0: pq = q - p pq2 = pq.x()**2 + pq.y()**2 if pq2 <= nearest_dist2: #assert pq.x() <= snap_dist #assert pq.x() >= -snap_dist #assert pq.y() <= snap_dist #assert pq.y() >= -snap_dist if pq2 < nearest_dist2: nearest_dist2 = pq2 nearest = [] # TODO: shrink snap_margins ? assert isinstance(q, QtCore.QPointF) # ** BUGFIX ** # There appears to be a bug such that if I do not make a copy of q here, # it sometimes mysteriously changes by the end of the function. # Bug was seldom if ever visible under Linux, Windows, or OS 10.10 # Debugged under OS X 10.14, Python 3.8.3, PyQt 5.15.2, 2021-Feb nearest.append((pq2, QtCore.QPointF(p), QtCore.QPointF(q))) #self._log.trace('nearest = {}', nearest) if search_timer.hasExpired(250): self._log.info('aborting slow search: {} ms', search_timer.elapsed()) return [] #self._log.info('{} children searched in {} ms', len(self.childItems()), search_timer.elapsed()) #self._log.trace('final nearest = {}', nearest) #for pq2,p,q in nearest: # assert isinstance(p, QtCore.QPointF) # assert isinstance(q, QtCore.QPointF) # pq = q - p # assert pq.x() <= snap_dist # assert pq.x() >= -snap_dist # assert pq.y() <= snap_dist # assert pq.y() >= -snap_dist return nearest
def instant_fit_to_view(self, target_rect): """ Fit the current scene into view, snugly :param target_rect: scene rect that contains all of the items we want to fit into view. """ sr = self.sceneRect() #if self.zoom_anim: # self.zoom_anim.stop() if target_rect.right() > sr.right() or target_rect.bottom() > sr.bottom(): self.setSceneRect(sr + QtCore.QMarginsF(0, 0, 500, 500)) if target_rect.left() < sr.left() or target_rect.top() < sr.top(): self.setSceneRect(sr + QtCore.QMarginsF(500, 500, 0, 0)) self.fitInView(target_rect, 1) self._fit_scale = self.transform().m11() ctrl.call_watchers(self, 'viewport_changed')
def _loadFinished(self): result = "" print('Load Finished') print(self.parent.tab_web.maximumHeight()) if self.grab_window: if self.taking_screenshot is False: self.runJavaScript('document.body.scrollHeight', self.val_scr_height) elif self.taking_screenshot: self.runJavaScript(self.js_file_script, self.val_scr_height_scroll) margins = QtCore.QMarginsF(15, 15, 15, 15) layout = QtGui.QPageLayout(QtGui.QPageSize(QtGui.QPageSize.A4), QtGui.QPageLayout.Portrait, margins) if self.js_content is not None: self.runJavaScript(self.js_content, self.val_scr) if self.print_pdf and not self.total_tasks_dict.get('print-pdf'): self.printToPdf(self.print_pdf, layout) else: if not self.wait_for_cookie and not self.timeout and not self.print_pdf and not self.grab_window: self._decide_quit() elif self.print_pdf and not self.timeout and not self.total_tasks_dict.get('print-pdf'): self.printToPdf(self.print_pdf, layout) elif self.timeout: if self.print_pdf and not self.total_tasks_dict.get('print-pdf'): self.printToPdf(self.print_pdf, layout) else: self.timer.start(self.timeout*1000)
def paint(self, painter, option, widget=0): painter.setPen(self.pen()) path = QtGui.QPainterPath() if logger.isEnabledFor('debug'): painter.drawRect(self.boundingRect()) # debug bounding rect else: # Prevent paint from falling outside the lines path.addEllipse(self._const_rect) path.closeSubpath() painter.setClipPath(path) if self.scene().renderMode != self.scene().RENDER_OUTLINE: painter.setBrush(self.brush()) painter.drawEllipse(self._const_rect) if self.isSelected(): #painter.setBrush(QtGui.QBrush(QtGui.QColor(255,0,0,191))) painter.setBrush(QtCore.Qt.NoBrush) painter.setPen(self.selectionPen) n = .25 / 2 margins = QtCore.QMarginsF(n, n, n, n) painter.drawEllipse(self._const_rect.marginsRemoved(margins)) if logger.isEnabledFor('debug'): painter.setBrush(QtCore.Qt.NoBrush) painter.setPen(QtGui.QPen(QtCore.Qt.gray, .01)) for p in self.snapPoints(): painter.drawEllipse(p, .06, .06) painter.setPen(QtGui.QPen(QtCore.Qt.green, .03)) painter.drawLine(QPointF( 0, 0), self._const_rect.topLeft()) # indicate "first" vertex painter.setPen(QtGui.QPen(QtCore.Qt.blue, .03)) painter.drawEllipse(QtCore.QPointF(0, 0), .05, .05) # indicate center of rotation
def nearestSnaps(self, snap_dist, excludePt=None): '''Return a list of (equally) closest snap-tuples, in scene coordinates. Parameters are in scene coordinates. Returned tuples are (distance squared, p from self, q from other) ''' # This never seems to take more than a couple dozen ms, but nevertheless # performance is very sluggish, because Qt5 sends all mouse events # without compression no matter how long it takes to respond. search_timer = QtCore.QElapsedTimer() search_timer.start() snap_margins = QtCore.QMarginsF(snap_dist, snap_dist, snap_dist, snap_dist) nearest_dist2 = snap_dist * snap_dist # Use squared distances to avoid calling sqrt nearest = [] # list of nearby pairs of points # It's distinctly faster to let QGraphicsScene compare each child tile with # other tiles than to ask it to compare all child points with other tiles, # though this still ends up O(n*n) when dragging many tiles over many tiles. for child in self.childItems(): snap_search_rect = child.sceneBoundingRect().marginsAdded( snap_margins) nearby_items = self.scene().items(snap_search_rect) nearby_tiles = [ it for it in nearby_items if hasattr(it, "sceneSnapPoints") and not it.isSelected() ] if nearby_tiles: self._log.trace('{} nearby tiles', len(nearby_tiles)) #child_scenePath = child.mapToScene(child.snapShape()) #child_sceneVertices = pathVertices(child_scenePath) for other_tile in nearby_tiles: #other_scenePath = other_tile.mapToScene(other_tile.snapShape()) for p in child.sceneSnapPoints(): if excludePt is None or QtCore.QLineF( p, excludePt).length() > snap_dist / 100.0: for q in other_tile.sceneSnapPoints( ): #pathVertices(other_scenePath): if excludePt is None or QtCore.QLineF( q, excludePt).length( ) > snap_dist / 100.0: pq = p - q pq2 = pq.x()**2 + pq.y()**2 if pq2 <= nearest_dist2: if pq2 < nearest_dist2: nearest_dist2 = pq2 nearest = [ n for n in nearest if n[0] <= nearest_dist2 ] # TODO: shrink snap_margins ? nearest.append((pq2, p, q)) if search_timer.hasExpired(250): self._log.info('aborting slow search: {} ms', search_timer.elapsed()) return [] #self._log.info('{} children searched in {} ms', len(self.childItems()), search_timer.elapsed()) return nearest
def move_point_after(self, p, x_old, y_old, label='Move point'): """Call if point is moved by another way and need save history and update polygons""" #save revert operations to history self._history.move_point(p.id, x_old, y_old, label) # compute recount params small = (self._rect.width() + self._rect.height()) / 1000000 trimed = self._rect - QtCore.QMarginsF(small, small, small, small) if (not trimed.contains(QtCore.QPointF(x_old, y_old))) or \ (not self._rect.contains(p.qpointf())): self.recount_canvas()
def move_point(self, p, x, y, label='Move point', not_history=False): """Add point to canvas""" #save revert operations to history if not not_history: self._history.move_point(p.id, p.x, p.y, label) # compute recount params need_recount = False small = (self._rect.width() + self._rect.height()) / 1000000 trimed = self._rect - QtCore.QMarginsF(small, small, small, small) if (not trimed.contains(p.qpointf())) or \ (not self._rect.contains(QtCore.QPointF(x, y))): need_recount = True # move point p.x = x p.y = y # recount canvas size if need_recount: self.recount_canvas()
def fit_to_window(self, force=False, soft=False): """ Calls up to graph view and makes it to fit all visible items here to view window.""" mw = prefs.edge_width mh = prefs.edge_height margins = QtCore.QMarginsF(mw, mh * 2, mw, mh) use_current_positions = len(ctrl.forest.nodes) < 25 vr = self.visible_rect(current=use_current_positions) + margins if self._cached_visible_rect and not force: if vr != self._cached_visible_rect: if self.keep_updating_visible_area or \ prefs.auto_zoom or \ vr.width() > self._cached_visible_rect.width() or \ vr.height() > self._cached_visible_rect.height(): self.graph_view.instant_fit_to_view(vr) self._cached_visible_rect = vr else: self.graph_view.instant_fit_to_view(vr) self._cached_visible_rect = vr
def delete_point(self, p, label='Delete point', not_history=False): #save revert operations to history if not not_history: assert len(p.lines) == 0 self._history.add_point(p.id, p.x, p.y, label) # compute recount params need_recount = False small = (self._rect.width() + self._rect.height()) / 1000000 trimed = self._rect - QtCore.QMarginsF(small, small, small, small) if not trimed.contains(p.qpointf()): need_recount = True # remove point self.po.remove_point(self, p) self.points.remove(p) if not not_history: self.regions.del_regions(0, p.id, not not_history) # recount canvas size if need_recount: self.recount_canvas()
def timerEvent(self, event): """ Timer event only for printing, for 'snapshot' effect :param event: """ def find_path(fixed_part, extension, counter=0): """ Generate file names until free one is found :param fixed_part: blah :param extension: blah :param counter: blah """ if not counter: fpath = fixed_part + extension else: fpath = fixed_part + str(counter) + extension if os.path.exists(fpath): fpath = find_path(fixed_part, extension, counter + 1) return fpath if not self.print_started: return else: self.print_started = False self.killTimer(event.timerId()) # Prepare file and path path = prefs.print_file_path or prefs.userspace_path or \ running_environment.default_userspace_path if not path.endswith('/'): path += '/' if not os.path.exists(path): print("bad path for printing (print_file_path in preferences) , " "using '.' instead.") path = './' filename = prefs.print_file_name if filename.endswith(('.pdf', '.png')): filename = filename[:-4] # Prepare image self.graph_scene.removeItem(self.graph_scene.photo_frame) self.graph_scene.photo_frame = None # Prepare printer png = prefs.print_format == 'png' source = self.graph_scene.print_rect() if png: full_path = find_path(path + filename, '.png', 0) scale = 4 target = QtCore.QRectF(QtCore.QPointF(0, 0), source.size() * scale) writer = QtGui.QImage(target.size().toSize(), QtGui.QImage.Format_ARGB32_Premultiplied) writer.fill(QtCore.Qt.transparent) painter = QtGui.QPainter() painter.begin(writer) painter.setRenderHint(QtGui.QPainter.Antialiasing) self.graph_scene.render(painter, target=target, source=source) painter.end() iwriter = QtGui.QImageWriter(full_path) iwriter.write(writer) log.info( "printed to %s as PNG (%spx x %spx, %sx size)." % (full_path, int(target.width()), int(target.height()), scale)) else: dpi = 25.4 full_path = find_path(path + filename, '.pdf', 0) target = QtCore.QRectF(0, 0, source.width() / 2.0, source.height() / 2.0) writer = QtGui.QPdfWriter(full_path) writer.setResolution(dpi) writer.setPageSizeMM(target.size()) writer.setPageMargins(QtCore.QMarginsF(0, 0, 0, 0)) painter = QtGui.QPainter() painter.begin(writer) self.graph_scene.render(painter, target=target, source=source) painter.end() log.info("printed to %s as PDF with %s dpi." % (full_path, dpi)) # Thank you! # Restore image self.graph_scene.setBackgroundBrush(self.color_manager.gradient)
def to_pdf(self, _): page = DOCUMENTS_PATH + '/docs.pdf' layout = QtGui.QPageLayout(QtGui.QPageSize(QtGui.QPageSize.A4), QtGui.QPageLayout.Landscape, QtCore.QMarginsF(0, 0, 0, 0)) self.view.page().printToPdf(page, layout)
def exportToPDF(self): """Export the displayed note to PDF.""" fname = QtWidgets.QFileDialog.getSaveFileName( caption="Export Note to PDF", filter="PDF Files (*.pdf);;All Files (*)")[0] if fname: # Make sure we export the current version of the text if self.stack.currentIndex() == 0: self.displayHTMLRenderedMarkdown(self.text.toPlainText()) pageLayout = QtGui.QPageLayout(QtGui.QPageSize(QtGui.QPageSize.A4), QtGui.QPageLayout.Landscape, QtCore.QMarginsF(0, 0, 0, 0)) self.web.page().printToPdf(fname, pageLayout)
def accept(self): """ Executed when the dialog is accepted. Saves the user selections to the printer. """ pageLayout = self.printer.pageLayout() pageUnits = self.units pageLayout.setUnits(pageUnits) # PAGE SIZE combobox = self.widget('page_size_combobox') pageSize = combobox.currentData() spinboxW = self.widget('page_custom_width_spinbox') customWidth = spinboxW.value() spinboxH = self.widget('page_custom_height_spinbox') customHeight = spinboxH.value() if pageSize.id() == QtGui.QPageSize.Custom: pageSize = QtGui.QPageSize(QtCore.QSizeF(customWidth, customHeight), pageUnits) pageLayout.setPageSize(pageSize) # ORIENTATION portrait = self.widget('orientation_portrait_radio') landscape = self.widget('orientation_landscape_radio') if portrait.isChecked(): pageLayout.setOrientation(QtGui.QPageLayout.Portrait) elif landscape.isChecked(): pageLayout.setOrientation(QtGui.QPageLayout.Landscape) # MARGINS spinboxT = self.widget('margin_top_spinbox') spinboxB = self.widget('margin_bottom_spinbox') spinboxL = self.widget('margin_left_spinbox') spinboxR = self.widget('margin_right_spinbox') pageMargins = QtCore.QMarginsF( spinboxL.value(), spinboxT.value(), spinboxR.value(), spinboxB.value()) pageLayout.setMargins(pageMargins) # UPDATE PRINTER LAYOUT self.printer.setPageLayout(pageLayout) super().accept()
def _emit_pdf(self, size): margins = QtCore.QMarginsF(0, 0, 0, 0) layout = QtGui.QPageLayout(QtGui.QPageSize(QtGui.QPageSize.A4), QtGui.QPageLayout.Portrait, margins) self.printToPdf(os.path.join(os.getcwd(), "notebook.pdf"), layout)