[PyQt] QTableView printing problem
gralex
gralex1974 at rambler.ru
Tue Sep 30 19:36:43 BST 2008
Hi, everybody.
I try modify the example "pixelator.pyw" from PyQt4 examples, and don't
understand , why printer spits out a blank sheet.
My variant :
import sys
from PyQt4 import QtCore, QtGui
import pixelator_rc
ItemSize = 256
class PixelDelegate(QtGui.QAbstractItemDelegate):
def __init__(self, parent=None):
QtGui.QAbstractItemDelegate.__init__(self,parent)
self.pixelSize = 12
def paint(self, painter, option, index):
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.setPen(QtCore.Qt.NoPen)
if option.state & QtGui.QStyle.State_Selected:
painter.setBrush(option.palette.highlight())
else:
painter.setBrush(QtGui.QBrush(QtCore.Qt.white))
painter.drawRect(option.rect)
if option.state & QtGui.QStyle.State_Selected:
painter.setBrush(option.palette.highlightedText())
else:
painter.setBrush(QtGui.QBrush(QtCore.Qt.black))
size = min(option.rect.width(), option.rect.height())
brightness, ok = index.model().data(index,
QtCore.Qt.DisplayRole).toInt()
radius = (size/2.0) - (brightness/255.0 * size/2.0)
painter.drawEllipse(QtCore.QRectF(
option.rect.x() + option.rect.width()/2 -
radius,
option.rect.y() + option.rect.height()/2 -
radius,
2*radius, 2*radius))
def sizeHint(self, option, index):
return QtCore.QSize(self.pixelSize, self.pixelSize)
def setPixelSize(self, size):
self.pixelSize = size
class ImageModel(QtCore.QAbstractTableModel):
def __init__(self, image, parent=None):
QtCore.QAbstractTableModel.__init__(self, parent)
self.modelImage = QtGui.QImage(image)
def rowCount(self, parent):
return self.modelImage.height()
def columnCount(self, parent):
return self.modelImage.width()
def data(self, index, role):
if not index.isValid():
return QtCore.QVariant()
elif role != QtCore.Qt.DisplayRole:
return QtCore.QVariant()
return
QtCore.QVariant(QtGui.qGray(self.modelImage.pixel(index.column(),
index.row())))
class MainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QMainWindow.__init__(self, parent)
self.currentPath = QtCore.QDir.home().absolutePath()
self.model = ImageModel(QtGui.QImage(), self)
centralWidget = QtGui.QWidget()
self.view = QtGui.QTableView()
#self.view.setShowGrid(False)
#self.view.horizontalHeader().hide()
#self.view.verticalHeader().hide()
delegate = PixelDelegate(self)
#self.view.setItemDelegate(delegate)
pixelSizeLabel = QtGui.QLabel(self.tr("Pixel size:"))
pixelSizeSpinBox = QtGui.QSpinBox()
pixelSizeSpinBox.setMinimum(1)
pixelSizeSpinBox.setMaximum(32)
pixelSizeSpinBox.setValue(12)
fileMenu = QtGui.QMenu(self.tr("&File"), self)
openAction = fileMenu.addAction(self.tr("&Open..."))
openAction.setShortcut(QtGui.QKeySequence(self.tr("Ctrl+O")))
self.printAction = fileMenu.addAction(self.tr("&Print..."))
self.printAction.setEnabled(False)
self.printAction.setShortcut(QtGui.QKeySequence(self.tr("Ctrl+P")))
quitAction = fileMenu.addAction(self.tr("E&xit"))
quitAction.setShortcut(QtGui.QKeySequence(self.tr("Ctrl+Q")))
helpMenu = QtGui.QMenu(self.tr("&Help"), self)
aboutAction = helpMenu.addAction(self.tr("&About"))
self.menuBar().addMenu(fileMenu)
self.menuBar().addSeparator()
self.menuBar().addMenu(helpMenu)
self.connect(openAction, QtCore.SIGNAL("triggered()"),
self.chooseImage)
self.connect(self.printAction, QtCore.SIGNAL("triggered()"),
self.printImage)
self.connect(quitAction, QtCore.SIGNAL("triggered()"),
QtGui.qApp, QtCore.SLOT("quit()"))
self.connect(aboutAction, QtCore.SIGNAL("triggered()"),
self.showAboutBox)
self.connect(pixelSizeSpinBox, QtCore.SIGNAL("valueChanged(int)"),
delegate.setPixelSize)
self.connect(pixelSizeSpinBox, QtCore.SIGNAL("valueChanged(int)"),
self.updateView)
controlsLayout = QtGui.QHBoxLayout()
controlsLayout.addWidget(pixelSizeLabel)
controlsLayout.addWidget(pixelSizeSpinBox)
controlsLayout.addStretch(1)
mainLayout = QtGui.QVBoxLayout()
mainLayout.addWidget(self.view)
mainLayout.addLayout(controlsLayout)
centralWidget.setLayout(mainLayout)
self.setCentralWidget(centralWidget)
self.setWindowTitle(self.tr("Pixelator"))
self.resize(640,480)
def chooseImage(self):
fileName = QtGui.QFileDialog.getOpenFileName(self,
self.tr("Choose an Image"),
self.currentPath, "*")
if not fileName.isEmpty():
self.openImage(fileName)
def openImage(self, fileName):
image = QtGui.QImage()
if image.load(fileName):
newModel = ImageModel(image, self)
self.view.setModel(newModel)
self.model = newModel
if not fileName.startsWith(":/"):
self.currentPath = fileName
self.setWindowTitle(self.tr("%1 -
Pixelator").arg(self.currentPath))
self.printAction.setEnabled(True)
self.updateView()
def printImage(self):
if self.model.rowCount(QtCore.QModelIndex()) *
self.model.columnCount(QtCore.QModelIndex()) > 90000:
answer = QtGui.QMessageBox.question(self, self.tr("Large
Image Size"),
self.tr("The printed image may be very "
"large. Are you sure that you
want "
"to print it?"),
QtGui.QMessageBox.Yes,
QtGui.QMessageBox.No)
if answer == QtGui.QMessageBox.No:
return
printer = QtGui.QPrinter(QtGui.QPrinter.HighResolution)
dlg = QtGui.QPrintDialog(printer, self)
dlg.setWindowTitle(self.tr("Print Image"))
if dlg.exec_() != QtGui.QDialog.Accepted:
return
painter = QtGui.QPainter()
painter.begin(printer)
rows = self.model.rowCount(QtCore.QModelIndex())
columns = self.model.columnCount(QtCore.QModelIndex())
sourceWidth = (columns+1) * ItemSize
sourceHeight = (rows+1) * ItemSize
painter.save()
xscale = printer.pageRect().width() / float(sourceWidth)
yscale = printer.pageRect().height() / float(sourceHeight)
scale = min(xscale, yscale)
painter.translate(printer.pageRect().x()+printer.pageRect().width()/2,
printer.pageRect().y()+printer.pageRect().height()/2)
painter.scale(scale, scale)
painter.translate(-sourceWidth/2, -sourceHeight/2)
option = QtGui.QStyleOptionViewItem()
parent = QtCore.QModelIndex()
progress = QtGui.QProgressDialog(self.tr("Printing..."),
self.tr("Cancel..."), 0, rows, self)
y = ItemSize / 2.0
for row in range(rows):
progress.setValue(row)
QtGui.qApp.processEvents()
if progress.wasCanceled():
break
x = ItemSize / 2.0
for col in range(columns):
option.rect = QtCore.QRect(x, y, ItemSize, ItemSize)
self.view.itemDelegate().paint(painter, option,
self.model.index(row, col,
parent))
x = x + ItemSize
y = y + ItemSize
progress.setValue(rows)
painter.restore()
painter.end()
if progress.wasCanceled():
QtGui.QMessageBox.information(self, self.tr("Printing
canceled"),
self.tr("The printing process
was canceled."),
QtGui.QMessageBox.Cancel)
def showAboutBox(self):
QtGui.QMessageBox.about(self, self.tr("About the Pixelator
example"),
self.tr("This example demonstrates how a standard view and
a custom\n"
"delegate can be used to produce a specialized
representation\n"
"of data in a simple custom model."))
def updateView(self):
for row in range(self.model.rowCount(QtCore.QModelIndex())):
self.view.resizeRowToContents(row)
for column in range(self.model.columnCount(QtCore.QModelIndex())):
self.view.resizeColumnToContents(column)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
window = MainWindow()
window.show()
window.openImage(QtCore.QString(":/images/qt.png"))
sys.exit(app.exec_())
Sorry for my english.
Good luck.
Gralex
More information about the PyQt
mailing list