Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct
Aitslimane last edited by
is there any way to print the content of of a QAbstractItemView (QTableWidget for example) into a QPaintDevice (PDF file) using QPainter ans QPdfWriter ?
JonB last edited by JonB
Now it's funny you should ask this, because I think it's the same question I was faced with just a few days ago!!
I wanted to be able to export a
QTableViewto PDF, generically.
First, I'll say I decided not to do it the "paint" way, for your consideration of an alternative!
I was already offering to export the data cells to CSV file (for Excel). I decided that I was not particularly caring of the table view's actual graphics. So instead I would go down the route of exporting "as data for a table".
I ended up:
- Populating the cells from the underlying
QTextDocument::toHtml()to get an HTML
- Finally sending that off to one of my existing HTML-to-PDF functions (I use
QWebEnginePage::printfToPdf(), but there are others).
I have been very happy with this approach, rather than actually trying to paint from the view. (It also scales nicely if you find you want to export to anything other than PDF, e.g. you can get a text-only representation.)
FWIW, I paste at the end some "extracts" of my code to give you a flavour and see if it suits you.
Now, if you really do want to go down the view-paint-PDF route, I can doubtless dig out the stackoverflow I came across to do it that way. However, IIRC, one issue was you had to implement your own scrolling to paint the "hidden" parts of the view to PDF, which was one reason I rejected that approach. Let me know if you still want that?
Some of my
class JTextDocument(QTextDocument): @staticmethod def setTextCursorHAlign(cursor: QTextCursor, hAlign: Qt.AlignmentFlag): blockFormat = cursor.blockFormat() alignment = (blockFormat.alignment() & Qt.AlignVertical_Mask) | (hAlign & Qt.AlignHorizontal_Mask) blockFormat.setAlignment(alignment) cursor.setBlockFormat(blockFormat) def insertTableForModel(self, cursor: QTextCursor, model: QAbstractItemModel) -> QTextTable: sourceModel = model if isinstance(model, QAbstractProxyModel): sourceModel = model.sourceModel() rowCnt = model.rowCount() colCnt = model.columnCount() tableFormat = QTextTableFormat() table = cursor.insertTable(rowCnt + 1, colCnt, tableFormat) headerFont = QTextCharFormat() headerFont.setFontWeight(QFont.Bold) for col in range(colCnt): headerCell = table.cellAt(0, col) cursor = headerCell.firstCursorPosition() self.setTextCursorHAlign(cursor, Qt.AlignHCenter) item = sourceModel.horizontalHeaderItem(col) cursor.insertText(item.text(), headerFont) for row in range(rowCnt): for col in range(colCnt): cell = table.cellAt(row + 1, col) cursor = cell.firstCursorPosition() val = model.data(model.index(row, col), Qt.DisplayRole) alignment = model.data(model.index(row, col), Qt.TextAlignmentRole) if alignment is not None: self.setTextCursorHAlign(cursor, alignment) cursor.insertText(val) return table # Sample caller outline: doc = JTextDocument(self) font = QFont("Verdana", 10) doc.setDefaultFont(font) doc.setDocumentMargin(10) cursor = QTextCursor(doc) cursor.movePosition(QTextCursor.Start) table = doc.insertTableForModel(cursor, model) cursor.movePosition(QTextCursor.End) html = doc.toHtml() # Now that you have HTML, do whatever to export that to PDF etc.