def exportAsPdf(self): self.repaintModel(controls=False) filename, fileFilter = QFileDialog.getSaveFileName( self, self.tr('Save Model As PDF'), '', self.tr('PDF files (*.pdf *.PDF)')) if not filename: return if not filename.lower().endswith('.pdf'): filename += '.pdf' totalRect = self.scene.itemsBoundingRect() totalRect.adjust(-10, -10, 10, 10) printerRect = QRectF(0, 0, totalRect.width(), totalRect.height()) printer = QPrinter() printer.setOutputFormat(QPrinter.PdfFormat) printer.setOutputFileName(filename) printer.setPaperSize(QSizeF(printerRect.width(), printerRect.height()), QPrinter.DevicePixel) printer.setFullPage(True) painter = QPainter(printer) self.scene.render(painter, printerRect, totalRect) painter.end() self.bar.pushMessage("", self.tr("Model was correctly exported as PDF"), level=Qgis.Success, duration=5) self.repaintModel(controls=True)
def exportAsPdf(self): self.repaintModel(controls=False) filename, fileFilter = QFileDialog.getSaveFileName(self, self.tr('Save Model As PDF'), '', self.tr('PDF files (*.pdf *.PDF)')) if not filename: return if not filename.lower().endswith('.pdf'): filename += '.pdf' totalRect = self.scene.itemsBoundingRect() totalRect.adjust(-10, -10, 10, 10) printerRect = QRectF(0, 0, totalRect.width(), totalRect.height()) printer = QPrinter() printer.setOutputFormat(QPrinter.PdfFormat) printer.setOutputFileName(filename) printer.setPaperSize(QSizeF(printerRect.width(), printerRect.height()), QPrinter.DevicePixel) printer.setFullPage(True) painter = QPainter(printer) self.scene.render(painter, printerRect, totalRect) painter.end() self.bar.pushMessage("", self.tr("Successfully exported model as PDF to <a href=\"{}\">{}</a>").format(QUrl.fromLocalFile(filename).toString(), QDir.toNativeSeparators(filename)), level=Qgis.Success, duration=5) self.repaintModel(controls=True)
def testPrintIterator(self): project, layout = self.prepareIteratorLayout() atlas = layout.atlas() # setup settings settings = QgsLayoutExporter.PrintExportSettings() settings.dpi = 80 settings.rasterizeWholeImage = False pdf_path = os.path.join(self.basetestpath, 'test_printiterator.pdf') # make a qprinter directed to pdf printer = QPrinter() printer.setOutputFileName(pdf_path) printer.setOutputFormat(QPrinter.PdfFormat) result, error = QgsLayoutExporter.print(atlas, printer, settings) self.assertEqual(result, QgsLayoutExporter.Success, error) rendered_page_1 = os.path.join(self.basetestpath, 'test_printiterator1.png') pdfToPng(pdf_path, rendered_page_1, dpi=80, page=1) self.assertTrue(self.checkImage('printeriterator1', 'iteratortoimage1', rendered_page_1, size_tolerance=2)) rendered_page_2 = os.path.join(self.basetestpath, 'test_printiterator2.png') pdfToPng(pdf_path, rendered_page_2, dpi=80, page=2) self.assertTrue(self.checkImage('printiterator2', 'iteratortoimage2', rendered_page_2, size_tolerance=2)) rendered_page_3 = os.path.join(self.basetestpath, 'test_printiterator3.png') pdfToPng(pdf_path, rendered_page_3, dpi=80, page=3) self.assertTrue(os.path.exists(rendered_page_3)) rendered_page_4 = os.path.join(self.basetestpath, 'test_printiterator4.png') pdfToPng(pdf_path, rendered_page_4, dpi=80, page=4) self.assertTrue(os.path.exists(rendered_page_4))
def save_pdf_format(settings_path, title, text): settings = QSettings() new_filename, filter = QFileDialog.getSaveFileName( None, QCoreApplication.translate("Asistente-LADM-COL", "Export to PDF"), settings.value(settings_path, '.'), filter="PDF (*.pdf)") if new_filename: settings.setValue(settings_path, os.path.dirname(new_filename)) new_filename = new_filename if new_filename.lower().endswith( ".pdf") else "{}.pdf".format(new_filename) txt_log = QTextEdit() txt_log.setHtml("{}<br>{}".format(title, text)) printer = QPrinter() printer.setPageSize(QPrinter.Letter) printer.setOutputFormat(QPrinter.PdfFormat) printer.setOutputFileName(new_filename) txt_log.print(printer) msg = QCoreApplication.translate( "Asistente-LADM-COL", "Report successfully generated in folder <a href='file:///{normalized_path}'>{path}</a>!" ).format(normalized_path=normalize_local_url(new_filename), path=new_filename) Logger().success_msg(__name__, msg)
def exportAsPdf(self): self.repaintModel(controls=False) filename, fileFilter = QFileDialog.getSaveFileName(self, self.tr('Save Model As PDF'), '', self.tr('PDF files (*.pdf *.PDF)')) if not filename: return if not filename.lower().endswith('.pdf'): filename += '.pdf' totalRect = self.scene.itemsBoundingRect() totalRect.adjust(-10, -10, 10, 10) printerRect = QRectF(0, 0, totalRect.width(), totalRect.height()) printer = QPrinter() printer.setOutputFormat(QPrinter.PdfFormat) printer.setOutputFileName(filename) printer.setPaperSize(QSizeF(printerRect.width(), printerRect.height()), QPrinter.DevicePixel) printer.setFullPage(True) painter = QPainter(printer) self.scene.render(painter, printerRect, totalRect) painter.end() self.bar.pushMessage("", "Model was correctly exported as PDF", level=Qgis.Success, duration=5) self.repaintModel(controls=True)
def export_dock_content(self, output_format: OutputFormats): """ Export the current displayed metadata sheet to the given format. """ layer_name = iface.activeLayer().name() file_path = os.path.join( self.settings.value("UI/lastFileNameWidgetDir"), '{name}.{ext}'.format(name=layer_name, ext=output_format.value['ext'])) output_file = QFileDialog.getSaveFileName( self, tr("Save File as {format}").format( format=output_format.value['label']), file_path, "{label} (*.{ext})".format( label=output_format.value['label'], ext=output_format.value['ext'], )) if output_file[0] == '': return self.settings.setValue("UI/lastFileNameWidgetDir", os.path.dirname(output_file[0])) if output_format == OutputFormats.Pdf: printer = QPrinter() printer.setOutputFormat(QPrinter.PdfFormat) printer.setPageMargins(20, 20, 20, 20, QPrinter.Millimeter) printer.setOutputFileName(output_file[0]) self.viewer.print(printer) iface.messageBar().pushSuccess( tr("Export PDF"), tr("The metadata has been exported as PDF successfully")) elif output_format in [OutputFormats.Html, OutputFormats.Dcat]: if output_format == OutputFormats.Html: data_str = self.viewer.page().currentFrame().toHtml() else: sql = self.sql_for_layer(self.current_datasource_uri, output_format=OutputFormats.Dcat) data = self.current_connection.executeSql(sql) with open(resources_path('xml', 'dcat.xml')) as xml_file: xml_template = xml_file.read() locale = QgsSettings().value("locale/userLocale", QLocale().name()) locale = locale.split('_')[0].lower() xml = parseString( xml_template.format(locale=locale, content=data[0][0])) data_str = xml.toprettyxml() file_writer = open(output_file[0], "w") file_writer.write(data_str) file_writer.close() iface.messageBar().pushSuccess( tr("Export") + ' ' + output_format.value['label'], tr("The metadata has been exported as {format} successfully"). format(format=output_format.value['label']))
def testPrint(self): l = QgsLayout(QgsProject.instance()) l.initializeDefaults() # add a second page page2 = QgsLayoutItemPage(l) page2.setPageSize('A5') l.pageCollection().addPage(page2) # add some items item1 = QgsLayoutItemShape(l) item1.attemptSetSceneRect(QRectF(10, 20, 100, 150)) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.green) fill.setStrokeStyle(Qt.NoPen) item1.setSymbol(fill_symbol) l.addItem(item1) item2 = QgsLayoutItemShape(l) item2.attemptSetSceneRect(QRectF(10, 20, 100, 150)) item2.attemptMove(QgsLayoutPoint(10, 20), page=1) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.cyan) fill.setStrokeStyle(Qt.NoPen) item2.setSymbol(fill_symbol) l.addItem(item2) exporter = QgsLayoutExporter(l) # setup settings settings = QgsLayoutExporter.PrintExportSettings() settings.dpi = 80 settings.rasterizeWholeImage = False pdf_file_path = os.path.join(self.basetestpath, 'test_printdpi.pdf') # make a qprinter directed to pdf printer = QPrinter() printer.setOutputFileName(pdf_file_path) printer.setOutputFormat(QPrinter.PdfFormat) self.assertEqual(exporter.print(printer, settings), QgsLayoutExporter.Success) self.assertTrue(os.path.exists(pdf_file_path)) rendered_page_1 = os.path.join(self.basetestpath, 'test_exporttopdfdpi.png') dpi = 80 pdfToPng(pdf_file_path, rendered_page_1, dpi=dpi, page=1) rendered_page_2 = os.path.join(self.basetestpath, 'test_exporttopdfdpi2.png') pdfToPng(pdf_file_path, rendered_page_2, dpi=dpi, page=2) self.assertTrue(self.checkImage('printdpi_page1', 'exporttopdfdpi_page1', rendered_page_1, size_tolerance=1)) self.assertTrue(self.checkImage('printdpi_page2', 'exporttopdfdpi_page2', rendered_page_2, size_tolerance=1))
def export_title_text_to_pdf(filepath, title, text): filepath = filepath if filepath.lower().endswith( ".pdf") else "{}.pdf".format(filepath) txt_log = QTextEdit() txt_log.setHtml("{}<br>{}".format(title, text)) printer = QPrinter() printer.setPageSize(QPrinter.Letter) printer.setOutputFormat(QPrinter.PdfFormat) printer.setOutputFileName(filepath) txt_log.print(printer)
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 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))
def _get_layout_pdf_image(self, width, height, dpi): pdfpath = getTempfilePath('pdf') temp_size = os.path.getsize(pdfpath) p = QPrinter() p.setOutputFormat(QPrinter.PdfFormat) p.setOutputFileName(pdfpath) p.setPaperSize( QSizeF(self._c.pageCollection().page(0).sizeWithUnits().width(), self._c.pageCollection().page(0).sizeWithUnits().height()), QPrinter.Millimeter) p.setFullPage(True) p.setColorMode(QPrinter.Color) p.setResolution(self._c.renderContext().dpi()) pdf_p = QPainter(p) # page_mm = p.pageRect(QPrinter.Millimeter) # page_px = p.pageRect(QPrinter.DevicePixel) # self._c.render(pdf_p, page_px, page_mm) exporter = QgsLayoutExporter(self._c) exporter.renderPage(pdf_p, 0) pdf_p.end() if temp_size == os.path.getsize(pdfpath): return False, '' filepath = getTempfilePath('png') # Poppler (pdftocairo or pdftoppm): # PDFUTIL -png -singlefile -r 72 -x 0 -y 0 -W 420 -H 280 in.pdf pngbase # muPDF (mudraw): # PDFUTIL -c rgb[a] -r 72 -w 420 -h 280 -o out.png in.pdf if PDFUTIL.strip().endswith('pdftocairo'): filebase = os.path.join( os.path.dirname(filepath), os.path.splitext(os.path.basename(filepath))[0]) call = [ PDFUTIL, '-png', '-singlefile', '-r', str(dpi), '-x', '0', '-y', '0', '-W', str(width), '-H', str(height), pdfpath, filebase ] elif PDFUTIL.strip().endswith('mudraw'): call = [ PDFUTIL, '-c', 'rgba', '-r', str(dpi), '-w', str(width), '-h', str(height), # '-b', '8', '-o', filepath, pdfpath ] else: return False, '' qDebug("_get_layout_pdf_image call: {0}".format(' '.join(call))) res = False try: subprocess.check_call(call) res = True except subprocess.CalledProcessError as e: qDebug("_get_layout_pdf_image failed!\n" "cmd: {0}\n" "returncode: {1}\n" "message: {2}".format(e.cmd, e.returncode, e.message)) if not res: os.unlink(filepath) filepath = '' return res, filepath
class WeightDataDialog(QDialog, FORM_CLASS): """ Modal dialog allowing to select weights in a d3.js visualization """ # QVariantMap is to map a JSON to dict see: # http://pyqt.sourceforge.net/Docs/PyQt4/incompatibilities.html#pyqt4-v4-7-4 # this is for javascript to emit when it changes the json json_updated = pyqtSignal(['QVariantMap'], name='json_updated') # Python classes should connect to json_cleaned json_cleaned = pyqtSignal(['QVariantMap'], name='json_cleaned') def __init__(self, iface, project_definition): self.iface = iface QDialog.__init__(self) # Set up the user interface from Designer. self.setupUi(self) self.ok_button = self.buttonBox.button(QDialogButtonBox.Ok) self.added_attrs_ids = set() self.discarded_feats = set() self.any_changes_made = False # keep track of changes made to the tree while on-the-fly calculations # are off (the tree has changed, but indices haven't been recalculated) self.modified_project_definition = None self.active_layer_numeric_fields = [] self.active_layer_numeric_fields_aliases = [] self.update_active_layer_numeric_fields() # keep track of the fact that the user has explicitly selected a field # to base the style on. Note that also the selection of the empty item # means that the user explicitly wants the system to use the default # behavior. self.style_by_field_selected = False self.project_definition = deepcopy(project_definition) try: proj_title = self.project_definition['title'] except KeyError: proj_title = 'Untitled' dialog_title = ('Set weights and operators for project: "%s"' % proj_title) self.setWindowTitle(dialog_title) self.web_view = self.web_view self.web_view.page().mainFrame().setScrollBarPolicy( Qt.Vertical, Qt.ScrollBarAlwaysOff) self.web_view.page().mainFrame().setScrollBarPolicy( Qt.Horizontal, Qt.ScrollBarAlwaysOff) self.web_view.load(QUrl('qrc:/plugins/irmt/weight_data.html')) self.printer = QPrinter(QPrinter.HighResolution) self.printer.setPageSize(QPrinter.A4) self.printer.setOutputFormat(QPrinter.PdfFormat) self.printer.setPrintRange(QPrinter.AllPages) self.printer.setOrientation(QPrinter.Portrait) self.printer.setDocName(proj_title) self.printer.setCreator( 'GEM Integrated Risk Modelling Toolkit QGIS Plugin') self.frame = self.web_view.page().mainFrame() self.frame.javaScriptWindowObjectCleared.connect(self.setup_js) self.web_view.loadFinished.connect(self.show_tree) self.json_updated.connect(self.handle_json_updated) self.populate_style_by_field_cbx() if not DEBUG: self.web_view.setContextMenuPolicy(Qt.NoContextMenu) self.web_view.settings().setAttribute(QWebSettings.JavascriptEnabled, True) def closeEvent(self, event): confirmation_on_close(self, event) def reject(self): confirmation_on_close(self) def update_project_definition(self, project_definition): self.project_definition = deepcopy(project_definition) self.populate_style_by_field_cbx() def update_active_layer_numeric_fields(self): self.active_layer_numeric_fields = [ field.name() for field in self.iface.activeLayer().fields() if field.typeName() in NUMERIC_FIELD_TYPES ] self.active_layer_numeric_fields_aliases = [ self.iface.activeLayer().attributeAlias(field_idx) for field_idx, field in enumerate(self.iface.activeLayer().fields()) if field.typeName() in NUMERIC_FIELD_TYPES ] def populate_style_by_field_cbx(self): self.update_active_layer_numeric_fields() fields_in_proj_def = get_field_names(self.project_definition) fields_for_styling = [ field for field in self.active_layer_numeric_fields if field in fields_in_proj_def ] # block signals to avoid performing the onchange actions while adding # items programmatically self.style_by_field_cbx.blockSignals(True) self.style_by_field_cbx.clear() self.style_by_field_cbx.addItem('') self.style_by_field_cbx.addItems(fields_for_styling) if 'style_by_field' in self.project_definition: idx = self.style_by_field_cbx.findText( self.project_definition['style_by_field']) self.style_by_field_cbx.setCurrentIndex(idx) # reactivate the signals, so the user's changes will trigger something self.style_by_field_cbx.blockSignals(False) def setup_js(self): # pass a reference (called qt_page) of self to the JS world # to expose a member of self to js you need to declare it as property # see for example self.json_str() if DEBUG: log_msg("######################### for weight_data_debug.html") self.print_self_for_debug() log_msg("######################### end for weight_data_debug.html") self.frame.addToJavaScriptWindowObject('qt_page', self) def show_tree(self): # start the tree self.frame.evaluateJavaScript('init_tree()') def handle_json_updated(self, data): self.any_changes_made = True if DEBUG: import pprint ppdata = pprint.pformat(data, indent=4) log_msg('in handle_json_updated, data=\n%s' % ppdata) if self.on_the_fly_ckb.isChecked(): self.project_definition = self.clean_json([data]) self._manage_style_by_field() self.json_cleaned.emit(self.project_definition) # nothing has changed since the last recalculation self.modified_project_definition = None else: # keep track of the current status of the project definition # as it is in the d3 tree, so it can be used when OK is pressed self.modified_project_definition = self.clean_json([data]) def _manage_style_by_field(self): if self.style_by_field_selected: if self.style_by_field_cbx.currentText(): self.project_definition['style_by_field'] = \ self.style_by_field_cbx.currentText() elif 'style_by_field' in self.project_definition: # if the empty item is selected, clean the project definition del self.project_definition['style_by_field'] def clean_json(self, data): # this method takes a list of dictionaries and removes some unneeded # keys. It recurses into the children elements if data == []: return data ignore_keys = ['depth', 'x', 'y', 'id', 'x0', 'y0', 'parent'] for element in data: for key in ignore_keys: element.pop(key, None) if 'children' in element: self.clean_json(element['children']) # return the main element return data[0] @pyqtSlot() def on_print_btn_clicked(self): dest_full_path_name = ask_for_destination_full_path_name( self, filter='Pdf files (*.pdf)') if not dest_full_path_name: return self.printer.setOutputFileName(dest_full_path_name) try: self.web_view.print_(self.printer) except Exception as exc: msg = 'It was impossible to create the pdf' log_msg(msg, level='C', message_bar=self.iface.messageBar(), exception=exc) else: msg = ('Project definition printed as pdf and saved to: %s' % dest_full_path_name) log_msg(msg, level='S', message_bar=self.iface.messageBar()) @pyqtSlot(str) def on_style_by_field_cbx_currentIndexChanged(self): self.style_by_field_selected = True self._manage_style_by_field() self.json_updated.emit(self.project_definition) @pyqtProperty(str) def json_str(self): # This method gets exposed to JS thanks to @pyqtProperty(str) return json.dumps(self.project_definition, sort_keys=False, indent=2, separators=(',', ': ')) @pyqtProperty(str) def DEFAULT_OPERATOR(self): return DEFAULT_OPERATOR @pyqtProperty(bool) def DEV_MODE(self): developer_mode = QSettings().value('/irmt/developer_mode', True, type=bool) return developer_mode @pyqtProperty(str) def OPERATORS(self): return ';'.join(list(OPERATORS_DICT.values())) @pyqtProperty(str) def ACTIVE_LAYER_NUMERIC_FIELDS(self): return ';'.join(self.active_layer_numeric_fields) @pyqtProperty(str) def ACTIVE_LAYER_NUMERIC_FIELDS_ALIASES(self): return ';'.join(self.active_layer_numeric_fields_aliases) @pyqtProperty(str) def NODE_TYPES(self): return ';'.join(["%s:%s" % (k, v) for k, v in NODE_TYPES.items()]) def print_self_for_debug(self): msg = """ var qt_page = { ACTIVE_LAYER_NUMERIC_FIELDS: "%s", ACTIVE_LAYER_NUMERIC_FIELDS_ALIASES: "%s", DEFAULT_OPERATOR: "%s", NODE_TYPES: "%s", OPERATORS: "%s", json_str: '%s', json_updated: function (updated_json_str) { console.log("json_updated signal emitted with this JSON:"); console.log(updated_json_str) }, DEV_MODE: %s };""" % (self.ACTIVE_LAYER_NUMERIC_FIELDS, self.ACTIVE_LAYER_NUMERIC_FIELDS_ALIASES, self.DEFAULT_OPERATOR, self.NODE_TYPES, self.OPERATORS, self.json_str.replace('\n', ''), str(self.DEV_MODE).lower()) log_msg(msg)
def _get_composer_pdf_image(self, width, height, dpi): pdfpath = getTempfilePath('pdf') temp_size = os.path.getsize(pdfpath) p = QPrinter() p.setOutputFormat(QPrinter.PdfFormat) p.setOutputFileName(pdfpath) p.setPaperSize(QSizeF(self._c.paperWidth(), self._c.paperHeight()), QPrinter.Millimeter) p.setFullPage(True) p.setColorMode(QPrinter.Color) p.setResolution(self._c.printResolution()) pdf_p = QPainter(p) # page_mm = p.pageRect(QPrinter.Millimeter) # page_px = p.pageRect(QPrinter.DevicePixel) # self._c.render(pdf_p, page_px, page_mm) self._c.renderPage(pdf_p, 0) pdf_p.end() if temp_size == os.path.getsize(pdfpath): return False, '' filepath = getTempfilePath('png') # Poppler (pdftocairo or pdftoppm): # PDFUTIL -png -singlefile -r 72 -x 0 -y 0 -W 420 -H 280 in.pdf pngbase # muPDF (mudraw): # PDFUTIL -c rgb[a] -r 72 -w 420 -h 280 -o out.png in.pdf if PDFUTIL.strip().endswith('pdftocairo'): filebase = os.path.join( os.path.dirname(filepath), os.path.splitext(os.path.basename(filepath))[0] ) call = [ PDFUTIL, '-png', '-singlefile', '-r', str(dpi), '-x', '0', '-y', '0', '-W', str(width), '-H', str(height), pdfpath, filebase ] elif PDFUTIL.strip().endswith('mudraw'): call = [ PDFUTIL, '-c', 'rgba', '-r', str(dpi), '-w', str(width), '-h', str(height), # '-b', '8', '-o', filepath, pdfpath ] else: return False, '' qDebug("_get_composer_pdf_image call: {0}".format(' '.join(call))) res = False try: subprocess.check_call(call) res = True except subprocess.CalledProcessError as e: qDebug("_get_composer_pdf_image failed!\n" "cmd: {0}\n" "returncode: {1}\n" "message: {2}".format(e.cmd, e.returncode, e.message)) if not res: os.unlink(filepath) filepath = '' return res, filepath
def CreatePDF(self, task, out, timestamp, data, frame, rows, columns, fileName, VManager): ''' Create PDF QgsTask ''' font_normal = QFont("Helvetica", 8, QFont.Normal) font_bold = QFont("Helvetica", 9, QFont.Bold) printer = QPrinter(QPrinter.HighResolution) printer.setOutputFormat(QPrinter.PdfFormat) printer.setPageSize(QPrinter.A4) printer.setOutputFileName(out) printer.setFullPage(True) document = QTextDocument() document.setDefaultFont(font_normal) document.setPageSize(printer.paperSize(QPrinter.Point)); cursor = QTextCursor(document) video_t = QCoreApplication.translate("QgsFmvMetadata", "Video : ") time_t = QCoreApplication.translate("QgsFmvMetadata", "TimeStamp : ") cursor.insertHtml( """ <p style='text-align: center;'> <img style='display: block; margin-left: auto; margin-right: auto;' src=\':/imgFMV/images/header_logo.png\' width='200' height='25' /> <p style='text-align: center;'> <strong>%s</strong>%s<strong> <p style='text-align: center;'> <strong>%s</strong>%s <p></p> """ % (video_t, fileName, time_t, timestamp)) tableFormat = QTextTableFormat() tableFormat.setBorderBrush(QBrush(Qt.black)) tableFormat.setAlignment(Qt.AlignHCenter) tableFormat.setHeaderRowCount(1) tableFormat.setCellPadding(2) tableFormat.setCellSpacing(2) cursor.insertTable(rows + 1, columns, tableFormat) tableHeaderFormat = QTextCharFormat() tableHeaderFormat.setFont(font_bold) tableHeaderFormat.setBackground(QColor("#67b03a")) tableHeaderFormat.setForeground(Qt.white) tableHeaderFormat.setVerticalAlignment(QTextCharFormat.AlignMiddle) alternate_background = QTextCharFormat() alternate_background.setBackground(QColor("#DDE9ED")) for column in range(columns): cursor.mergeBlockCharFormat(tableHeaderFormat) cursor.insertText(VManager.horizontalHeaderItem( column).text()) cursor.movePosition(QTextCursor.NextCell) row = 1 for key in sorted(data.keys()): values = [str(key), str(data[key][0]),str(data[key][1])] for column in range(columns): cursor.insertText(values[column]) if (row) % 2 == 0: cursor.mergeBlockCharFormat(alternate_background) cursor.movePosition(QTextCursor.NextCell) row += 1 cursor.movePosition(QTextCursor.End) current_t = QCoreApplication.translate("QgsFmvMetadata", "Current Frame") self.TextBlockCenter(cursor, TextFormat= QTextFormat.PageBreak_AlwaysBefore) cursor.insertHtml(""" <br><p style='text-align: center;'><strong>""" + current_t +"""</strong></p><br> """) self.TextBlockCenter(cursor) cursor.insertImage(frame.scaledToWidth(500, Qt.SmoothTransformation)) document.print_(printer) if task.isCanceled(): return None return {'task': task.description()}
class ReportWorker(AbstractWorker): """Worker class handling report generation""" def __init__(self, out_dir): super().__init__() self.out_dir = out_dir self.current_step = 1 # setup QPrinter self.printer = QPrinter() self.printer.setPageSize(QPrinter.A4) self.printer.setFullPage(True) self.printer.setOutputFormat(QPrinter.PdfFormat) templates_path = os.path.join(os.path.dirname(__file__), "report_templates") # load templates with open(os.path.join(templates_path, "infrastrutture_tmpl.html"), "r") as f: self.infrastrutture_tmpl = Template(f.read()) with open(os.path.join(templates_path, "aree_emerg_tmpl.html"), "r") as f: self.aree_emerg_tmpl = Template(f.read()) with open(os.path.join(templates_path, "aggregati_tmpl.html"), "r") as f: self.aggregati_tmpl = Template(f.read()) with open(os.path.join(templates_path, "edifici_tmpl.html"), "r") as f: self.edifici_tmpl = Template(f.read()) with open(os.path.join(templates_path, "unita_strutt_tmpl.html"), "r") as f: self.unita_strutt_tmpl = Template(f.read()) # load lookup tables self.tipo_infra_dict = self._gen_codes_dict("vw_tipo_infra") self.pav_per_dict = self._gen_codes_dict("vw_pav_per") self.ost_disc_dict = self._gen_codes_dict("vw_ost_disc") self.morf_dict = self._gen_codes_dict("vw_morf") self.zona_ms_dict = self._gen_codes_dict("vw_zona_ms") self.falda_dict = self._gen_codes_dict("vw_falda") self.acq_sup_dict = self._gen_codes_dict("vw_acq_sup") self.pai_dict = self._gen_codes_dict("vw_pai") self.tipo_area_dict = self._gen_codes_dict("vw_tipo_area") self.piano_dict = self._gen_codes_dict("vw_piano") self.infra_acq_dict = self._gen_codes_dict("vw_infra_acq") self.infra_ele_dict = self._gen_codes_dict("vw_infra_ele") self.infra_fog_dict = self._gen_codes_dict("vw_infra_fog") self.posizio_dict = self._gen_codes_dict("vw_posizio") self.specialis_dict = self._gen_codes_dict("vw_specialis") self.n_interr_dict = self._gen_codes_dict("vw_n_interr") self.alt_piano_dict = self._gen_codes_dict("vw_alt_piano") self.strutt_ver_dict = self._gen_codes_dict("vw_strutt_ver") self.tipo_mur_dict = self._gen_codes_dict("vw_tipo_mur") self.danno_dict = self._gen_codes_dict("vw_danno") self.stato_man_dict = self._gen_codes_dict("vw_stato_man") self.id_edif_dict = self._gen_codes_dict("vw_id_edif") self.uso_att_dict = self._gen_codes_dict("vw_uso_att") self.evento_dict = self._gen_codes_dict("vw_evento") self.tipo_evento_dict = self._gen_codes_dict("vw_tipo") self.verif_sism_dict = self._gen_codes_dict("vw_verif_sism") self.utilizz_dict = self._gen_codes_dict("vw_utilizz") def _gen_codes_dict(self, lookup_table_name): """Generate dictionary with codes from lookup table""" lookup_table = QgsProject.instance().mapLayersByName( lookup_table_name)[0] dict = {} for f in lookup_table.getFeatures(): dict[f["cod"]] = f["descrizione"] return dict def work(self): root = QgsProject.instance().layerTreeRoot() cle_group = root.findGroup("CLE") cle_layer_nodes = cle_group.children() for node in cle_layer_nodes: self.set_message.emit( f"Generating reports for {node.layer().name()}...") features = node.layer().getFeatures() cnt = 0 for feature in features: self.generate_report(node.layer().name(), feature) cnt += 1 self.progress.emit(int(cnt * 100 / node.layer().featureCount())) if self.killed: break if self.killed: raise UserAbortedNotification("User aborted") return "Task completed!" def generate_report(self, layer_name, feature): # self.set_message.emit(f'Generating report for {feature["ID_AC"]} ({layer_name})') # dictionary with field names and values of the feature attrs_dict = dict(zip(feature.fields().names(), feature.attributes())) html = None if layer_name.startswith("Infrastrutture"): pdf_name = f"{feature['ID_AC']}.pdf" if not os.path.exists(os.path.join(self.out_dir, "Infrastrutture")): os.mkdir(os.path.join(self.out_dir, "Infrastrutture")) pdf_path = os.path.join(self.out_dir, "Infrastrutture", pdf_name) self.printer.setOutputFileName(pdf_path) # substitute codes with corresponding values from lookup tables attrs_dict["tipo_infra"] = self.tipo_infra_dict[ attrs_dict["tipo_infra"]] attrs_dict["strade_a"] = "☑" if attrs_dict[ "strade_a"] == "true" else "☐" attrs_dict["strade_b"] = "☑" if attrs_dict[ "strade_b"] == "true" else "☐" attrs_dict["strade_c"] = "☑" if attrs_dict[ "strade_c"] == "true" else "☐" attrs_dict["strade_d"] = "☑" if attrs_dict[ "strade_d"] == "true" else "☐" attrs_dict["strade_e"] = "☑" if attrs_dict[ "strade_e"] == "true" else "☐" attrs_dict["strade_f"] = "☑" if attrs_dict[ "strade_f"] == "true" else "☐" attrs_dict["pav_per"] = self.pav_per_dict[attrs_dict["pav_per"]] attrs_dict["ost_disc"] = self.ost_disc_dict[attrs_dict["ost_disc"]] attrs_dict["morf"] = self.morf_dict[attrs_dict["morf"]] attrs_dict["ubic_sotto"] = "☑" if attrs_dict[ "ubic_sotto"] == "true" else "☐" attrs_dict["ubic_sopra"] = "☑" if attrs_dict[ "ubic_sopra"] == "true" else "☐" attrs_dict["zona_ms"] = self.zona_ms_dict[attrs_dict["zona_ms"]] attrs_dict["inst_fran"] = "☑" if attrs_dict[ "inst_fran"] == "true" else "☐" attrs_dict["inst_liq"] = "☑" if attrs_dict[ "inst_liq"] == "true" else "☐" attrs_dict["inst_fag"] = "☑" if attrs_dict[ "inst_fag"] == "true" else "☐" attrs_dict["inst_ced"] = "☑" if attrs_dict[ "inst_ced"] == "true" else "☐" attrs_dict["inst_cav"] = "☑" if attrs_dict[ "inst_cav"] == "true" else "☐" attrs_dict["frana_AC"] = "☑" if attrs_dict[ "frana_AC"] == "true" else "☐" attrs_dict["frana_mon"] = "☑" if attrs_dict[ "frana_mon"] == "true" else "☐" attrs_dict["frana_val"] = "☑" if attrs_dict[ "frana_val"] == "true" else "☐" attrs_dict["falda"] = self.falda_dict[attrs_dict["falda"]] attrs_dict["acq_sup"] = self.acq_sup_dict[attrs_dict["acq_sup"]] attrs_dict["pai"] = self.pai_dict[attrs_dict["pai"]] attrs_dict["alluvio"] = "☑" if attrs_dict[ "alluvio"] == "true" else "☐" html = self.infrastrutture_tmpl.substitute(attrs_dict) elif layer_name.startswith("Aree"): pdf_name = f"{feature['ID_AE']}.pdf" if not os.path.exists(os.path.join(self.out_dir, "Aree_emergenza")): os.mkdir(os.path.join(self.out_dir, "Aree_emergenza")) pdf_path = os.path.join(self.out_dir, "Aree_emergenza", pdf_name) self.printer.setOutputFileName(pdf_path) # substitute codes with corresponding values from lookup tables attrs_dict["tipo_area"] = self.tipo_area_dict[ attrs_dict["tipo_area"]] attrs_dict["piano"] = self.piano_dict[attrs_dict["piano"]] attrs_dict["pav_per"] = self.pav_per_dict[attrs_dict["pav_per"]] attrs_dict["infra_acq"] = self.infra_acq_dict[ attrs_dict["infra_acq"]] attrs_dict["infra_ele"] = self.infra_ele_dict[ attrs_dict["infra_ele"]] attrs_dict["infra_fog"] = self.infra_fog_dict[ attrs_dict["infra_fog"]] attrs_dict["morf"] = self.morf_dict[attrs_dict["morf"]] attrs_dict["ubic_sotto"] = "☑" if attrs_dict[ "ubic_sotto"] == "true" else "☐" attrs_dict["ubic_sopra"] = "☑" if attrs_dict[ "ubic_sopra"] == "true" else "☐" attrs_dict["zona_ms"] = self.zona_ms_dict[attrs_dict["zona_ms"]] attrs_dict["inst_fran"] = "☑" if attrs_dict[ "inst_fran"] == "true" else "☐" attrs_dict["inst_liq"] = "☑" if attrs_dict[ "inst_liq"] == "true" else "☐" attrs_dict["inst_fag"] = "☑" if attrs_dict[ "inst_fag"] == "true" else "☐" attrs_dict["inst_ced"] = "☑" if attrs_dict[ "inst_ced"] == "true" else "☐" attrs_dict["inst_cav"] = "☑" if attrs_dict[ "inst_cav"] == "true" else "☐" attrs_dict["frana_AE"] = "☑" if attrs_dict[ "frana_AE"] == "true" else "☐" attrs_dict["frana_mon"] = "☑" if attrs_dict[ "frana_mon"] == "true" else "☐" attrs_dict["frana_val"] = "☑" if attrs_dict[ "frana_val"] == "true" else "☐" attrs_dict["falda"] = self.falda_dict[attrs_dict["falda"]] attrs_dict["acq_sup"] = self.acq_sup_dict[attrs_dict["acq_sup"]] attrs_dict["pai"] = self.pai_dict[attrs_dict["pai"]] attrs_dict["alluvio"] = "☑" if attrs_dict[ "alluvio"] == "true" else "☐" html = self.aree_emerg_tmpl.substitute(attrs_dict) elif layer_name.startswith("Aggregati"): pdf_name = f"{feature['ID_AS']}.pdf" if not os.path.exists( os.path.join(self.out_dir, "Aggregati_strutturali")): os.mkdir(os.path.join(self.out_dir, "Aggregati_strutturali")) pdf_path = os.path.join(self.out_dir, "Aggregati_strutturali", pdf_name) self.printer.setOutputFileName(pdf_path) # substitute codes with corresponding values from lookup tables attrs_dict["conn_volte"] = "☑" if attrs_dict[ "conn_volte"] == "true" else "☐" attrs_dict["conn_rifus"] = "☑" if attrs_dict[ "conn_rifus"] == "true" else "☐" attrs_dict["regol_1"] = "☑" if attrs_dict[ "regol_1"] == "true" else "☐" attrs_dict["regol_2"] = "☑" if attrs_dict[ "regol_2"] == "true" else "☐" attrs_dict["regol_3"] = "☑" if attrs_dict[ "regol_3"] == "true" else "☐" attrs_dict["regol_4"] = "☑" if attrs_dict[ "regol_4"] == "true" else "☐" attrs_dict["regol_5"] = "☑" if attrs_dict[ "regol_5"] == "true" else "☐" attrs_dict["vuln_1"] = "☑" if attrs_dict[ "vuln_1"] == "true" else "☐" attrs_dict["vuln_2"] = "☑" if attrs_dict[ "vuln_2"] == "true" else "☐" attrs_dict["vuln_3"] = "☑" if attrs_dict[ "vuln_3"] == "true" else "☐" attrs_dict["vuln_4"] = "☑" if attrs_dict[ "vuln_4"] == "true" else "☐" attrs_dict["vuln_5"] = "☑" if attrs_dict[ "vuln_5"] == "true" else "☐" attrs_dict["vuln_6"] = "☑" if attrs_dict[ "vuln_6"] == "true" else "☐" attrs_dict["rinfor_1"] = "☑" if attrs_dict[ "rinfor_1"] == "true" else "☐" attrs_dict["rinfor_2"] = "☑" if attrs_dict[ "rinfor_2"] == "true" else "☐" attrs_dict["morf"] = self.morf_dict[attrs_dict["morf"]] attrs_dict["ubic_sotto"] = "☑" if attrs_dict[ "ubic_sotto"] == "true" else "☐" attrs_dict["ubic_sopra"] = "☑" if attrs_dict[ "ubic_sopra"] == "true" else "☐" attrs_dict["zona_ms"] = self.zona_ms_dict[attrs_dict["zona_ms"]] attrs_dict["inst_fran"] = "☑" if attrs_dict[ "inst_fran"] == "true" else "☐" attrs_dict["inst_liq"] = "☑" if attrs_dict[ "inst_liq"] == "true" else "☐" attrs_dict["inst_fag"] = "☑" if attrs_dict[ "inst_fag"] == "true" else "☐" attrs_dict["inst_ced"] = "☑" if attrs_dict[ "inst_ced"] == "true" else "☐" attrs_dict["inst_cav"] = "☑" if attrs_dict[ "inst_cav"] == "true" else "☐" attrs_dict["frana_AS"] = "☑" if attrs_dict[ "frana_AS"] == "true" else "☐" attrs_dict["frana_mon"] = "☑" if attrs_dict[ "frana_mon"] == "true" else "☐" attrs_dict["frana_val"] = "☑" if attrs_dict[ "frana_val"] == "true" else "☐" attrs_dict["pai"] = self.pai_dict[attrs_dict["pai"]] attrs_dict["alluvio"] = "☑" if attrs_dict[ "alluvio"] == "true" else "☐" html = self.aggregati_tmpl.substitute(attrs_dict) elif layer_name.startswith("Edifici"): pdf_name = f"{feature['ID_ES']}.pdf" if not os.path.exists( os.path.join(self.out_dir, "Edifici_strategici")): os.mkdir(os.path.join(self.out_dir, "Edifici_strategici")) pdf_path = os.path.join(self.out_dir, "Edifici_strategici", pdf_name) self.printer.setOutputFileName(pdf_path) # substitute codes with corresponding values from lookup tables attrs_dict["isolato"] = "☑" if attrs_dict[ "isolato"] == "true" else "☐" attrs_dict["posizio"] = self.posizio_dict[attrs_dict["posizio"]] attrs_dict["fronte"] = "☑" if attrs_dict[ "fronte"] == "true" else "☐" attrs_dict["specialis"] = self.specialis_dict[attrs_dict[ "specialis"]] if attrs_dict["spec"] == "true" else "" attrs_dict["spec"] = "☑" if attrs_dict[ "spec"] == "true" else "☐" attrs_dict["n_interr"] = self.n_interr_dict[attrs_dict["n_interr"]] attrs_dict["alt_piano"] = self.alt_piano_dict[ attrs_dict["alt_piano"]] attrs_dict["vol_unico"] = "☑" if attrs_dict[ "vol_unico"] == "true" else "☐" attrs_dict["strutt_ver"] = self.strutt_ver_dict[ attrs_dict["strutt_ver"]] attrs_dict["tipo_mur"] = self.tipo_mur_dict[attrs_dict["tipo_mur"]] attrs_dict["cord_cat"] = "☑" if attrs_dict[ "cord_cat"] == "true" else "☐" attrs_dict["pilastri"] = "☑" if attrs_dict[ "pilastri"] == "true" else "☐" attrs_dict["pilotis"] = "☑" if attrs_dict[ "pilotis"] == "true" else "☐" attrs_dict["sopraelev"] = "☑" if attrs_dict[ "sopraelev"] == "true" else "☐" attrs_dict["danno"] = self.danno_dict[attrs_dict["danno"]] attrs_dict["stato_man"] = self.stato_man_dict[ attrs_dict["stato_man"]] attrs_dict["pr_pubb"] = "☑" if attrs_dict[ "pr_pubb"] == "true" else "☐" attrs_dict["pr_priv"] = "☑" if attrs_dict[ "pr_priv"] == "true" else "☐" attrs_dict["morf"] = self.morf_dict[attrs_dict["morf"]] attrs_dict["ubic_sotto"] = "☑" if attrs_dict[ "ubic_sotto"] == "true" else "☐" attrs_dict["ubic_sopra"] = "☑" if attrs_dict[ "ubic_sopra"] == "true" else "☐" attrs_dict["zona_ms"] = self.zona_ms_dict[attrs_dict["zona_ms"]] attrs_dict["inst_fran"] = "☑" if attrs_dict[ "inst_fran"] == "true" else "☐" attrs_dict["inst_liq"] = "☑" if attrs_dict[ "inst_liq"] == "true" else "☐" attrs_dict["inst_fag"] = "☑" if attrs_dict[ "inst_fag"] == "true" else "☐" attrs_dict["inst_ced"] = "☑" if attrs_dict[ "inst_ced"] == "true" else "☐" attrs_dict["inst_cav"] = "☑" if attrs_dict[ "inst_cav"] == "true" else "☐" attrs_dict["frana_ar"] = "☑" if attrs_dict[ "frana_ar"] == "true" else "☐" attrs_dict["frana_mon"] = "☑" if attrs_dict[ "frana_mon"] == "true" else "☐" attrs_dict["frana_val"] = "☑" if attrs_dict[ "frana_val"] == "true" else "☐" attrs_dict["pai"] = self.pai_dict[attrs_dict["pai"]] attrs_dict["alluvio"] = "☑" if attrs_dict[ "alluvio"] == "true" else "☐" attrs_dict["ID_edif"] = self.id_edif_dict[attrs_dict["ID_edif"]] attrs_dict["emerg_1"] = "☑" if attrs_dict[ "emerg_1"] == "true" else "☐" attrs_dict["emerg_2"] = "☑" if attrs_dict[ "emerg_2"] == "true" else "☐" attrs_dict["emerg_3"] = "☑" if attrs_dict[ "emerg_3"] == "true" else "☐" attrs_dict["emerg_4"] = "☑" if attrs_dict[ "emerg_4"] == "true" else "☐" attrs_dict["emerg_5"] = "☑" if attrs_dict[ "emerg_5"] == "true" else "☐" attrs_dict["emerg_6"] = "☑" if attrs_dict[ "emerg_6"] == "true" else "☐" attrs_dict["uso_orig"] = self.uso_att_dict[attrs_dict["uso_orig"]] attrs_dict["uso_att"] = self.uso_att_dict[attrs_dict["uso_att"]] attrs_dict["interv"] = "☑" if attrs_dict[ "interv"] == "true" else "☐" attrs_dict["interv_1"] = "☑" if attrs_dict[ "interv_1"] == "true" else "☐" attrs_dict["interv_2"] = "☑" if attrs_dict[ "interv_2"] == "true" else "☐" attrs_dict["interv_3"] = "☑" if attrs_dict[ "interv_3"] == "true" else "☐" attrs_dict["interv_4"] = "☑" if attrs_dict[ "interv_4"] == "true" else "☐" attrs_dict["interv_5"] = "☑" if attrs_dict[ "interv_5"] == "true" else "☐" attrs_dict["interv_6"] = "☑" if attrs_dict[ "interv_6"] == "true" else "☐" attrs_dict["interv_7"] = "☑" if attrs_dict[ "interv_7"] == "true" else "☐" attrs_dict["evento_1"] = self.evento_dict[ attrs_dict["evento_1"]] if attrs_dict["evento_1"] else "" attrs_dict["data_ev_1"] = attrs_dict["data_ev_1"] if attrs_dict[ "evento_1"] else "" attrs_dict["tipo_1"] = self.tipo_evento_dict[ attrs_dict["tipo_1"]] if attrs_dict["evento_1"] else "" attrs_dict["evento_2"] = self.evento_dict[ attrs_dict["evento_2"]] if attrs_dict["evento_2"] else "" attrs_dict["data_ev_2"] = attrs_dict["data_ev_2"] if attrs_dict[ "evento_2"] else "" attrs_dict["tipo_2"] = self.tipo_evento_dict[ attrs_dict["tipo_2"]] if attrs_dict["evento_2"] else "" attrs_dict["evento_3"] = self.evento_dict[ attrs_dict["evento_3"]] if attrs_dict["evento_3"] else "" attrs_dict["data_ev_3"] = attrs_dict["data_ev_3"] if attrs_dict[ "evento_3"] else "" attrs_dict["tipo_3"] = self.tipo_evento_dict[ attrs_dict["tipo_3"]] if attrs_dict["evento_3"] else "" attrs_dict["verif_sism"] = self.verif_sism_dict[ attrs_dict["verif_sism"]] html = self.edifici_tmpl.substitute(attrs_dict) elif layer_name.startswith("Unita"): pdf_name = f"{feature['ID_US']}.pdf" if not os.path.exists( os.path.join(self.out_dir, "Unita_strutturali")): os.mkdir(os.path.join(self.out_dir, "Unita_strutturali")) pdf_path = os.path.join(self.out_dir, "Unita_strutturali", pdf_name) self.printer.setOutputFileName(pdf_path) # substitute codes with corresponding values from lookup tables attrs_dict["isolato"] = "☑" if attrs_dict[ "isolato"] == "true" else "☐" attrs_dict["posizio"] = self.posizio_dict[attrs_dict["posizio"]] attrs_dict["fronte"] = "☑" if attrs_dict[ "fronte"] == "true" else "☐" attrs_dict["specialis"] = self.specialis_dict[attrs_dict[ "specialis"]] if attrs_dict["spec"] == "true" else "" attrs_dict["spec"] = "☑" if attrs_dict[ "spec"] == "true" else "☐" attrs_dict["n_interr"] = self.n_interr_dict[attrs_dict["n_interr"]] attrs_dict["alt_piano"] = self.alt_piano_dict[ attrs_dict["alt_piano"]] attrs_dict["vol_unico"] = "☑" if attrs_dict[ "vol_unico"] == "true" else "☐" attrs_dict["strutt_ver"] = self.strutt_ver_dict[ attrs_dict["strutt_ver"]] attrs_dict["tipo_mur"] = self.tipo_mur_dict[attrs_dict["tipo_mur"]] attrs_dict["cord_cat"] = "☑" if attrs_dict[ "cord_cat"] == "true" else "☐" attrs_dict["pilastri"] = "☑" if attrs_dict[ "pilastri"] == "true" else "☐" attrs_dict["pilotis"] = "☑" if attrs_dict[ "pilotis"] == "true" else "☐" attrs_dict["sopraelev"] = "☑" if attrs_dict[ "sopraelev"] == "true" else "☐" attrs_dict["danno"] = self.danno_dict[attrs_dict["danno"]] attrs_dict["stato_man"] = self.stato_man_dict[ attrs_dict["stato_man"]] attrs_dict["pr_pubb"] = "☑" if attrs_dict[ "pr_pubb"] == "true" else "☐" attrs_dict["pr_priv"] = "☑" if attrs_dict[ "pr_priv"] == "true" else "☐" attrs_dict["morf"] = self.morf_dict[attrs_dict["morf"]] attrs_dict["ubic_sotto"] = "☑" if attrs_dict[ "ubic_sotto"] == "true" else "☐" attrs_dict["ubic_sopra"] = "☑" if attrs_dict[ "ubic_sopra"] == "true" else "☐" attrs_dict["zona_ms"] = self.zona_ms_dict[attrs_dict["zona_ms"]] attrs_dict["inst_fran"] = "☑" if attrs_dict[ "inst_fran"] == "true" else "☐" attrs_dict["inst_liq"] = "☑" if attrs_dict[ "inst_liq"] == "true" else "☐" attrs_dict["inst_fag"] = "☑" if attrs_dict[ "inst_fag"] == "true" else "☐" attrs_dict["inst_ced"] = "☑" if attrs_dict[ "inst_ced"] == "true" else "☐" attrs_dict["inst_cav"] = "☑" if attrs_dict[ "inst_cav"] == "true" else "☐" attrs_dict["frana_ar"] = "☑" if attrs_dict[ "frana_ar"] == "true" else "☐" attrs_dict["frana_mon"] = "☑" if attrs_dict[ "frana_mon"] == "true" else "☐" attrs_dict["frana_val"] = "☑" if attrs_dict[ "frana_val"] == "true" else "☐" attrs_dict["pai"] = self.pai_dict[attrs_dict["pai"]] attrs_dict["alluvio"] = "☑" if attrs_dict[ "alluvio"] == "true" else "☐" attrs_dict["uso_att"] = self.uso_att_dict[attrs_dict["uso_att"]] attrs_dict["uso_a"] = "☑" if attrs_dict[ "uso_a"] == "true" else "☐" attrs_dict["uso_a_1"] = attrs_dict[ "uso_a_1"] if attrs_dict["uso_a_1"] > 0 else "-" attrs_dict["uso_b"] = "☑" if attrs_dict[ "uso_b"] == "true" else "☐" attrs_dict["uso_b_1"] = attrs_dict[ "uso_b_1"] if attrs_dict["uso_b_1"] > 0 else "-" attrs_dict["uso_c"] = "☑" if attrs_dict[ "uso_c"] == "true" else "☐" attrs_dict["uso_c_1"] = attrs_dict[ "uso_c_1"] if attrs_dict["uso_c_1"] > 0 else "-" attrs_dict["uso_d"] = "☑" if attrs_dict[ "uso_d"] == "true" else "☐" attrs_dict["uso_d_1"] = attrs_dict[ "uso_d_1"] if attrs_dict["uso_d_1"] > 0 else "-" attrs_dict["uso_e"] = "☑" if attrs_dict[ "uso_e"] == "true" else "☐" attrs_dict["uso_e_1"] = attrs_dict[ "uso_e_1"] if attrs_dict["uso_e_1"] > 0 else "-" attrs_dict["uso_f"] = "☑" if attrs_dict[ "uso_f"] == "true" else "☐" attrs_dict["uso_f_1"] = attrs_dict[ "uso_f_1"] if attrs_dict["uso_f_1"] > 0 else "-" attrs_dict["uso_g"] = "☑" if attrs_dict[ "uso_g"] == "true" else "☐" attrs_dict["uso_g_1"] = attrs_dict[ "uso_g_1"] if attrs_dict["uso_g_1"] > 0 else "-" attrs_dict["epoca_1"] = "☑" if attrs_dict[ "epoca_1"] == "true" else "☐" attrs_dict["epoca_2"] = "☑" if attrs_dict[ "epoca_2"] == "true" else "☐" attrs_dict["epoca_3"] = "☑" if attrs_dict[ "epoca_3"] == "true" else "☐" attrs_dict["epoca_4"] = "☑" if attrs_dict[ "epoca_4"] == "true" else "☐" attrs_dict["epoca_5"] = "☑" if attrs_dict[ "epoca_5"] == "true" else "☐" attrs_dict["epoca_6"] = "☑" if attrs_dict[ "epoca_6"] == "true" else "☐" attrs_dict["epoca_7"] = "☑" if attrs_dict[ "epoca_7"] == "true" else "☐" attrs_dict["epoca_8"] = "☑" if attrs_dict[ "epoca_8"] == "true" else "☐" attrs_dict["utilizz"] = self.utilizz_dict[attrs_dict["utilizz"]] html = self.unita_strutt_tmpl.substitute(attrs_dict) if html is not None: doc = QTextDocument() # weird & broken html subset supported by QTextDocument: # https://doc.qt.io/qt-5/richtext-html-subset.html doc.setHtml(html) doc.print(self.printer)