2012-08-23 76 views
3

我有一个Python和PySide应用程序,它连接到一个mysql数据库并在QTableView中显示查询结果。 我需要打印表格视图的内容。 下面是一些代码:打印Pyside QTableView

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 

我无法找到一个这样的例子,我不知道从文档太多,所以我会很感激一些帮助

感谢

+0

开始阅读Qt的文档:http://doc.qt.nokia.com/4.7 -snapshot/printing.html –

+1

谢谢,但我无法将C++代码转换为python。我不是很了解C++,但Qt文档有时候很有用。 –

+3

这不是一个真正的问题,但它是如何结束的,但没有一个简单的问题,下面的过去呢? http://stackoverflow.com/questions/3147030/qtableview-printing?rq=1 – neuronet

回答

4

一个办法是否将表格内容转储到QTextDocument,然后打印。

下面的演示使用一个简单的文本表,但HTML可以用来获得更先进的格式:

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_()) 
+0

谢谢ekhumoro和jdi,你的答案都很好,但我只能选择一个正确的答案,我会给它ekhumoro,因为他的方法打印时看起来更好。 –

3

在寻找一种方法来打印多页QTable,你可能会找人或者说在@ ekhumoro的答案中转储到QTextDocument,或者直接从表中手动管理页面大小。

下面是如何,你可以直接从打印表格,进行自定义打印方法粗略例如:

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()