Question: I'm trying to display a PDF I created (using fpdf2) in a Pyside6 app. There seems to be two roads there:  I can use QWebEngineView with plugins enabled, in which I can inject the PDF raw bytes, which works. It is not ideal for me since there's a lot of UI involved ; I'd like something cleaner.  Or I can use QPdfView. That widgets takes an QPdfDocument object from which it reads from. Unfortunately, QPdfDocument only have a .load() function that takes a filename. Since I'm looking to avoid disk writes there, I'm not interested in temporarly saving the file to disk to show it on the GUI.   There's two signatures on the .load() function tho : Supported signatures: PySide6.QtPdf.QPdfDocument.load(PySide6.QtCore.QIODevice, /) PySide6.QtPdf.QPdfDocument.load(str, /)  Here's the thing: I can't instantiate a QIODevice from Python, so I can't feed it PDF's bytes like a buffer (there's a .write() function that looks interesting). I've tried using BytesIO (from io package), but no luck there. Is there a way to create a QPdfDocument object from a PDF file's bytes? Thanks for your help!

Answer: You need to use a QBuffer (which inherits QIODevice) backed by a QByteArray containing the pdf bytes data. The buffer doesn't take ownership of the data, and the document doesn't take ownership of the buffer, so you need to ensure these objects are kept alive whilst the pdf is loading. A slot connected to the statusChanged signal can be used to clean up the objects once the document is loaded (or if an error occurs). A basic example that implements all that is given below (just provide a pdf file-path as a command-line argument to test it). (PS: whilst testing, I found that the viewer seg-faults on exit if a document has successfully loaded. This happens even when loading from a file-path. The issue is fairly harmless, and it can be easily fixed by explicitly closing the document before closing down the application. I get the same problem using either PySide-6.8.3 or PyQt-6.8.1 with Qt-6.8.3 on Linux, so it seems to be caused by a Qt bug. It's possible that other versions/platforms aren't affected). DEMO: import sys from PySide6 import QtCore, QtWidgets, QtPdf, QtPdfWidgets # from PyQt6 import QtCore, QtWidgets, QtPdf, QtPdfWidgets class PdfView(QtPdfWidgets.QPdfView): def __init__(self, parent=None): super().__init__(parent) self.setDocument(QtPdf.QPdfDocument(self)) self.document().statusChanged.connect(self.handleStatusChanged) def loadData(self, data): self._data = QtCore.QByteArray(data) self._buffer = QtCore.QBuffer(self._data) self._buffer.open(QtCore.QIODeviceBase.OpenModeFlag.ReadOnly) self.document().load(self._buffer) def handleStatusChanged(self, status): print(status) if (status == QtPdf.QPdfDocument.Status.Ready or status == QtPdf.QPdfDocument.Status.Error): self._buffer.close() del self._buffer, self._data def closeEvent(self, event): # prevent seg-fault on exit self.document().close() if __name__ == '__main__': app = QtWidgets.QApplication(['Test']) pdfview = PdfView() pdfview.setGeometry(600, 100, 800, 600) # FOR TESTING PURPOSES ONLY # get sample pdf bytes data with open(sys.argv[1], 'rb') as stream: pdfview.loadData(stream.read()) pdfview.show() app.exec()