Imprimiendo Pyside QTableView

Tengo una aplicación Python y PySide que se conecta a una base de datos mysql y muestra los resultados de una consulta en un QTableView. Necesito imprimir el contenido de la vista de tabla. Aquí hay un código:

self.db_table = QtGui.QTableView(self) self.model = QtSql.QSqlQueryModel() self.model.setQuery("SELECT * FROM simpsons") self.model.setHeaderData(1, QtCore.Qt.Horizontal, self.tr("First Name")) self.model.setHeaderData(2, QtCore.Qt.Horizontal, self.tr("Last Name")) self.db_table.setModel(self.model) self.print_btn = QtGui.QPushButton("Print") self.print_btn.clicked.connect(self.print_btn_clicked) def print_btn_clicked(self): printDialog = QtGui.QPrintDialog(self.printer, self) if printDialog.exec_() == QtGui.QDialog.Accepted: #printing code 

No puedo encontrar un ejemplo para esto y no entiendo mucho de la documentación, así que agradecería algo de ayuda

Gracias

Una forma de hacerlo es volcar el contenido de la tabla en un QTextDocument y luego imprimirlo.

La siguiente demostración usa una tabla de texto simple, pero html podría usarse para obtener un formato más sofisticado:

 from PyQt4 import QtGui, QtCore class Window(QtGui.QWidget): def __init__(self, rows, columns): QtGui.QWidget.__init__(self) self.table = QtGui.QTableView(self) model = QtGui.QStandardItemModel(rows, columns, self.table) for row in range(rows): for column in range(columns): item = QtGui.QStandardItem('(%d, %d)' % (row, column)) item.setTextAlignment(QtCore.Qt.AlignCenter) model.setItem(row, column, item) self.table.setModel(model) self.buttonPrint = QtGui.QPushButton('Print', self) self.buttonPrint.clicked.connect(self.handlePrint) self.buttonPreview = QtGui.QPushButton('Preview', self) self.buttonPreview.clicked.connect(self.handlePreview) layout = QtGui.QGridLayout(self) layout.addWidget(self.table, 0, 0, 1, 2) layout.addWidget(self.buttonPrint, 1, 0) layout.addWidget(self.buttonPreview, 1, 1) def handlePrint(self): dialog = QtGui.QPrintDialog() if dialog.exec_() == QtGui.QDialog.Accepted: self.handlePaintRequest(dialog.printer()) def handlePreview(self): dialog = QtGui.QPrintPreviewDialog() dialog.paintRequested.connect(self.handlePaintRequest) dialog.exec_() def handlePaintRequest(self, printer): document = QtGui.QTextDocument() cursor = QtGui.QTextCursor(document) model = self.table.model() table = cursor.insertTable( model.rowCount(), model.columnCount()) for row in range(table.rows()): for column in range(table.columns()): cursor.insertText(model.item(row, column).text()) cursor.movePosition(QtGui.QTextCursor.NextCell) document.print_(printer) if __name__ == '__main__': import sys app = QtGui.QApplication(sys.argv) window = Window(25, 2) window.resize(300, 400) window.show() sys.exit(app.exec_()) 

Al buscar un método para imprimir una QTable de varias páginas, es probable que encuentre a alguien que le diga que descargue un QTextDocument como en la respuesta de @ ekhumoro, o que administre manualmente el tamaño de la página, imprimiendo directamente desde la Tabla.

Este es un ejemplo aproximado de cómo podría imprimir directamente desde la tabla, haciendo un método de impresión personalizado:

 class Window(QtGui.QDialog): def __init__(self): ... self.db_table = TableView(self) def print_table(self): dialog = QtGui.QPrintDialog(self) if dialog.exec_() == dialog.Accepted: self.db_table.print_(dialog.printer()) class TableView(QtGui.QTableView): def print_(self, printer): model = self.model() rows = model.rowCount() cols = model.columnCount() totalWidth = 0.0 for i in xrange(cols): totalWidth += self.columnWidth(i) painter = QtGui.QPainter(printer) pageSize = printer.pageRect() pageHeight = pageSize.height() scaleX = pageSize.width() / totalWidth painter.scale(scaleX, 1.0) totalHeight = 0.0 newPage = False offsetY = 0 for row in xrange(rows): height = self.rowHeight(row) totalHeight += height if totalHeight > pageHeight: totalHeight = height printer.newPage() newPage = True for col in xrange(cols): idx = model.index(row, col) option = self.viewOptions() option.rect = self.visualRect(idx) if newPage: offsetY = option.rect.y() newPage = False option.rect.moveTop(option.rect.y()-offsetY) self.itemDelegate().paint(painter, option, idx) painter.end()