def printProfile(self): printer = QPrinter(QPrinter.HighResolution) printer.setOutputFormat(QPrinter.PdfFormat) printer.setPaperSize(QPrinter.A4) printer.setOrientation(QPrinter.Landscape) printpreviewdlg = QPrintPreviewDialog() printpreviewdlg.paintRequested.connect(self.printRequested) printpreviewdlg.exec_()
def exportPDF(self, view, file_name, width, height): pdf = QPrinter() pdf.setOutputFormat(QPrinter.PdfFormat) pdf.setPrintRange(QPrinter.AllPages) pdf.setOrientation(QPrinter.Portrait) pdf.setResolution(QPrinter.HighResolution) pdf.setPaperSize(QSizeF(width, height), QPrinter.Point) pdf.setFullPage(True) pdf.setOutputFileName(file_name) view.mainFrame().print_(pdf) QApplication.restoreOverrideCursor()
def print_pdf(self): if self.deck is not None: #Setting the printer printer = QPrinter(QPrinter.HighResolution) printer.setOutputFormat(QPrinter.PdfFormat) printer.setOrientation(getattr(QPrinter, "Portrait")) printer.setOutputFileName(self.path) printer.setPaperSize(getattr(QPrinter, self.paper)) printer.setFullPage(True) guide = self.max_cards() printer.setOrientation(getattr(QPrinter, guide["orientation"])) print guide, self.card_size #Start printing with QPainter(printer) as paint: ind = 0 resol = printer.resolution() for c in self.deck: c.resize(self.card_size[0], self.card_size[1]) if ind == guide["max"]: printer.newPage() ind = 0 col = ind % guide["horizontal"] fil = ind // guide["horizontal"] print ind, fil, col target = QRectF((col)*self.card_size[0]*resol, (fil)*self.card_size[1]*resol, self.card_size[0]*resol, self.card_size[1]*resol) self.preview_card(c) self.scene.render(paint, target=target, source=QRectF(0,0,c.width(),c.height())) ind += 1
def printPage(ok): printer = QPrinter() printer.setOutputFormat(QPrinter.PdfFormat) printer.setOrientation(QPrinter.Landscape) printer.setPageMargins(0.1,0.1,0.1,0.1, QPrinter.Millimeter) printer.setOutputFileName(sys.argv[2]) view.print_(printer) app.exit()
class WebKitPDF ( QObject ): def __init__ ( self, url, dest ): QObject.__init__ ( self ) self.dest = dest self.page = QtWebKit.QWebPage ( self ) self.mainFrame = self.page.mainFrame() self.mainFrame.load ( QUrl ( url ) ) # Settings # Disable the scrollbars self.mainFrame.setScrollBarPolicy(Qt.Horizontal, Qt.ScrollBarAlwaysOff) self.mainFrame.setScrollBarPolicy(Qt.Vertical, Qt.ScrollBarAlwaysOff) self.connect ( self.page, SIGNAL ( "loadProgress(int)" ), self.loadProgress ) self.connect ( self.page, SIGNAL ( "loadFinished(bool)" ), self.renderPDF ) def loadProgress ( self, progress ): print "Progress: ", progress def renderPDF ( self, status ): print "Load finished with status: ", status print "Rendering PDF ..." contentsSize = self.mainFrame.contentsSize() contentsSize.setWidth(1280) self.page.setViewportSize ( contentsSize ) self.printer = QPrinter ( QPrinter.PrinterResolution ) #self.printer = QPrinter ( QPrinter.ScreenResolution ) self.printer.setOutputFormat ( QPrinter.PdfFormat ) #self.printer.setPaperSize ( QPrinter.A4 ) self.printer.setFullPage( True ) self.printer.setPaperSize ( QSizeF( contentsSize ), QPrinter.DevicePixel ) self.printer.setOrientation ( QPrinter.Portrait ) self.printer.setOutputFileName ( self.dest ) self.painter = QPainter ( self.printer ) self.painter.setRenderHint ( QPainter.Antialiasing ) self.mainFrame.render ( self.painter ) self.painter.end() app = QtGui.QApplication.instance() app.exit ( 0 )
def on_stampa_triggered(self, checked=None): """Slot launched when the user click on the "stampa" button""" if checked is None: return printer = QPrinter() print_dialog = QPrintDialog(printer, self) if print_dialog.exec_() == QDialog.Accepted: printer.setOrientation(QPrinter.Landscape) painter = QPainter() painter.begin(printer) geometry = self.ui_calendar.Table.geometry() self.ui_calendar.Table.setGeometry(printer.pageRect()) self.ui_calendar.Table.render(painter) self.ui_calendar.Table.setGeometry(geometry) painter.end()
def renderPdf(self, fileName): p = QPrinter() p.setOutputFormat(QPrinter.PdfFormat) p.setOutputFileName(fileName) p.setResolution(pdf_dpi) paperSize = self.m_paperSize if not len(paperSize): pageSize = QSize(self.m_page.mainFrame().contentsSize()) paperSize['width'] = str(pageSize.width()) + 'px' paperSize['height'] = str(pageSize.height()) + 'px' paperSize['border'] = '0px' if paperSize.get('width') and paperSize.get('height'): sizePt = QSizeF(ceil(self.stringToPointSize(paperSize['width'])), ceil(self.stringToPointSize(paperSize['height']))) p.setPaperSize(sizePt, QPrinter.Point) elif 'format' in paperSize: orientation = QPrinter.Landscape if paperSize.get( 'orientation') and paperSize['orientation'].lower( ) == 'landscape' else QPrinter.Portrait orientation = QPrinter.Orientation(orientation) p.setOrientation(orientation) formats = { 'A3': QPrinter.A3, 'A4': QPrinter.A4, 'A5': QPrinter.A5, 'Legal': QPrinter.Legal, 'Letter': QPrinter.Letter, 'Tabloid': QPrinter.Tabloid } p.setPaperSize(QPrinter.A4) # fallback for format, size in formats.items(): if format.lower() == paperSize['format'].lower(): p.setPaperSize(size) break else: return False border = floor(self.stringToPointSize( paperSize['border'])) if paperSize.get('border') else 0 p.setPageMargins(border, border, border, border, QPrinter.Point) self.m_page.mainFrame().print_(p) return True
def render_pdf(self, page, fileName, paperSize=None): """Renders the page into a pdf :param page: The webpage that we want to render :param fileName: The path where we want to save the pdf. For example /home/user/mypdf.pdf :param paperSize: An PaperSize object that will be used to render the webpage """ mainFrame = page.currentFrame() printer = QPrinter() printer.setOutputFormat(QPrinter.PdfFormat) printer.setOutputFileName(fileName) printer.setResolution(self._get_default_dpi()) if paperSize is None: ps = mainFrame.contentsSize() paperSize = PaperSize(width=ps.width(), height=ps.width(), margin=(0, 0, 0, 0), orientation=None, page_type=None) if paperSize.page_type is not None: if paperSize.orientation.lower() == "landscape": orientation = QPrinter.Landscape else: orientation = QPrinter.Portrait printer.setOrientation(orientation) printer.setPaperSize(QPrinter.A4) # Fallback for f in self.PAGE_TYPE: if paperSize.page_type.lower() == f[0].lower(): printer.setPaperSize(f[1]) break else: sizePt = QSizeF(paperSize.width, paperSize.height) printer.setPaperSize(sizePt, QPrinter.Point) printer.setPageMargins(paperSize.margin[0], paperSize.margin[1], paperSize.margin[2], paperSize.margin[3], QPrinter.Point) mainFrame.print_(printer)
def __outPDF(self): """ To save the profile as pdf file """ fileName = QFileDialog.getSaveFileName( self.__iface.mainWindow(), QCoreApplication.translate("VDLTools", "Save As"), QCoreApplication.translate("VDLTools", "Profile.pdf"),"Portable Document Format (*.pdf)") if fileName is not None: if self.__lib == 'Qwt5': printer = QPrinter() printer.setCreator(QCoreApplication.translate("VDLTools", "QGIS Profile Plugin")) printer.setOutputFileName(fileName) printer.setOutputFormat(QPrinter.PdfFormat) printer.setOrientation(QPrinter.Landscape) self.__plotWdg.print_(printer) elif self.__lib == 'Matplotlib': self.__plotWdg.figure.savefig(str(fileName))
def print_grid(self): if self.deck is not None: #Setting the printer printer = QPrinter(QPrinter.HighResolution) printer.setOutputFormat(QPrinter.PdfFormat) printer.setOrientation(getattr(QPrinter, self.orientation)) printer.setOutputFileName(self.path) printer.setPaperSize(getattr(QPrinter, self.paper)) #Start printing with QPainter(printer) as paint: first = True for c in self.deck: if not first: printer.newPage() first = False self.preview_card(c) self.scene.render(paint)
def outPDF(self, iface, wdg, mdl, library): for i in range(0, mdl.rowCount()): if mdl.item(i, 0).data(Qt.CheckStateRole): name = str(mdl.item(i, 2).data(Qt.EditRole)) break fileName = QFileDialog.getSaveFileName( iface.mainWindow(), "Save As", "Profile of " + name + ".pdf", "Portable Document Format (*.pdf)") if fileName: if library == "Qwt5" and has_qwt: printer = QPrinter() printer.setCreator('QGIS Profile Plugin') printer.setOutputFileName(fileName) printer.setOutputFormat(QPrinter.PdfFormat) printer.setOrientation(QPrinter.Landscape) wdg.plotWdg.print_(printer) elif library == "Matplotlib" and has_mpl: wdg.plotWdg.figure.savefig(str(fileName))
def renderPdf(self, fileName): p = QPrinter() p.setOutputFormat(QPrinter.PdfFormat) p.setOutputFileName(fileName) p.setResolution(pdf_dpi) paperSize = self.m_paperSize if not len(paperSize): pageSize = QSize(self.m_page.mainFrame().contentsSize()) paperSize['width'] = str(pageSize.width()) + 'px' paperSize['height'] = str(pageSize.height()) + 'px' paperSize['border'] = '0px' if paperSize.get('width') and paperSize.get('height'): sizePt = QSizeF(ceil(self.stringToPointSize(paperSize['width'])), ceil(self.stringToPointSize(paperSize['height']))) p.setPaperSize(sizePt, QPrinter.Point) elif 'format' in paperSize: orientation = QPrinter.Landscape if paperSize.get('orientation') and paperSize['orientation'].lower() == 'landscape' else QPrinter.Portrait orientation = QPrinter.Orientation(orientation) p.setOrientation(orientation) formats = { 'A3': QPrinter.A3, 'A4': QPrinter.A4, 'A5': QPrinter.A5, 'Legal': QPrinter.Legal, 'Letter': QPrinter.Letter, 'Tabloid': QPrinter.Tabloid } p.setPaperSize(QPrinter.A4) # fallback for format, size in formats.items(): if format.lower() == paperSize['format'].lower(): p.setPaperSize(size) break else: return False border = floor(self.stringToPointSize(paperSize['border'])) if paperSize.get('border') else 0 p.setPageMargins(border, border, border, border, QPrinter.Point) self.m_page.mainFrame().print_(p) return True
def open_html_in_print_preview_from_gui_thread(html, html_document=QTextDocument, page_size=None, page_orientation=None): printer = QPrinter() printer.setPageSize(page_size or QPrinter.A4) printer.setOrientation(page_orientation or QPrinter.Portrait) dialog = QPrintPreviewDialog(printer) @QtCore.pyqtSlot(QPrinter) def render(printer): doc = html_document() doc.setHtml(html) doc.print_(printer) dialog.paintRequested.connect(render) # show maximized seems to trigger a bug in qt which scrolls the page down #dialog.showMaximized() desktop = QCoreApplication.instance().desktop() # use the size of the desktop instead to set the dialog size dialog.resize(desktop.width() * 0.75, desktop.height() * 0.75) dialog.exec_()
def preview(self): """ Muestra el dialogo de vista previa de impresión """ try: printer = QPrinter() printer.setOrientation(self.orientation) printer.setPageSize(self.pageSize) web = self.web + self.printIdentifier report = reports.frmReportes(web, printer, self) report.exec_() except NotImplementedError as inst: QMessageBox.information( self, qApp.organizationName(), u"No se ha implementado la función de impresión para este modulo" ) logging.error(unicode(inst)) except UserWarning as inst: QMessageBox.critical(self, qApp.organizationName(), unicode(inst)) logging.error(unicode(inst)) except Exception as inst: QMessageBox.critical(self, qApp.organizationName(), "Hubo un error al intentar mostrar su reporte") logging.critical(unicode(inst))
def outPrint( self, iface, wdg, mdl, library): # Postscript file rendering doesn't work properly yet. for i in range(0, mdl.rowCount()): if mdl.item(i, 0).data(Qt.CheckStateRole): name = str(mdl.item(i, 2).data(Qt.EditRole)) #return fileName = QFileDialog.getSaveFileName(iface.mainWindow(), "Save As", "Profile of " + name + ".ps", "PostScript Format (*.ps)") if fileName: if library == "Qwt5" and has_qwt: printer = QPrinter() printer.setCreator("QGIS Profile Plugin") printer.setDocName("QGIS Profile") printer.setOutputFileName(fileName) printer.setColorMode(QPrinter.Color) printer.setOrientation(QPrinter.Portrait) dialog = QPrintDialog(printer) if dialog.exec_(): wdg.plotWdg.print_(printer) elif library == "Matplotlib" and has_mpl: wdg.plotWdg.figure.savefig(str(fileName))
class WebKitPDF(QObject): def __init__(self, url, dest): QObject.__init__(self) self.dest = dest self.page = QtWebKit.QWebPage(self) self.mainFrame = self.page.mainFrame() self.mainFrame.load(QUrl(url)) self.connect(self.page, SIGNAL("loadProgress(int)"), self.loadProgress) self.connect(self.page, SIGNAL("loadFinished(bool)"), self.renderPDF) def loadProgress(self, progress): print "Progress: ", progress def renderPDF(self, status): print "Load finished with status: ", status print "Rendering PDF ..." contentsSize = self.mainFrame.contentsSize() self.page.setViewportSize(contentsSize) self.printer = QPrinter(QPrinter.PrinterResolution) #self.printer = QPrinter ( QPrinter.ScreenResolution ) self.printer.setOutputFormat(QPrinter.PdfFormat) #self.printer.setPaperSize ( QPrinter.A4 ) self.printer.setFullPage(True) self.printer.setPaperSize(QSizeF(contentsSize), QPrinter.DevicePixel) self.printer.setOrientation(QPrinter.Portrait) self.printer.setOutputFileName(self.dest) self.painter = QPainter(self.printer) self.painter.setRenderHint(QPainter.Antialiasing) self.mainFrame.render(self.painter) self.painter.end() app = QtGui.QApplication.instance() app.exit(0)
def saveWindow(self): fileTypes = {'PDF':('pdf',), 'Postscript':('ps',),'SVG':('svg',)} filters = ';;'.join(['%s (%s)' % (k, ' '.join(['*.'+e for e in v])) for k, v in fileTypes.items()]) dlg = QFileDialog(self, QCoreApplication.translate('QwtPlot', 'Select type and name of file to save'), SimuVis4.Globals.defaultFolder or '', filters) dlg.setFileMode(QFileDialog.AnyFile) dlg.setAcceptMode(QFileDialog.AcceptSave) if dlg.exec_() != QDialog.Accepted: return tmp = str(dlg.selectedFilter()) fileType = tmp[:tmp.find('(')-1] dlg.setDefaultSuffix(fileTypes[fileType][0]) files = dlg.selectedFiles() if not files: return fileName = unicode(files[0]) SimuVis4.Globals.defaultFolder, tmp = os.path.split(fileName) if fileType == 'PDF': printer = QPrinter() printer.setOutputFormat(QPrinter.PdfFormat) printer.setOrientation(QPrinter.Landscape) printer.setOutputFileName(fileName) printer.setCreator('SimuVis4') self.plot.print_(printer) elif fileType == 'Postscript': printer = QPrinter() printer.setOutputFormat(QPrinter.PostScriptFormat) printer.setOrientation(QPrinter.Landscape) printer.setOutputFileName(fileName) printer.setCreator('SimuVis4') self.plot.print_(printer) elif fileType == 'SVG': generator = QSvgGenerator() generator.setFileName(fileName) generator.setSize(QSize(800, 600)) self.plot.print_(generator)
class Ventana_Imprimir(QtGui.QDialog): def __init__(self, parent=None, datos=None): self.parent = parent self.transito = datos super(Ventana_Imprimir, self).__init__(parent=self.parent) self.setGeometry(30, 40, 800, 500) self.setWindowTitle("Imprimir albaran") self.init_controles() #self.navegador.setUrl(QUrl('http://www.google.es')) self.navegador.setHtml(self.leer_plantilla_y_poner_datos()) #self.navegador.loadFinished.connect(lambda: self.LoadEnd()) def leer_plantilla_y_poner_datos(self): html = open(PLANTILLA_ALBARAN).read() if self.transito is None: html = """ <!DOCTYPE html> <html lang="es"> <head> <meta charset="UTF-8"> <title></title> </head> <body > <h1 style='color:red;'>NO HAY DATOS QUE PRESENTAR</h1> </body> </html> """ else: #pongamos los datos #self.transito = Historico() html = html.replace("@num_albaran", str(self.transito.num_albaran)) html = html.replace("@mat_cabina", self.transito.mat_cabina) html = html.replace("@mat_remolque", self.transito.mat_remolque) html = html.replace("@cliente", self.transito.razon_social_cliente) html = html.replace("@producto", self.transito.nombre_producto) html = html.replace("@proveedor", self.transito.razon_social_proveedor) html = html.replace("@poseedor", self.transito.razon_social_poseedor) html = html.replace("@agencia", self.transito.razon_social_agencia) html = html.replace("@conductor", self.transito.nombre_conductor) html = html.replace("@origen", self.transito.origen) html = html.replace("@destino", self.transito.destino) html = html.replace("@fech_entrada", self.transito.fecha_entrada) html = html.replace("@fech_salida", self.transito.fecha_salida) html = html.replace("@peso_entrada", str(self.transito.bruto)) html = html.replace("@peso_salida", str(self.transito.tara)) html = html.replace("@neto", str(self.transito.neto)) return html def printPreview(self): dialog = QtGui.QPrintPreviewDialog(self.printer) dialog.setWindowState(Qt.WindowMaximized) #dialog.paintRequested.connect(self.print_) dialog.setWindowFlags(Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowMinMaxButtonsHint | Qt.WindowCloseButtonHint | Qt.WindowContextHelpButtonHint) dialog.exec() def imprimir(self): print('Prepandando impresion') self.printer = QPrinter(QPrinter.HighResolution); self.printer.setPageSize(QPrinter.A4); self.printer.setOrientation(QPrinter.Portrait); self.printer.setPageMargins(10, 10, 10, 10, QPrinter.Millimeter) self.navegador.print_(self.printer) def LoadEnd(self): #self.printer = QPrinter( QPrinter.HighResolution ) #self.printer.setOutputFormat( QPrinter.PdfFormat ) #self.printer.setOutputFileName( "out.pdf" ) #self.printPreview() #self.navegador.print_( self.printer ) pass def init_controles(self): vbox = QtGui.QVBoxLayout() self.navegador = QtWebKit.QWebView(self) self.btnImprimir = QtGui.QPushButton(IMPRIMIR, self) self.btnImprimir.clicked.connect(lambda: self.imprimir()) vbox.addWidget(self.btnImprimir) vbox.addWidget(self.navegador) self.setLayout(vbox)
def renderPdf(self, fileName): p = QPrinter() p.setOutputFormat(QPrinter.PdfFormat) p.setOutputFileName(fileName) p.setResolution(pdf_dpi) paperSize = self.m_paperSize if not len(paperSize): pageSize = QSize(self.m_webPage.mainFrame().contentsSize()) paperSize['width'] = str(pageSize.width()) + 'px' paperSize['height'] = str(pageSize.height()) + 'px' paperSize['border'] = '0px' if paperSize.get('width') and paperSize.get('height'): sizePt = QSizeF(ceil(self.stringToPointSize(paperSize['width'])), ceil(self.stringToPointSize(paperSize['height']))) p.setPaperSize(sizePt, QPrinter.Point) elif 'format' in paperSize: orientation = QPrinter.Landscape if paperSize.get('orientation') and paperSize['orientation'].lower() == 'landscape' else QPrinter.Portrait orientation = QPrinter.Orientation(orientation) p.setOrientation(orientation) formats = { 'A0': QPrinter.A0, 'A1': QPrinter.A1, 'A2': QPrinter.A2, 'A3': QPrinter.A3, 'A4': QPrinter.A4, 'A5': QPrinter.A5, 'A6': QPrinter.A6, 'A7': QPrinter.A7, 'A8': QPrinter.A8, 'A9': QPrinter.A9, 'B0': QPrinter.B0, 'B1': QPrinter.B1, 'B2': QPrinter.B2, 'B3': QPrinter.B3, 'B4': QPrinter.B4, 'B5': QPrinter.B5, 'B6': QPrinter.B6, 'B7': QPrinter.B7, 'B8': QPrinter.B8, 'B9': QPrinter.B9, 'B10': QPrinter.B10, 'C5E': QPrinter.C5E, 'Comm10E': QPrinter.Comm10E, 'DLE': QPrinter.DLE, 'Executive': QPrinter.Executive, 'Folio': QPrinter.Folio, 'Ledger': QPrinter.Ledger, 'Legal': QPrinter.Legal, 'Letter': QPrinter.Letter, 'Tabloid': QPrinter.Tabloid } p.setPaperSize(QPrinter.A4) # fallback for format, size in formats.items(): if format.lower() == paperSize['format'].lower(): p.setPaperSize(size) break else: return False border = floor(self.stringToPointSize(paperSize['border'])) if paperSize.get('border') else 0 p.setPageMargins(border, border, border, border, QPrinter.Point) self.m_webPage.mainFrame().print_(p) return True
class GanttPrintHandler(PrintHandler): def __init__(self, ganttWidget): super(GanttPrintHandler, self).__init__() self._printer = None self.ganttWidget = ganttWidget self._pri = Namespace() def printer(self): if self._printer is None: self._printer = QPrinter(QPrinter.HighResolution) self._printer.setOrientation(QtGui.QPrinter.Landscape) self._printer.setFullPage(True) #self.translate(-15, -15) self._printer.setDocName(self.ganttWidget.ganttModel.name) return self._printer def createPreviewDialog(self, printer): return MyPrintPreviewDialog(self.ganttWidget, printer) @property def horizontalPageCount(self): return settings.print.HORIZONTAL_PAGE_COUNT def pageCount(self): self.preparePrint(self.printer()) return len(self._pageInfo) def preparePrint(self, printer): """druckenの前準備。派生クラスでオーバライド""" #drucken用のWidgetを用意する self._widget = GanttWidget() self._widget.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self._widget.ganttModel = self.ganttWidget.ganttModel self._pri = self.getPrintRectInfo(printer) self._widget.setGeometry(QRect(0, 0, self._pri.log.headerWidth + self._pri.log.bodyWidth, self._pri.log.headerHeight + self._pri.log.bodyHeight)) #各ページの表示範囲を算出する self._pageInfo = [] bh = self._pri.log.bodyHeight top = 0 while bh > 0: if bh < self._pri.log.bodyHeightPerPage: height = bh else: height = self._pri.log.bodyHeightPerPage #---- bw = self._pri.log.bodyWidth left = 0 while bw > 0: if bw < self._pri.log.bodyWidthPerPage: width = bw else: width = self._pri.log.bodyWidthPerPage self._pageInfo.append(QRect(left, top, width, height)) left += width bw -= width #---- top += height bh -= height print("self._pageInfo:", self._pageInfo) def getPrintRectInfo(self, printer): bodyHeight = 0 it = QtGui.QTreeWidgetItemIterator(self._widget, QtGui.QTreeWidgetItemIterator.NotHidden) while it.value(): #rect = self.visualRect(self.indexFromItem(it.value())) #rowHeight = self.rowHeight(self.indexFromItem(it.value())) #print(rect, rowHeight) #visualRect, rowHeightで取得できる高さが実際の行高さよりも小さいので #定数値を足し込んでおくことにする bodyHeight += ROW_HEIGHT it += 1 obj = Namespace() obj.dev = Namespace() obj.log = Namespace() obj.scl = Namespace() print("settings.columnWidth", settings.columnWidth) obj.log.headerWidth = settings.getHeaderWidth() obj.log.headerHeight = HEADER_HEIGHT obj.log.bodyWidth = self._widget.preferableWidth() obj.log.bodyHeight = bodyHeight obj.log.bodyWidthPerPage = obj.log.bodyWidth / self.horizontalPageCount obj.log.bodyHeightPerPage = ROW_HEIGHT * settings.print.ROWS_PER_PAGE obj.log.pageWidth = obj.log.headerWidth + obj.log.bodyWidthPerPage obj.log.pageHeight = obj.log.headerHeight + obj.log.bodyHeightPerPage pageRect = printer.pageRect() obj.dev.pageWidth = pageRect.width() obj.dev.pageHeight = pageRect.height() obj.dev.headerWidth = obj.dev.pageWidth * settings.print.HEADER_WIDTH_RATIO obj.dev.headerHeight = obj.dev.pageHeight * settings.print.HEADER_HEIGHT_RATIO obj.dev.bodyWidth = obj.dev.pageWidth - obj.dev.headerWidth obj.dev.bodyHeight = obj.dev.pageHeight - obj.dev.headerHeight obj.scl.headerWidth = obj.dev.headerWidth / obj.log.headerWidth obj.scl.headerHeight = obj.dev.headerHeight / obj.log.headerHeight obj.scl.bodyWidth = obj.dev.bodyWidth / obj.log.bodyWidthPerPage obj.scl.bodyHeight = obj.dev.bodyHeight / obj.log.bodyHeightPerPage #obj.header print(obj) return obj def printPage(self, painter, pageNo, pageCount): print("paintRect:", painter.device().pageRect(), painter.device().paperRect()) painter.save() #----------------------------------------------------------------------- deviceRect = painter.device().pageRect() painter.translate(deviceRect.top(), deviceRect.left()) #print(deviceRect) bodyRect = self._pageInfo[pageNo-1] #print(bodyRect) #データ部ヘッダ rect1 = self.renderDataHeader(painter, bodyRect) #データ部本体 self.renderDataBody(painter, bodyRect) #chart部ヘッダ self.renderChartHeader(painter, bodyRect) #chart部本体 self.renderChartBody(painter, bodyRect) #ページのframe painter.setPen(self._widget.pen4chartBoundary) log = self._pri.dev painter.drawRect(0,0,log.headerWidth,log.headerHeight) painter.drawRect(log.headerWidth,0,log.bodyWidth,log.headerHeight) painter.drawRect(0,log.headerHeight,log.headerWidth,log.bodyHeight) painter.drawRect( log.headerWidth,log.headerHeight,log.bodyWidth,log.bodyHeight) #----------------------------------------------------------------------- painter.restore() def renderDataHeader(self, painter, bodyRect): """データ部ヘッダ""" painter.save() #painter.translate(0, 0) painter.scale(self._pri.scl.headerWidth, self._pri.scl.headerHeight) rect = QRect(0,0,self._pri.log.headerWidth, self._pri.log.headerHeight) self._widget.render(painter, sourceRegion=QRegion(rect)) painter.restore() def renderDataBody(self, painter, bodyRect): """データ部本体""" painter.save() painter.translate(0, self._pri.dev.headerHeight) painter.scale(self._pri.scl.headerWidth, self._pri.scl.bodyHeight) self._widget.render(painter, sourceRegion=QtGui.QRegion( 0, self._pri.log.headerHeight + bodyRect.top(), self._pri.log.headerWidth, bodyRect.height())) painter.restore() def renderChartHeader(self, painter, bodyRect): """chart部ヘッダ""" painter.save() painter.translate(self._pri.dev.headerWidth, 0) painter.scale(self._pri.scl.bodyWidth, self._pri.scl.headerHeight) self._widget.render(painter, sourceRegion=QtGui.QRegion( self._pri.log.headerWidth + bodyRect.left(), 0, bodyRect.width(), self._pri.log.headerHeight)) painter.restore() def renderChartBody(self, painter, bodyRect): """chart部本体""" painter.save() painter.translate(self._pri.dev.headerWidth, self._pri.dev.headerHeight) painter.scale(self._pri.scl.bodyWidth, self._pri.scl.bodyHeight) self._widget.render(painter, sourceRegion=QtGui.QRegion( self._pri.log.headerWidth + bodyRect.left(), self._pri.log.headerHeight + bodyRect.top(), bodyRect.width(), bodyRect.height())) painter.restore()
<body> {table} </body> </html>. ''' with open('_tmp_results.html', 'w') as f: f.write(html_string.format(table=df.to_html( classes='mystyle', index=False, float_format='%.1f', # Case by case specific formatting: formatters={'Max UR Line1': lambda x: '%.2f' % x}))) # Create a document and print it to pdf doc = QTextDocument() location = '_tmp_results.html' html = open(location).read() doc.setHtml(html) printer = QPrinter() printer.setOutputFileName('results.pdf') printer.setOutputFormat(QPrinter.PdfFormat) printer.setPageSize(QPrinter.A3) printer.setOrientation(QPrinter.Landscape) printer.setPageMargins(10, 10, 10, 10, QPrinter.Millimeter) doc.print_(printer) # Clean up os.remove('_tmp_df_style.css') os.remove('_tmp_results.html')
class BatchPlottingDialog(QDialog): """ Class for batch plotting dialog """ def __init__(self, iface, batch_plotting): """ Initialize dialog data and event handlers """ super(BatchPlottingDialog, self).__init__() self.ui = Ui_BatchPlottingDialog() self.ui.setupUi(self) self.iface = iface self.ui.OutputTab.setCurrentIndex(2) # if batch_plotting is True -> plotting by selected polygons # False -> plot map canvas self.batch_plotting = batch_plotting if not self.batch_plotting: self.setWindowTitle(tr("Plot by Template")) self.ui.OutputTab.setTabEnabled(0, False) self.ui.OutputTab.setTabEnabled(1, False) # event handlers self.ui.PlotButton.clicked.connect(self.onPlotButton) self.ui.TempDirButton.clicked.connect(self.onTempDirButton) self.ui.CloseButton.clicked.connect(self.onCloseButton) self.ui.TemplateList.setSortingEnabled(True) # set paths self.pdfpath = "" if self.batch_plotting: self.ui.OutputPDFEdit.setText( QgsAtlasComposition(None).filenamePattern()) self.ui.SingleFileCheckbox.stateChanged.connect( self.changedSingleFileCheckbox) else: # set scale to map canvas scale self.ui.ScaleCombo.insertItem( 0, "%d" % round(self.iface.mapCanvas().scale())) self.ui.ScaleCombo.insertItem(0, "<extent>") self.ui.ScaleCombo.setCurrentIndex(0) self.printer = None def showEvent(self, event): """ Reset dialog when receives a show event. """ self.templatepath = QSettings().value( "SurveyingCalculation/template_dir", config.template_dir) self.fillLayersCombo() self.fillTemplateList() def fillLayersCombo(self): """ Fill the polygon layers combobox. """ oldSelectedLayer = self.ui.LayersComboBox.itemText( self.ui.LayersComboBox.currentIndex()) self.ui.LayersComboBox.clear() # if batch plotting is false only map canvas will be in the list if not self.batch_plotting: self.ui.LayersComboBox.addItem(tr("<Map view>")) self.ui.LayersComboBox.setCurrentIndex(0) return # if batch plotting is true fill layers combo polygon_layers = get_vector_layers_by_type(QGis.Polygon) if polygon_layers is None: return for layer in polygon_layers: self.ui.LayersComboBox.addItem(layer.name(), layer) # get current layer name try: actlayer_name = self.iface.activeLayer().name() except (AttributeError): actlayer_name = "" if self.ui.LayersComboBox.findText(oldSelectedLayer) == -1: self.ui.LayersComboBox.setCurrentIndex( self.ui.LayersComboBox.findText(actlayer_name)) else: self.ui.LayersComboBox.setCurrentIndex( self.ui.LayersComboBox.findText(oldSelectedLayer)) def fillTemplateList(self): """ Fill the listbox of composer template files. """ if self.ui.TemplateList.currentItem() is not None: oldSelectedTemplate = self.ui.TemplateList.currentItem().text() else: oldSelectedTemplate = "" self.ui.TemplateList.clear() tempdir = QDir(self.templatepath) if tempdir.exists(): fileinfolist = tempdir.entryInfoList( ["*.qpt"], QDir.Files | QDir.NoDotAndDotDot | QDir.NoSymLinks, QDir.NoSort) for fi in fileinfolist: item = QListWidgetItem(fi.fileName()) self.ui.TemplateList.addItem(item) if fi.fileName() == oldSelectedTemplate: self.ui.TemplateList.setCurrentItem(item) def onTempDirButton(self): """ Change the directory that contains print composer templates. """ templatepath = QFileDialog.getExistingDirectory( self, tr("Select Directory"), self.templatepath, QFileDialog.ShowDirsOnly) if templatepath != "": self.templatepath = templatepath QSettings().setValue("SurveyingCalculation/template_dir", templatepath) QSettings().sync() self.fillTemplateList() def changedSingleFileCheckbox(self, state): self.ui.OutputPDFEdit.setEnabled(not state) def onPlotButton(self): """ Batch plots selected geometry items using the selected template and scale. """ # check if one layer is selected if self.ui.LayersComboBox.currentIndex() == -1: QMessageBox.warning(self, tr("Warning"), tr("Select a layer!")) self.ui.LayersComboBox.setFocus() return # check if one composition template is selected if self.ui.TemplateList.selectedItems() == []: QMessageBox.warning(self, tr("Warning"), tr("Select a composer template!")) self.ui.TemplateList.setFocus() return template_filename = QDir(self.templatepath).absoluteFilePath( self.ui.TemplateList.currentItem().text()) # get the scale if self.ui.ScaleCombo.currentText() == "<extent>": scale = -1 else: try: scale = int(self.ui.ScaleCombo.currentText()) except (ValueError): QMessageBox.warning( self, tr("Warning"), tr("Scale must be a positive integer value!")) self.ui.ScaleCombo.setFocus() return if scale <= 0: QMessageBox.warning( self, tr("Warning"), tr("Scale must be a positive integer value!")) self.ui.ScaleCombo.setFocus() return # get composer name composer_name = self.ui.ComposerEdit.text() #check if there are selected items on polygon layers if self.batch_plotting: selected_layer = self.ui.LayersComboBox.itemData( self.ui.LayersComboBox.currentIndex()) selected_polygons = get_features(selected_layer.name(), QGis.Polygon, True) if selected_polygons is None: QMessageBox.warning( self, tr("Warning"), tr("Select at least one polygon on layer '%s'!" % selected_layer.name())) return # check output setting if self.ui.OutputTab.currentIndex() == 0: # to PDF if not self.ui.SingleFileCheckbox.checkState(): if len(self.ui.OutputPDFEdit.text()) == 0: res = QMessageBox.warning( self, tr("Warning"), tr("The filename pattern is empty. A default one will be used." ), QMessageBox.Ok | QMessageBox.Cancel, QMessageBox.Ok) if res == QMessageBox.Cancel: return self.ui.OutputPDFEdit.setText( QgsAtlasComposition(None).filenamePattern()) elif self.ui.OutputTab.currentIndex() == 1: # to Printer # no need for checking pass elif self.ui.OutputTab.currentIndex() == 2: # to Composer View # no need for checking yet pass # get map renderer of map canvas renderer = self.iface.mapCanvas().mapRenderer() self.composition = QgsComposition(renderer) # if plot to Composer View the composition must be set # before loading the template # otherwise composer's item properties doesn't appear if self.ui.OutputTab.currentIndex() == 2: # to Composer View if len(composer_name) == 0: composer = self.iface.createNewComposer() else: composer = self.iface.createNewComposer(composer_name) composer.setComposition(self.composition) # read template file and add to composition template_file = QFile(template_filename) template_file.open(QIODevice.ReadOnly | QIODevice.Text) template_content = template_file.readAll() template_file.close() document = QDomDocument() document.setContent(template_content) self.composition.loadFromTemplate(document) # if batch_plotting is True create an atlas composition if self.batch_plotting: # get composer map item and set new scale and the grid cmap = self.composition.getComposerMapById(0) cmap.setNewScale(scale) cmap.setGridIntervalX(scale / 10) cmap.setGridIntervalY(scale / 10) cmap.setAtlasDriven(True) cmap.setAtlasScalingMode(QgsComposerMap.Fixed) # set atlas composition parameters atlas = self.composition.atlasComposition() atlas.setEnabled(True) atlas.setCoverageLayer(selected_layer) atlas.setHideCoverage(False) atlas.setFilenamePattern(self.ui.OutputPDFEdit.text()) atlas.setSingleFile(self.ui.SingleFileCheckbox.checkState()) atlas.setSortFeatures(False) atlas.setFilterFeatures(True) selected_ids = [f.id() for f in selected_layer.selectedFeatures()] filter_id_string = ','.join([str(sid) for sid in selected_ids]) atlas.setFeatureFilter("$id in (" + filter_id_string + ")") # print the complete atlas composition if self.ui.OutputTab.currentIndex() == 0: # to PDF self.composition.setAtlasMode(QgsComposition.ExportAtlas) if self.pdfpath == "": self.pdfpath = QgsProject.instance().homePath().encode( sys.getfilesystemencoding()) if self.ui.SingleFileCheckbox.checkState(): #print to single pdf (multi-page) outputFileName = QDir( self.pdfpath).absoluteFilePath("qgis.pdf") outputFileName = QFileDialog.getSaveFileName( self, tr("Choose a file name to save the map as"), outputFileName, tr("PDF Format") + " (*.pdf *.PDF)") if not outputFileName: return if not outputFileName.lower().endswith(".pdf"): outputFileName += ".pdf" self.pdfpath = QDir(outputFileName).absolutePath() else: #print to more pdf outputDir = QFileDialog.getExistingDirectory( self, tr("Directory where to save PDF files"), self.pdfpath, QFileDialog.ShowDirsOnly) if not outputDir: return # test directory (if it exists and is writable) if not QDir(outputDir).exists() or not QFileInfo( outputDir).isWritable(): QMessageBox.warning( self, tr("Unable to write into the directory"), tr("The given output directory is not writable. Cancelling." )) return self.pdfpath = outputDir printer = QPrinter() painter = QPainter() if not len(atlas.featureFilterErrorString()) == 0: QMessageBox.warning( self, tr("Atlas processing error"), tr("Feature filter parser error: %s" % atlas.featureFilterErrorString())) return atlas.beginRender() if self.ui.SingleFileCheckbox.checkState(): #prepare for first feature, so that we know paper size to begin with atlas.prepareForFeature(0) self.composition.beginPrintAsPDF(printer, outputFileName) # set the correct resolution self.composition.beginPrint(printer) printReady = painter.begin(printer) if not printReady: QMessageBox.warning( self, tr("Atlas processing error"), tr("Error creating %s." % outputFileName)) return progress = QProgressDialog(tr("Rendering maps..."), tr("Abort"), 0, atlas.numFeatures(), self) QApplication.setOverrideCursor(Qt.BusyCursor) for featureI in range(0, atlas.numFeatures()): progress.setValue(featureI + 1) # process input events in order to allow aborting QCoreApplication.processEvents() if progress.wasCanceled(): atlas.endRender() break if not atlas.prepareForFeature(featureI): QMessageBox.warning(self, tr("Atlas processing error"), tr("Atlas processing error")) progress.cancel() QApplication.restoreOverrideCursor() return if not self.ui.SingleFileCheckbox.checkState(): multiFilePrinter = QPrinter() outputFileName = QDir(outputDir).filePath( atlas.currentFilename()) + ".pdf" self.composition.beginPrintAsPDF( multiFilePrinter, outputFileName) # set the correct resolution self.composition.beginPrint(multiFilePrinter) printReady = painter.begin(multiFilePrinter) if not printReady: QMessageBox.warning( self, tr("Atlas processing error"), tr("Error creating %s." % outputFileName)) progress.cancel() QApplication.restoreOverrideCursor() return self.composition.doPrint(multiFilePrinter, painter) painter.end() else: # start print on a new page if we're not on the first feature if featureI > 0: printer.newPage() self.composition.doPrint(printer, painter) atlas.endRender() if self.ui.SingleFileCheckbox.checkState(): painter.end() QApplication.restoreOverrideCursor() elif self.ui.OutputTab.currentIndex() == 1: # to Printer # if To Printer is selected set the printer # setting up printer if self.printer is None: self.printer = QPrinter() self.printer.setFullPage(True) self.printer.setColorMode(QPrinter.Color) # open printer setting dialog pdlg = QPrintDialog(self.printer, self) pdlg.setModal(True) pdlg.setOptions(QAbstractPrintDialog.None) if not pdlg.exec_() == QDialog.Accepted: return QApplication.setOverrideCursor(Qt.BusyCursor) #prepare for first feature, so that we know paper size to begin with self.composition.setAtlasMode(QgsComposition.ExportAtlas) atlas.prepareForFeature(0) # set orientation if self.composition.paperWidth( ) > self.composition.paperHeight(): self.printer.setOrientation(QPrinter.Landscape) self.printer.setPaperSize( QSizeF(self.composition.paperHeight(), self.composition.paperWidth()), QPrinter.Millimeter) else: self.printer.setOrientation(QPrinter.Portrait) self.printer.setPaperSize( QSizeF(self.composition.paperWidth(), self.composition.paperHeight()), QPrinter.Millimeter) self.printer.setResolution(self.composition.printResolution()) self.composition.beginPrint(self.printer) painter = QPainter(self.printer) if not len(atlas.featureFilterErrorString()) == 0: QMessageBox.warning( self, tr("Atlas processing error"), tr("Feature filter parser error: %s" % atlas.featureFilterErrorString())) QApplication.restoreOverrideCursor() return atlas.beginRender() progress = QProgressDialog(tr("Rendering maps..."), tr("Abort"), 0, atlas.numFeatures(), self) for featureI in range(0, atlas.numFeatures()): progress.setValue(featureI + 1) # process input events in order to allow cancelling QCoreApplication.processEvents() if progress.wasCanceled(): atlas.endRender() break if not atlas.prepareForFeature(featureI): QMessageBox.warning(self, tr("Atlas processing error"), tr("Atlas processing error")) progress.cancel() QApplication.restoreOverrideCursor() return # start print on a new page if we're not on the first feature if featureI > 0: self.printer.newPage() self.composition.doPrint(self.printer, painter) atlas.endRender() painter.end() QApplication.restoreOverrideCursor() elif self.ui.OutputTab.currentIndex() == 2: # to Composer View # create new composer self.composition.setAtlasMode(QgsComposition.PreviewAtlas) composer.composerWindow().on_mActionAtlasPreview_triggered( True) atlas.parameterChanged.emit() # Increase the reference count of the composer object # for not being garbage collected. # If not doing this composer would lost reference and qgis would crash # when referring to this composer object or at quit. ctypes.c_long.from_address(id(composer)).value += 1 else: # if batch_plotting is False open a QgsComposerView with current map canvas cmap = self.composition.getComposerMapById(0) # set the new extent of composer map item newextent = self.iface.mapCanvas().mapRenderer().extent() currentextent = cmap.extent() canvas_ratio = newextent.width() / newextent.height() map_ratio = currentextent.width() / currentextent.height() if map_ratio < canvas_ratio: dh = newextent.width() / map_ratio - newextent.height() newextent.setYMinimum(newextent.yMinimum() - dh / 2) newextent.setYMaximum(newextent.yMaximum() + dh / 2) else: dw = map_ratio * newextent.height() - newextent.width() newextent.setXMinimum(newextent.xMinimum() - dw / 2) newextent.setXMaximum(newextent.xMaximum() + dw / 2) cmap.setNewExtent(newextent) # set the new scale of composer map item if scale > 0: cmap.setNewScale(scale) sc = cmap.scale() # set the grid interval according to the scale cmap.setGridIntervalX(sc / 10) cmap.setGridIntervalY(sc / 10) # Increase the reference count of the composer object # for not being garbage collected. # If not doing this composer would lost reference and qgis would crash # when referring to this composer object or at quit. ctypes.c_long.from_address(id(composer)).value += 1 self.accept() def onCloseButton(self): """ Close the dialog when the Close button pushed. """ self.reject()
class BatchPlottingDialog(QDialog): """ Class for batch plotting dialog """ def __init__(self, iface, batch_plotting): """ Initialize dialog data and event handlers """ super(BatchPlottingDialog, self).__init__() self.ui = Ui_BatchPlottingDialog() self.ui.setupUi(self) self.iface = iface self.ui.OutputTab.setCurrentIndex(2) # if batch_plotting is True -> plotting by selected polygons # False -> plot map canvas self.batch_plotting = batch_plotting if not self.batch_plotting: self.setWindowTitle(tr("Plot by Template")) self.ui.OutputTab.setTabEnabled(0,False) self.ui.OutputTab.setTabEnabled(1,False) # event handlers self.ui.PlotButton.clicked.connect(self.onPlotButton) self.ui.TempDirButton.clicked.connect(self.onTempDirButton) self.ui.CloseButton.clicked.connect(self.onCloseButton) self.ui.TemplateList.setSortingEnabled(True) # set paths self.pdfpath = "" if self.batch_plotting: self.ui.OutputPDFEdit.setText( QgsAtlasComposition(None).filenamePattern() ) self.ui.SingleFileCheckbox.stateChanged.connect(self.changedSingleFileCheckbox) else: # set scale to map canvas scale self.ui.ScaleCombo.insertItem(0,"%d"%round(self.iface.mapCanvas().scale())) self.ui.ScaleCombo.insertItem(0,"<extent>") self.ui.ScaleCombo.setCurrentIndex(0) self.printer = None def showEvent(self, event): """ Reset dialog when receives a show event. """ self.templatepath = QSettings().value("SurveyingCalculation/template_dir",config.template_dir) self.fillLayersCombo() self.fillTemplateList() def fillLayersCombo(self): """ Fill the polygon layers combobox. """ oldSelectedLayer = self.ui.LayersComboBox.itemText( self.ui.LayersComboBox.currentIndex() ) self.ui.LayersComboBox.clear() # if batch plotting is false only map canvas will be in the list if not self.batch_plotting: self.ui.LayersComboBox.addItem(tr("<Map view>")) self.ui.LayersComboBox.setCurrentIndex(0) return # if batch plotting is true fill layers combo polygon_layers = get_vector_layers_by_type(QGis.Polygon) if polygon_layers is None: return for layer in polygon_layers: self.ui.LayersComboBox.addItem(layer.name(),layer) # get current layer name try: actlayer_name = self.iface.activeLayer().name() except (AttributeError): actlayer_name = "" if self.ui.LayersComboBox.findText(oldSelectedLayer) == -1: self.ui.LayersComboBox.setCurrentIndex( self.ui.LayersComboBox.findText(actlayer_name) ) else: self.ui.LayersComboBox.setCurrentIndex( self.ui.LayersComboBox.findText(oldSelectedLayer) ) def fillTemplateList(self): """ Fill the listbox of composer template files. """ if self.ui.TemplateList.currentItem() is not None: oldSelectedTemplate = self.ui.TemplateList.currentItem().text() else: oldSelectedTemplate = "" self.ui.TemplateList.clear() tempdir = QDir(self.templatepath) if tempdir.exists(): fileinfolist = tempdir.entryInfoList(["*.qpt"], QDir.Files | QDir.NoDotAndDotDot | QDir.NoSymLinks, QDir.NoSort) for fi in fileinfolist: item = QListWidgetItem(fi.fileName()) self.ui.TemplateList.addItem(item) if fi.fileName() == oldSelectedTemplate: self.ui.TemplateList.setCurrentItem( item ) def onTempDirButton(self): """ Change the directory that contains print composer templates. """ templatepath = QFileDialog.getExistingDirectory(self, tr("Select Directory"), self.templatepath, QFileDialog.ShowDirsOnly) if templatepath!="": self.templatepath = templatepath QSettings().setValue("SurveyingCalculation/template_dir",templatepath) QSettings().sync() self.fillTemplateList() def changedSingleFileCheckbox(self, state): self.ui.OutputPDFEdit.setEnabled(not state) def onPlotButton(self): """ Batch plots selected geometry items using the selected template and scale. """ # check if one layer is selected if self.ui.LayersComboBox.currentIndex() == -1: QMessageBox.warning(self, tr("Warning"), tr("Select a layer!")) self.ui.LayersComboBox.setFocus() return # check if one composition template is selected if self.ui.TemplateList.selectedItems() == []: QMessageBox.warning(self, tr("Warning"), tr("Select a composer template!")) self.ui.TemplateList.setFocus() return template_filename = QDir(self.templatepath).absoluteFilePath( self.ui.TemplateList.currentItem().text()) # get the scale if self.ui.ScaleCombo.currentText()=="<extent>": scale = -1 else: try: scale = int(self.ui.ScaleCombo.currentText()) except (ValueError): QMessageBox.warning(self, tr("Warning"), tr("Scale must be a positive integer value!")) self.ui.ScaleCombo.setFocus() return if scale<=0: QMessageBox.warning(self, tr("Warning"), tr("Scale must be a positive integer value!")) self.ui.ScaleCombo.setFocus() return # get composer name composer_name = self.ui.ComposerEdit.text() #check if there are selected items on polygon layers if self.batch_plotting: selected_layer = self.ui.LayersComboBox.itemData(self.ui.LayersComboBox.currentIndex()) selected_polygons = get_features(selected_layer.name(),QGis.Polygon,True) if selected_polygons is None: QMessageBox.warning(self, tr("Warning"), tr("Select at least one polygon on layer '%s'!"%selected_layer.name())) return # check output setting if self.ui.OutputTab.currentIndex() == 0: # to PDF if not self.ui.SingleFileCheckbox.checkState(): if len( self.ui.OutputPDFEdit.text() ) == 0: res = QMessageBox.warning(self, tr("Warning"), tr("The filename pattern is empty. A default one will be used."), QMessageBox.Ok | QMessageBox.Cancel, QMessageBox.Ok) if res == QMessageBox.Cancel: return self.ui.OutputPDFEdit.setText( QgsAtlasComposition(None).filenamePattern() ) elif self.ui.OutputTab.currentIndex() == 1: # to Printer # no need for checking pass elif self.ui.OutputTab.currentIndex() == 2: # to Composer View # no need for checking yet pass # get map renderer of map canvas renderer = self.iface.mapCanvas().mapRenderer() self.composition = QgsComposition(renderer) # if plot to Composer View the composition must be set # before loading the template # otherwise composer's item properties doesn't appear if self.ui.OutputTab.currentIndex() == 2: # to Composer View if len(composer_name)==0: composer = self.iface.createNewComposer() else: composer = self.iface.createNewComposer(composer_name) composer.setComposition(self.composition) # read template file and add to composition template_file = QFile( template_filename ) template_file.open(QIODevice.ReadOnly | QIODevice.Text) template_content = template_file.readAll() template_file.close() document = QDomDocument() document.setContent(template_content) self.composition.loadFromTemplate(document) # if batch_plotting is True create an atlas composition if self.batch_plotting: # get composer map item and set new scale and the grid cmap = self.composition.getComposerMapById(0) cmap.setNewScale(scale) cmap.setGridIntervalX(scale/10) cmap.setGridIntervalY(scale/10) cmap.setAtlasDriven(True) cmap.setAtlasScalingMode( QgsComposerMap.Fixed ) # set atlas composition parameters atlas = self.composition.atlasComposition() atlas.setEnabled(True) atlas.setCoverageLayer( selected_layer ) atlas.setHideCoverage(False) atlas.setFilenamePattern( self.ui.OutputPDFEdit.text() ) atlas.setSingleFile( self.ui.SingleFileCheckbox.checkState() ) atlas.setSortFeatures(False) atlas.setFilterFeatures(True) selected_ids = [f.id() for f in selected_layer.selectedFeatures()] filter_id_string = ','.join([str(sid) for sid in selected_ids]) atlas.setFeatureFilter("$id in (" + filter_id_string + ")") # print the complete atlas composition if self.ui.OutputTab.currentIndex() == 0: # to PDF self.composition.setAtlasMode( QgsComposition.ExportAtlas ) if self.pdfpath=="": self.pdfpath = QgsProject.instance().homePath().encode(sys.getfilesystemencoding()) if self.ui.SingleFileCheckbox.checkState(): #print to single pdf (multi-page) outputFileName = QDir(self.pdfpath).absoluteFilePath("qgis.pdf") outputFileName = QFileDialog.getSaveFileName(self, tr( "Choose a file name to save the map as" ), outputFileName, tr( "PDF Format" ) + " (*.pdf *.PDF)" ) if not outputFileName: return if not outputFileName.lower().endswith(".pdf"): outputFileName += ".pdf" self.pdfpath = QDir(outputFileName).absolutePath() else: #print to more pdf outputDir = QFileDialog.getExistingDirectory( self, tr( "Directory where to save PDF files" ), self.pdfpath, QFileDialog.ShowDirsOnly ) if not outputDir: return # test directory (if it exists and is writable) if not QDir(outputDir).exists() or not QFileInfo(outputDir).isWritable(): QMessageBox.warning( self, tr( "Unable to write into the directory" ), tr( "The given output directory is not writable. Cancelling." ) ) return self.pdfpath = outputDir printer = QPrinter() painter = QPainter() if not len(atlas.featureFilterErrorString()) == 0: QMessageBox.warning( self, tr( "Atlas processing error" ), tr( "Feature filter parser error: %s" % atlas.featureFilterErrorString() ) ) return atlas.beginRender() if self.ui.SingleFileCheckbox.checkState(): #prepare for first feature, so that we know paper size to begin with atlas.prepareForFeature(0) self.composition.beginPrintAsPDF(printer, outputFileName) # set the correct resolution self.composition.beginPrint(printer) printReady = painter.begin(printer) if not printReady: QMessageBox.warning( self, tr( "Atlas processing error" ), tr( "Error creating %s." % outputFileName ) ) return progress = QProgressDialog( tr( "Rendering maps..." ), tr( "Abort" ), 0, atlas.numFeatures(), self ) QApplication.setOverrideCursor( Qt.BusyCursor ) for featureI in range(0, atlas.numFeatures()): progress.setValue( featureI+1 ) # process input events in order to allow aborting QCoreApplication.processEvents() if progress.wasCanceled(): atlas.endRender() break if not atlas.prepareForFeature( featureI ): QMessageBox.warning( self, tr( "Atlas processing error" ), tr( "Atlas processing error" ) ) progress.cancel() QApplication.restoreOverrideCursor() return if not self.ui.SingleFileCheckbox.checkState(): multiFilePrinter = QPrinter() outputFileName = QDir( outputDir ).filePath( atlas.currentFilename() ) + ".pdf" self.composition.beginPrintAsPDF( multiFilePrinter, outputFileName ) # set the correct resolution self.composition.beginPrint( multiFilePrinter ) printReady = painter.begin( multiFilePrinter ) if not printReady: QMessageBox.warning( self, tr( "Atlas processing error" ), tr( "Error creating %s." % outputFileName ) ) progress.cancel() QApplication.restoreOverrideCursor() return self.composition.doPrint( multiFilePrinter, painter ) painter.end() else: # start print on a new page if we're not on the first feature if featureI > 0: printer.newPage() self.composition.doPrint( printer, painter ) atlas.endRender() if self.ui.SingleFileCheckbox.checkState(): painter.end() QApplication.restoreOverrideCursor() elif self.ui.OutputTab.currentIndex() == 1: # to Printer # if To Printer is selected set the printer # setting up printer if self.printer is None: self.printer = QPrinter() self.printer.setFullPage(True) self.printer.setColorMode(QPrinter.Color) # open printer setting dialog pdlg = QPrintDialog(self.printer,self) pdlg.setModal(True) pdlg.setOptions(QAbstractPrintDialog.None) if not pdlg.exec_() == QDialog.Accepted: return QApplication.setOverrideCursor(Qt.BusyCursor) #prepare for first feature, so that we know paper size to begin with self.composition.setAtlasMode( QgsComposition.ExportAtlas ) atlas.prepareForFeature(0) # set orientation if self.composition.paperWidth() > self.composition.paperHeight(): self.printer.setOrientation(QPrinter.Landscape) self.printer.setPaperSize( QSizeF(self.composition.paperHeight(), self.composition.paperWidth()), QPrinter.Millimeter) else: self.printer.setOrientation(QPrinter.Portrait) self.printer.setPaperSize( QSizeF(self.composition.paperWidth(), self.composition.paperHeight()), QPrinter.Millimeter) self.printer.setResolution(self.composition.printResolution()) self.composition.beginPrint( self.printer ) painter = QPainter(self.printer) if not len(atlas.featureFilterErrorString()) == 0: QMessageBox.warning( self, tr( "Atlas processing error" ), tr( "Feature filter parser error: %s" % atlas.featureFilterErrorString() ) ) QApplication.restoreOverrideCursor() return atlas.beginRender() progress = QProgressDialog( tr( "Rendering maps..." ), tr( "Abort" ), 0, atlas.numFeatures(), self ) for featureI in range(0, atlas.numFeatures()): progress.setValue( featureI+1 ) # process input events in order to allow cancelling QCoreApplication.processEvents() if progress.wasCanceled(): atlas.endRender() break if not atlas.prepareForFeature( featureI ): QMessageBox.warning( self, tr( "Atlas processing error" ), tr( "Atlas processing error" ) ) progress.cancel() QApplication.restoreOverrideCursor() return # start print on a new page if we're not on the first feature if featureI > 0: self.printer.newPage() self.composition.doPrint( self.printer, painter ) atlas.endRender() painter.end() QApplication.restoreOverrideCursor() elif self.ui.OutputTab.currentIndex() == 2: # to Composer View # create new composer self.composition.setAtlasMode( QgsComposition.PreviewAtlas ) composer.composerWindow().on_mActionAtlasPreview_triggered(True) atlas.parameterChanged.emit() # Increase the reference count of the composer object # for not being garbage collected. # If not doing this composer would lost reference and qgis would crash # when referring to this composer object or at quit. ctypes.c_long.from_address( id(composer) ).value += 1 else: # if batch_plotting is False open a QgsComposerView with current map canvas cmap = self.composition.getComposerMapById(0) # set the new extent of composer map item newextent = self.iface.mapCanvas().mapRenderer().extent() currentextent = cmap.extent() canvas_ratio = newextent.width()/newextent.height() map_ratio = currentextent.width()/currentextent.height() if map_ratio < canvas_ratio: dh = newextent.width() / map_ratio - newextent.height() newextent.setYMinimum( newextent.yMinimum() - dh / 2 ) newextent.setYMaximum( newextent.yMaximum() + dh / 2 ) else: dw = map_ratio * newextent.height() - newextent.width() newextent.setXMinimum( newextent.xMinimum() - dw / 2 ) newextent.setXMaximum( newextent.xMaximum() + dw / 2 ) cmap.setNewExtent(newextent) # set the new scale of composer map item if scale>0: cmap.setNewScale(scale) sc = cmap.scale() # set the grid interval according to the scale cmap.setGridIntervalX(sc/10) cmap.setGridIntervalY(sc/10) # Increase the reference count of the composer object # for not being garbage collected. # If not doing this composer would lost reference and qgis would crash # when referring to this composer object or at quit. ctypes.c_long.from_address( id(composer) ).value += 1 self.accept() def onCloseButton(self): """ Close the dialog when the Close button pushed. """ self.reject()
class Ventana_Imprimir(QtGui.QDialog): def __init__(self, parent=None, datos=None): self.parent = parent self.transito = datos super(Ventana_Imprimir, self).__init__(parent=self.parent) self.setGeometry(30, 40, 800, 500) self.setWindowTitle("Imprimir albaran") self.init_controles() #self.navegador.setUrl(QUrl('http://www.google.es')) self.navegador.setHtml(self.leer_plantilla_y_poner_datos()) #self.navegador.loadFinished.connect(lambda: self.LoadEnd()) def leer_plantilla_y_poner_datos(self): html = open(PLANTILLA_ALBARAN).read() if self.transito is None: html = """ <!DOCTYPE html> <html lang="es"> <head> <meta charset="UTF-8"> <title></title> </head> <body > <h1 style='color:red;'>NO HAY DATOS QUE PRESENTAR</h1> </body> </html> """ else: #pongamos los datos #self.transito = Historico() html = html.replace("@num_albaran", str(self.transito.num_albaran)) html = html.replace("@mat_cabina", self.transito.mat_cabina) html = html.replace("@mat_remolque", self.transito.mat_remolque) html = html.replace("@cliente", self.transito.razon_social_cliente) html = html.replace("@producto", self.transito.nombre_producto) html = html.replace("@proveedor", self.transito.razon_social_proveedor) html = html.replace("@poseedor", self.transito.razon_social_poseedor) html = html.replace("@agencia", self.transito.razon_social_agencia) html = html.replace("@conductor", self.transito.nombre_conductor) html = html.replace("@origen", self.transito.origen) html = html.replace("@destino", self.transito.destino) html = html.replace("@fech_entrada", self.transito.fecha_entrada) html = html.replace("@fech_salida", self.transito.fecha_salida) html = html.replace("@peso_entrada", str(self.transito.bruto)) html = html.replace("@peso_salida", str(self.transito.tara)) html = html.replace("@neto", str(self.transito.neto)) return html def printPreview(self): dialog = QtGui.QPrintPreviewDialog(self.printer) dialog.setWindowState(Qt.WindowMaximized) #dialog.paintRequested.connect(self.print_) dialog.setWindowFlags(Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowMinMaxButtonsHint | Qt.WindowCloseButtonHint | Qt.WindowContextHelpButtonHint) dialog.exec() def imprimir(self): print('Prepandando impresion') self.printer = QPrinter(QPrinter.HighResolution) self.printer.setPageSize(QPrinter.A4) self.printer.setOrientation(QPrinter.Portrait) self.printer.setPageMargins(10, 10, 10, 10, QPrinter.Millimeter) self.navegador.print_(self.printer) def LoadEnd(self): #self.printer = QPrinter( QPrinter.HighResolution ) #self.printer.setOutputFormat( QPrinter.PdfFormat ) #self.printer.setOutputFileName( "out.pdf" ) #self.printPreview() #self.navegador.print_( self.printer ) pass def init_controles(self): vbox = QtGui.QVBoxLayout() self.navegador = QtWebKit.QWebView(self) self.btnImprimir = QtGui.QPushButton(IMPRIMIR, self) self.btnImprimir.clicked.connect(lambda: self.imprimir()) vbox.addWidget(self.btnImprimir) vbox.addWidget(self.navegador) self.setLayout(vbox)
class Form(QDialog): def __init__(self, args=None,parent=None): super(Form, self).__init__(parent) self.printer = QPrinter() self.printer.setPageSize(QPrinter.A4) self.filename = '' #File name to convert lblFileName = QLabel("File Name") self.txtFileName = QLineEdit() if len(args) > 1: self.txtFileName.setText(args[1]) self.filename = args[1] self.txtFileName.setReadOnly(True) btnGetFileName = QToolButton() btnGetFileName.setText("..") getFileLayout = QHBoxLayout() getFileLayout.addWidget(lblFileName) getFileLayout.addWidget(self.txtFileName) getFileLayout.addWidget(btnGetFileName) #Code page of file lblCodePage = QLabel("Code Page") self.cmbCodePage = QComboBox() self.cmbCodePage.addItem("dos") self.cmbCodePage.addItem("windows") self.cmbCodePage.addItem("utf8") codePageLayout = QHBoxLayout() codePageLayout.addStretch() codePageLayout.addWidget(lblCodePage) codePageLayout.addWidget(self.cmbCodePage) #Printer Orientation (Portrait / Landscape) lblOrientation = QLabel("Orientation") self.cmbOrientation = QComboBox() self.cmbOrientation.addItem("portait") self.cmbOrientation.addItem("landscape") orientationLayout = QHBoxLayout() orientationLayout.addStretch() orientationLayout.addWidget(lblOrientation) orientationLayout.addWidget(self.cmbOrientation) #Buttons for save or Just quit bSave = QPushButton("Go for it") bQuit = QPushButton("Abort") buttonLayout = QHBoxLayout() buttonLayout.addWidget(bQuit) buttonLayout.addStretch() buttonLayout.addWidget(bSave) #Final Layout layout = QVBoxLayout() layout.addLayout(getFileLayout) layout.addLayout(codePageLayout) layout.addLayout(orientationLayout) layout.addLayout(buttonLayout) self.setLayout(layout) #Connections self.connect(bSave, SIGNAL("clicked()"),self.printViaQPainter) self.connect(bQuit, SIGNAL("clicked()"), self.accept) self.connect(btnGetFileName, SIGNAL("clicked()"),self.getFileName) self.setWindowTitle("dos/windows text to PDF") def getFileName(self): fd = QFileDialog(self) self.filename = fd.getOpenFileName() self.txtFileName.setText(self.filename) def printViaQPainter(self): from os.path import isfile if isfile(self.filename): lines = open(self.filename) else: return a = self.filename.split('.') s = a[-1] fname = '' for i in range(len(a)-1) : fname += a[i] fname += '.pdf' self.printer.setOutputFileName(fname) self.printer.setOutputFormat(QPrinter.PdfFormat) if self.cmbOrientation.currentText() == 'landscape': self.printer.setOrientation(QPrinter.Landscape) pageRect = self.printer.pageRect() LeftMargin = 15 biggest = findBiggestLine(self.filename) bestSize = findBestFontSize(biggest,pageRect) sansFont = QFont("Courier", bestSize) sansLineHeight = QFontMetrics(sansFont).height() painter = QPainter(self.printer) page = 1 y = 20 cpage = codePage(self.cmbCodePage.currentText()) for line in lines: painter.save() painter.setFont(sansFont) y += sansLineHeight x = LeftMargin try: painter.drawText(x,y,line[:-1].decode(cpage)) except: painter.drawText(x,y,'CodePage error !!!') if y > (pageRect.height() - 54) : self.printer.newPage() y = 20 painter.restore() lines.close() self.accept()
def renderPdf(self, fileName): p = QPrinter() p.setOutputFormat(QPrinter.PdfFormat) p.setOutputFileName(fileName) p.setResolution(pdf_dpi) paperSize = self.m_paperSize if not len(paperSize): pageSize = QSize(self.m_webPage.mainFrame().contentsSize()) paperSize['width'] = str(pageSize.width()) + 'px' paperSize['height'] = str(pageSize.height()) + 'px' paperSize['border'] = '0px' if paperSize.get('width') and paperSize.get('height'): sizePt = QSizeF(ceil(self.stringToPointSize(paperSize['width'])), ceil(self.stringToPointSize(paperSize['height']))) p.setPaperSize(sizePt, QPrinter.Point) elif 'format' in paperSize: orientation = QPrinter.Landscape if paperSize.get( 'orientation') and paperSize['orientation'].lower( ) == 'landscape' else QPrinter.Portrait orientation = QPrinter.Orientation(orientation) p.setOrientation(orientation) formats = { 'A0': QPrinter.A0, 'A1': QPrinter.A1, 'A2': QPrinter.A2, 'A3': QPrinter.A3, 'A4': QPrinter.A4, 'A5': QPrinter.A5, 'A6': QPrinter.A6, 'A7': QPrinter.A7, 'A8': QPrinter.A8, 'A9': QPrinter.A9, 'B0': QPrinter.B0, 'B1': QPrinter.B1, 'B2': QPrinter.B2, 'B3': QPrinter.B3, 'B4': QPrinter.B4, 'B5': QPrinter.B5, 'B6': QPrinter.B6, 'B7': QPrinter.B7, 'B8': QPrinter.B8, 'B9': QPrinter.B9, 'B10': QPrinter.B10, 'C5E': QPrinter.C5E, 'Comm10E': QPrinter.Comm10E, 'DLE': QPrinter.DLE, 'Executive': QPrinter.Executive, 'Folio': QPrinter.Folio, 'Ledger': QPrinter.Ledger, 'Legal': QPrinter.Legal, 'Letter': QPrinter.Letter, 'Tabloid': QPrinter.Tabloid } p.setPaperSize(QPrinter.A4) # fallback for format, size in formats.items(): if format.lower() == paperSize['format'].lower(): p.setPaperSize(size) break else: return False border = floor(self.stringToPointSize( paperSize['border'])) if paperSize.get('border') else 0 p.setPageMargins(border, border, border, border, QPrinter.Point) self.m_webPage.mainFrame().print_(p) return True
def renderPdf(self, fileName): p = QPrinter() p.setOutputFormat(QPrinter.PdfFormat) p.setOutputFileName(fileName) p.setResolution(self.pdf_dpi) paperSize = self.m_paperSize if not len(paperSize): pageSize = QSize(self.m_webPage.mainFrame().contentsSize()) paperSize["width"] = str(pageSize.width()) + "px" paperSize["height"] = str(pageSize.height()) + "px" paperSize["border"] = "0px" if paperSize.get("width") and paperSize.get("height"): sizePt = QSizeF( ceil(self.stringToPointSize(paperSize["width"])), ceil(self.stringToPointSize(paperSize["height"])) ) p.setPaperSize(sizePt, QPrinter.Point) elif "format" in paperSize: orientation = ( QPrinter.Landscape if paperSize.get("orientation") and paperSize["orientation"].lower() == "landscape" else QPrinter.Portrait ) orientation = QPrinter.Orientation(orientation) p.setOrientation(orientation) formats = { "A0": QPrinter.A0, "A1": QPrinter.A1, "A2": QPrinter.A2, "A3": QPrinter.A3, "A4": QPrinter.A4, "A5": QPrinter.A5, "A6": QPrinter.A6, "A7": QPrinter.A7, "A8": QPrinter.A8, "A9": QPrinter.A9, "B0": QPrinter.B0, "B1": QPrinter.B1, "B2": QPrinter.B2, "B3": QPrinter.B3, "B4": QPrinter.B4, "B5": QPrinter.B5, "B6": QPrinter.B6, "B7": QPrinter.B7, "B8": QPrinter.B8, "B9": QPrinter.B9, "B10": QPrinter.B10, "C5E": QPrinter.C5E, "Comm10E": QPrinter.Comm10E, "DLE": QPrinter.DLE, "Executive": QPrinter.Executive, "Folio": QPrinter.Folio, "Ledger": QPrinter.Ledger, "Legal": QPrinter.Legal, "Letter": QPrinter.Letter, "Tabloid": QPrinter.Tabloid, } p.setPaperSize(QPrinter.A4) # fallback for format_, size in formats.items(): if format_.lower() == paperSize["format"].lower(): p.setPaperSize(size) break else: return False border = floor(self.stringToPointSize(paperSize["border"])) if paperSize.get("border") else 0 p.setPageMargins(border, border, border, border, QPrinter.Point) self.m_webPage.mainFrame().print_(p) return True
class WebPageToPdf(QObject): threadPdfStatusBar = QtCore.pyqtSignal(object) threadPdfWritingStatus = QtCore.pyqtSignal(object) threadPdfWritingDone = QtCore.pyqtSignal(int) def __init__(self): QObject.__init__(self) self.regex = Regex() self.title = '' self.webView = QWebView() self.webView.settings().setAttribute(QWebSettings.AutoLoadImages, True) self.webView.settings().setAttribute(QWebSettings.JavascriptEnabled, True) self.webView.settings().setAttribute(QWebSettings.PluginsEnabled, True) self.webView.settings().setAttribute(QWebSettings.DeveloperExtrasEnabled, True) self.pdfPrinter = QPrinter() self.webView.loadFinished.connect(self.convertToPdf) def setupDefaultPdfPrinter(self, fileName): self.pdfPrinter.setOrientation(QPrinter.Portrait) self.pdfPrinter.setPageSize(QPrinter.A4) self.pdfPrinter.setOutputFormat(QPrinter.PdfFormat) self.pdfPrinter.setOutputFileName(fileName) def printWebHtmlToPdf(self, url, filePath, fileName, groupType): self.tempPdfFile = filePath + 'out.pdf' self.filePath = filePath self.fileName = fileName self.url = url self.groupType = groupType self.setupDefaultPdfPrinter(self.tempPdfFile) self.threadPdfStatusBar.emit('Fetching Data From Web. Please Wait...') # self.threadPdfWritingStatus.emit( # '<font size=4 color=green><b>Method "%s": </b></font><font color=green><b>Fetching Data From Web for</b> %s<b>.<br />Please Wait...</b></font>' % ( # self.groupType, self.url)) self.threadPdfWritingStatus.emit( '<font color=green><b>Fetching Data From Web for</b> %s<b>.<br />Please Wait...</b></font>' % self.url) self.webView.load(QUrl(url)) self.title = self.webView.title() def convertToPdf(self): print 'Generating Pdf' # self.threadPdfWritingStatus.emit( # '<font size=4><b>Method "%s": </b></font><b>Generating Pdf for</b> %s<b>. Please Wait...</b>' % ( # self.groupType, self.url)) self.threadPdfWritingStatus.emit( '<b>Generating Pdf for</b> %s<b>. Please Wait...</b>' % self.url) self.threadPdfStatusBar.emit('Generating Pdf. Please Wait...') self.webView.print_(self.pdfPrinter) print 'Generated Pdf' # self.threadPdfWritingStatus.emit( # '<font size=4><b>Method "%s": </b></font><b>Generated Pdf for</b> %s<b>. Please Wait...</b>' % ( # self.groupType, self.url)) self.threadPdfWritingStatus.emit( '<b>Generated Pdf for</b> %s<b>. Please Wait...</b>' % self.url) self.threadPdfStatusBar.emit('Generated Pdf.') self.mergePdf() self.threadPdfWritingDone.emit(True) def mergePdf(self): # self.threadPdfWritingStatus.emit( # '<font size=4><b>Method "%s": </b></font><b>Setting Title for</b> %s<b>. Please Wait...</b><br />' % ( # self.groupType, self.url)) self.threadPdfWritingStatus.emit( '<b>Setting Title for</b> %s<b>. Please Wait...</b><br />' % self.url) packet = StringIO() # create a new PDF with Reportlab pdfCanvas = canvas.Canvas(packet, pagesize=A4) pdfCanvas.setFont('Helvetica', 8) if len(self.title) is 0: self.title = str(self.url).split('/')[-1] self.title = self.regex.getSearchedData('(?i)([a-zA-Z0-9-_ ]*?)\.[a-zA-Z0-9_]*$', self.title) self.title = self.regex.replaceData('(?i)_', ' ', self.title) title = unicode(self.title[:57] + '...') if (len(self.title) > 60) else unicode(self.title) url = self.url[:57] + '...' if (len(self.title) > 60) else self.url pdfCanvas.drawString(5, 830, title + ' ' + str(url).lower()) d = datetime.datetime.now() strDate = str(d.strftime("%Y-%m-%d %H-%M-%S %p")) pdfCanvas.drawString(420, 5, 'Created Date Time: ' + strDate) pdfCanvas.save() packet.seek(0) newPdf = PdfFileReader(packet) if not os.path.exists(self.tempPdfFile): return self.printWebHtmlToPdf(self.url, self.filePath, self.fileName) writer = PdfFileWriter() tmpPdfFile = file(self.tempPdfFile, 'rb') reader = PdfFileReader(tmpPdfFile) for i in range(0, (reader.getNumPages())): page = reader.getPage(i) page.mergePage(newPdf.getPage(0)) # page = newPdf.getPage(0) # page.mergePage(reader.getPage(i)) writer.addPage(page) print 'Filename: ' + self.fileName outputStream = file(self.filePath + self.fileName, "wb") writer.write(outputStream) outputStream.close() tmpPdfFile.close() os.remove(str(self.tempPdfFile))
class Base(QMainWindow): """ Esta clase sirve de base para todos aquellos formularios que siguen el estandar de dos pestañas, una para navegación y otra para edición """ orientation = QPrinter.Portrait pageSize = QPrinter.Letter web = "" def __init__(self, parent, own_toolbar=False): """ @param parent: El widget padre de esta ventana @param own_toolbar: Si este widget dibujara su toolbar en el padre o en el mismo @type parent: QWidget @type own_toolbar: bool """ super(Base, self).__init__(parent) self.user = user.LoggedUser self._status = True self.parentWindow = parent self.own_toolbar = own_toolbar self.database = QSqlDatabase.database() """ @type: QSqlDatabase @ivar: La base de datos a la cual se conecta el sistema """ self.mapper = QDataWidgetMapper(self) u""" @type: QDataWidgetMapper @ivar: El mapper que se encarga de asignar los datos del modelo de navegación a los distintos widgets """ self.printProgressBar = QProgressBar(self) self.webview = QWebView() """ @ivar: EL objeto webview usado para cargar los reportes @type: QWebView """ self.loaded = False """ @ivar: Si se pudo o no cargar un reporte @type: bool """ self.startUi() self.editmodel = None self.printer = QPrinter() self._status = False def startUi(self): """ Iniciar todos los elementos graficos """ self.setupUi(self) if not self.own_toolbar: self.parent().addToolBar(self.toolBar) self.removeToolBar(self.toolBar) settings = QSettings() self.restoreState(settings.value(self.windowTitle() + "/State").toByteArray()) """ @ivar: El MainWindow al que pertenece este widget """ self.createActions() self.printProgressBar.setVisible(False) _tab1shortcut = QShortcut(QKeySequence("Ctrl+1"), self, functools.partial(self.tabWidget.setCurrentIndex, 0)) _tab2shortcut = QShortcut(QKeySequence("Ctrl+2"), self, functools.partial(self.tabWidget.setCurrentIndex, 1)) self.mapper.currentIndexChanged[int].connect(self.updateDetailFilter) self.actionCut.setVisible(False) self.actionPaste.setVisible(False) self.actionCopy.setVisible(False) def closeEvent(self, event): u""" Guardar el tamaño, la posición en la pantalla y la posición de la barra de tareas Preguntar si realmente se desea cerrar la pestaña cuando se esta en modo edición """ if not self.status: if ( not QMessageBox.question( self, qApp.organizationName(), u"¿Está seguro que desea salir?", QMessageBox.Yes | QMessageBox.No ) == QMessageBox.Yes ): event.ignore() # Guardar el tamaño y la posición settings = QSettings() settings.setValue(self.windowTitle() + "/Geometry", self.saveGeometry()) if not self.own_toolbar: self.parent().mdiArea().parent().parent().removeToolBar(self.toolBar) def editCell(self): """ Editar la celda actualmente seleccionada de self.tableedit """ self.tabledetails.edit(self.tabledetails.selectionModel().currentIndex()) @pyqtSlot(QDateTime) @if_edit_model def on_dtPicker_dateTimeChanged(self, datetime): """ Cambiar el tipo de cambio del modelo de edición si cambia la fecha @param datetime: La fecha contenida en self.dtPicker @type datetime: QDateTime """ query = QSqlQuery() try: if not self.database.isOpen(): if not self.database.open(): raise Exception( "No se pudo conectar a la base de " + "datos para recuperar los tipos " + "de cambio" ) q = """ SELECT idtc, tasa FROM tiposcambio WHERE fecha = %s LIMIT 1 """ % datetime.toString( "yyyyMMdd" ) if not query.exec_(q): raise UserWarning("No se pudieron recuperar los tipos de " + "cambio") if not query.size() == 1: logging.critical(u"La consulta para obtener tipos de " + "cambio no devolvio exactamente un valor") raise UserWarning(u"Hubo un error al obtener los tipos " + "de cambio") query.first() self.editmodel.exchangeRateId = query.value(0).toInt()[0] self.editmodel.exchangeRate = Decimal(query.value(1).toString()) # self.editmodel.setData( self.editmodel.index( 0, 0 ), self.editmodel.index( 0, 0 ).data() ) self.editmodel.datetime = datetime except UserWarning as inst: QMessageBox.critical(self, qApp.organizationName(), unicode(inst)) self.dtPicker.setDateTime(self.editmodel.datetime) logging.error(inst) logging.error(query.lastError().text()) except Exception as inst: QMessageBox.critical(self, qApp.organizationName(), u"Hubo un error al obtener los tipos de" + " cambio") logging.critical(query.lastError().text()) logging.critical(inst) self.dtPicker.setDateTime(self.editmodel.datetime) def navigate(self, to): """ Esta funcion se encarga de navegar entro los distintos documentos @param to: es una string que puede tomar los valores 'next' 'previous' 'first' 'last' """ if self.mapper.currentIndex != -1: row = self.mapper.currentIndex() if to == "next": row += 1 if row >= self.navproxymodel.rowCount(): row = self.navproxymodel.rowCount() - 1 self.mapper.setCurrentIndex(row) elif to == "previous": if row <= 1: row = 0 else: row = row - 1 self.mapper.setCurrentIndex(row) elif to == "first": self.mapper.toFirst() elif to == "last": self.mapper.toLast() else: self.mapper.toLast()() if self.tabledetails != None: self.tabledetails.resizeColumnsToContents() self.tabledetails.horizontalHeader().setStretchLastSection(True) self.tablenavigation.selectRow(self.mapper.currentIndex()) def updateDetailFilter(self, _index): """ Esta función se debe implementar en los formularios para que al navegar se actualize el filtro de la tabla detalles @param index: Este es el indice del mapper en el que actualmente se encuentra navegando @type index: int """ QMessageBox.information(self, qApp.organizationName(), u"Esta parte del sistema no ha " + "sido implementada") raise NotImplementedError() def loadModels(self): """ Esta función se ejecuta en el constructor del formulario mediante un QTimer, carga los formularios por primera vez """ self.updateModels() self.navigate("last") self.status = True def _setStatus(self, stat): """ @param stat: False = editando, True = navegando @type stat: bool """ self._status = stat self.setControls(self._status) def _getStatus(self): """ esta propiedad cambia entre navegar y editar """ return self._status status = property(_getStatus, _setStatus) @pyqtSlot(unicode) def on_txtSearch_textChanged(self, searchstring): """ Cambiar el filtro para el navigation model @param searchstring: Es el contenido por el cual se va a filtrar el modelo de navegación @type searchstring: string """ self.navproxymodel.setFilterFixedString(searchstring) @pyqtSlot(QModelIndex) def on_tablenavigation_doubleClicked(self, index): """ Al hacer doble click en la tabla de navegación el se cambia a la pestaña detalles mostrando el documento seleccionado @param index: El indice de la tabla en la que se dio doble click @type index: QModelIndex """ self.mapper.setCurrentIndex(index.row()) self.tabWidget.setCurrentIndex(0) @pyqtSlot(QModelIndex) def on_tablenavigation_clicked(self, index): self.mapper.setCurrentIndex(index.row()) def save(self, ask=True): """ Guardar el documento actual @param ask: Si se deberia o no preguntar al usuario si esta seguro antes de proceder @type ask: bool """ if ( ask == False or QMessageBox.question( self, qApp.organizationName(), u"¿Esta seguro que desea guardar?", QMessageBox.Yes | QMessageBox.No ) == QMessageBox.Yes ): if self.editmodel.valid: if self.editmodel.save(): QMessageBox.information(self, qApp.organizationName(), u"El documento se ha guardado con éxito") self.editmodel = None self.updateModels() self.navigate("last") self.status = True else: QMessageBox.critical(self, qApp.organizationName(), "Ha ocurrido un error al guardar el documento") else: try: QMessageBox.warning(self, qApp.organizationName(), self.editmodel.validError) except AttributeError: QMessageBox.warning( self, qApp.organizationName(), u"El documento no puede guardarse" + " ya que la información no esta" + " completa", ) def setControls(self, unused_status): """ Habilitar o deshabilitar los controles según status @param status: @type status: bool """ QMessageBox.information(self, qApp.organizationName(), u"Esta parte del sistema no ha sido implementada") raise NotImplementedError() def addLine(self): """ añadir una linea a table edit, solo se llama directamente en una ocasion, al comenzar la edicion de un documento """ row = self.editmodel.rowCount() self.editmodel.insertRows(row) def createAction(self, text, slot=None, shortcut=None, icon=None, tip=None, checkable=False, signal="triggered"): """ Crear un objeto acción @param text: El texto de la acción @type text: string @param slot: El slot que se ejecutara cuando se dispare esta acción @type slot: callable @param shortcut: El acceso directo que tiene asignada esta acción @type shortcut: QKeySequence @param icon: El icono de esta acción @type icon: string @param tip: El tooltip que tendra esta acción @type tip: string @param checkable: Si esta acción es checkable o no @type checkable: bool @param signal: La señal en la que esta acción ejecutara el slot @type signal: string @rtype: QAction """ action = QAction(text, self) if icon is not None: if type(icon) == QIcon: action.setIcon(icon) else: action.setIcon(QIcon(icon)) if shortcut is not None: action.setShortcut(shortcut) if tip is not None: action.setToolTip(tip) action.setStatusTip(tip) if slot is not None: getattr(action, signal).connect(slot) if checkable: action.setCheckable(True) return action def newDocument(self): """ Empezar la edición de un nuevo documento """ QMessageBox.information(self, qApp.organizationName(), u"Esta parte del sistema no ha sido implementada") raise NotImplementedError() def cancel(self): """ Cancelar la edición del nuevo documento """ QMessageBox.information(self, qApp.organizationName(), u"Esta parte del sistema no ha sido implementada") raise NotImplementedError() @property def printIdentifier(self): """ La identificación de este documento para reporte, normalmente sera el iddocumento o el ndocimpreso @rtype:string """ raise NotImplementedError(u"printIdentifier debe implementarse para " + "poder imprimir") def preview(self): """ Muestra el dialogo de vista previa de impresión """ try: printer = QPrinter() printer.setOrientation(self.orientation) printer.setPageSize(self.pageSize) web = self.web + self.printIdentifier report = reports.frmReportes(web, printer, self) report.exec_() except NotImplementedError as inst: QMessageBox.information( self, qApp.organizationName(), u"No se ha implementado la función de impresión para este modulo" ) logging.error(unicode(inst)) except UserWarning as inst: QMessageBox.critical(self, qApp.organizationName(), unicode(inst)) logging.error(unicode(inst)) except Exception as inst: QMessageBox.critical(self, qApp.organizationName(), "Hubo un error al intentar mostrar su reporte") logging.critical(unicode(inst)) def printDocument(self): """ Imprime el documento actual """ try: base = reports.Reports.url if base == "": raise UserWarning(u"No existe una configuración para el " + "servidor de reportes") self.printer.setOrientation(self.orientation) self.printer.setPageSize(self.pageSize) web = base + self.web + self.printIdentifier + "&uname=" + self.user.user + "&hash=" + self.user.hash self.loaded = False self.webview.load(QUrl(web)) self.webview.loadFinished[bool].connect(self.on_webview_loadFinished) self.webview.loadProgress[int].connect(self.on_webview_loadProgress) except NotImplementedError as inst: logging.error(unicode(inst)) QMessageBox.information( self, qApp.organizationName(), u"La función de impresión no se ha " + "implementado para este modulo" ) except UserWarning as inst: logging.error(unicode(inst)) QMessageBox.critical(self, qApp.organizationName(), unicode(inst)) except Exception as inst: logging.critical(unicode(inst)) QMessageBox.critical(self, qApp.organizationName(), "Hubo un problema al intentar imprimir" + " su reporte") def on_webview_loadProgress(self, progress): """ Muestra el progreso de la carga del reporte en un progressBar """ self.printProgressBar.setValue(progress) def on_webview_loadFinished(self, status): if self.printProgressBar.isVisible(): self.printProgressBar.hide() if not status: QMessageBox.critical(self, qApp.organizationName(), "El reporte no se pudo cargar") logging.error("No se pudo cargar el reporte") self.loaded = True printdialog = QPrintDialog(self.printer, self) if printdialog.exec_() == QDialog.Accepted: self.webview.print_(self.printer) del self.webview def deleteRow(self): """ Funcion usada para borrar lineas de la tabla """ index = self.tabledetails.currentIndex() if not index.isValid(): return row = index.row() self.editmodel.removeRows(row, 1) self.updateLabels() def updateLabels(self): """ Este metodo se llama para actualizar las etiquetas de totales en el formulario """ raise NotImplementedError() def createActions(self): """ Crea las acciones predefinidas del sistema """ self.actionNew = self.createAction( text="Nuevo", tip="Crear un nuevo documento", icon=QIcon.fromTheme("document-new", QIcon(":/icons/res/document-new.png")), shortcut="Ctrl+n", slot=self.newDocument, ) self.actionPreview = self.createAction( text="Previsualizar", tip=u"Vista de impresión del documento", icon=QIcon.fromTheme("document-preview", QIcon(":/icons/res/document-preview.png")), shortcut="Ctrl+p", slot=self.preview, ) self.actionPrint = self.createAction( text="Imprimir", tip="Imprimir el documento", icon=QIcon.fromTheme("document-print", QIcon(":/icons/res/document-print.png")), slot=self.printDocument, ) self.actionSave = self.createAction( text="Guardar", tip="Guardar el documento", icon=QIcon.fromTheme("document-save", QIcon(":/icons/res/document-save.png")), shortcut="Ctrl+g", slot=self.save, ) self.actionCancel = self.createAction( text="Cancelar", tip=u"Cancelar la creación del nuevo documento", icon=QIcon.fromTheme("dialog-cancel", QIcon(":/icons/res/dialog-cancel.png")), shortcut="Esc", slot=self.cancel, ) # edicion, TODO: QUE FUNCIONEN ESTAS ACCIONES self.actionCopy = self.createAction( text="Copiar", icon=QIcon.fromTheme("edit-copy", QIcon(":/icons/res/edit-copy.png")), shortcut="Ctrl+c" ) self.actionCut = self.createAction( text="Cortar", icon=QIcon.fromTheme("edit-cut", QIcon(":/icons/res/edit-cut.png")), shortcut="Ctrl+x" ) self.actionPaste = self.createAction(text="Pegar", icon=":/icons/res/edit-paste.png", shortcut="Ctrl+v") # navegación self.actionGoFirst = self.createAction( text="Primer documento", tip="Ir al primer documento", icon=QIcon.fromTheme("go-first", QIcon(":/icons/res/go-first.png")), slot=functools.partial(self.navigate, "first"), ) self.actionGoPrevious = self.createAction( text="Documento anterior", tip="Ir al documento anterior", icon=QIcon.fromTheme("go-previous", QIcon(":/icons/res/go-previous.png")), slot=functools.partial(self.navigate, "previous"), ) self.actionGoLast = self.createAction( text="Ultimo documento", tip="Ir al ultimo documento", icon=QIcon.fromTheme("go-last", QIcon(":/icons/res/go-last.png")), slot=functools.partial(self.navigate, "last"), ) self.actionGoNext = self.createAction( text="Documento siguiente", tip="Ir al siguiente documento", icon=QIcon.fromTheme("go-next", QIcon(":/icons/res/go-next.png")), slot=functools.partial(self.navigate, "next"), ) self.actionDeleteRow = self.createAction( text="Borrar la fila", icon=QIcon.fromTheme("edit-delete", QIcon(":/icons/res/edit-delete.png")), slot=self.deleteRow, ) self.addActionsToToolBar() def addActionsToToolBar(self): """ Añade las acciones predefinidas a la barra de tareas """ self.toolBar.addActions( [self.actionNew, self.actionPreview, self.actionPrint, self.actionSave, self.actionCancel] ) self.toolBar.addSeparator() self.toolBar.addActions( [self.actionGoFirst, self.actionGoPrevious, self.actionGoLast, self.actionGoNext, self.actionGoLast] ) @pyqtSlot() @if_edit_model def on_txtObservations_textChanged(self): """ Asignar las observaciones al editmodel """ self.editmodel.observations = self.txtObservations.toPlainText().strip()