def convert_html_to_pdf(source, destination, page_size=QPrinter.Letter, print_format=QPrinter.PdfFormat, timeout=10000, app=None): """Converts an .html file at the source to a .pdf at the destination Any external files linked in the source file must be paths relative to the location of the source file itself. If building the html file dynamically, the rel_path function can be used to create proper relative paths using the .html location as the source location. The conversion is done using th ability of a QPrinter to print a QWebView to a PDF. This means we must have some Qt bindings, either PySide (default) or PyQt4 (5 support incoming?), but then are only limited by what the QWebView can display. While the intent is so print to a PDF, the format parameter is exposed so that this can be used to print directly to a printer or (if >=Qt4.2) PostScript format. If this is being used in a larger QApplication, we should only have one instance of QApplication, so pass the existing instance to the `app` parameter. """ if app is None: app = QApplication(sys.argv) view = QWebView() # We want to ensure the page was fully loaded before printing, so # we wait for the loadFinished event to fire. with wait_for_signal(view.loadFinished, timeout=timeout): # QUrl requires absolute path names view.load(QUrl.fromLocalFile(os.path.abspath(source))) # With the QWebView loaded, we now print to the destination PDF printer = QPrinter() printer.setPageSize(page_size) printer.setOutputFormat(print_format) printer.setOutputFileName(destination) view.print_(printer) # Exit the application app.exit()
def convert_html_to_pdf( source, destination, page_size=QPrinter.Letter, print_format=QPrinter.PdfFormat, timeout=10000, app=None): """Converts an .html file at the source to a .pdf at the destination Any external files linked in the source file must be paths relative to the location of the source file itself. If building the html file dynamically, the rel_path function can be used to create proper relative paths using the .html location as the source location. The conversion is done using th ability of a QPrinter to print a QWebView to a PDF. This means we must have some Qt bindings, either PySide (default) or PyQt4 (5 support incoming?), but then are only limited by what the QWebView can display. While the intent is so print to a PDF, the format parameter is exposed so that this can be used to print directly to a printer or (if >=Qt4.2) PostScript format. If this is being used in a larger QApplication, we should only have one instance of QApplication, so pass the existing instance to the `app` parameter. """ if app is None: app = QApplication(sys.argv) view = QWebView() # We want to ensure the page was fully loaded before printing, so # we wait for the loadFinished event to fire. with wait_for_signal(view.loadFinished, timeout=timeout): # QUrl requires absolute path names view.load(QUrl.fromLocalFile(os.path.abspath(source))) # With the QWebView loaded, we now print to the destination PDF printer = QPrinter() printer.setPageSize(page_size) printer.setOutputFormat(print_format) printer.setOutputFileName(destination) view.print_(printer) # Exit the application app.exit()
class HTMLViewer(QtGui.QWidget): def __init__(self, parent=None): super(HTMLViewer, self).__init__(parent) self.view = QWebView(self) layout = QtGui.QVBoxLayout(self) layout.setSpacing(0) layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self.view) # Create ContextMenu context_menu = QtGui.QMenu(self.view) def open_context_menu(point): context_menu.exec_(self.view.mapToGlobal(point)) self.view.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.view.customContextMenuRequested.connect(open_context_menu) action = QtGui.QAction('&Back', self, shortcut=QtGui.QKeySequence.Back, statusTip="Click to go back", triggered=self.view.back) action.setShortcut('Backspace') context_menu.addAction(action) action = QtGui.QAction('&Forward', self, shortcut=QtGui.QKeySequence.Forward, statusTip="Click to go forward", triggered=self.view.forward) action.setShortcut('Shift + Backspace') context_menu.addAction(action) action = QtGui.QAction('&Reload', self, shortcut=QtGui.QKeySequence.Refresh, statusTip="Click to refresh", triggered=self.view.reload) context_menu.addAction(action) context_menu.addSeparator() action = QtGui.QAction('&Print', self, shortcut=QtGui.QKeySequence.Print, statusTip="Click to print", triggered=self.print_) context_menu.addAction(action) def contextMenuEvent(self, event): self.context_menu.exec_(event.globalPos()) def print_(self): printer = QtGui.QPrinter() printer_dialog = QtGui.QPrintDialog(printer, self.view) if printer_dialog.exec_() != QtGui.QDialog.Accepted: # do nothing return # printout the view with selected printer self.view.print_(printer) # --- slots @QtCore.Slot(unicode) def update(self, value): # save vertical/horizontal scrollbar value m = self.view.page().mainFrame() v = m.scrollBarValue(QtCore.Qt.Vertical) h = m.scrollBarValue(QtCore.Qt.Horizontal) # set new HTML (value should be unicode) self.view.setHtml(value) # update vertical/horizontal scrollbar value m = self.view.page().mainFrame() m.setScrollBarValue(QtCore.Qt.Vertical, v) m.setScrollBarValue(QtCore.Qt.Horizontal, h)