aboutsummaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
authorArun Srinivasan <rulfzid@gmail.com>2011-02-12 18:43:12 -0600
committerHugo Parente Lima <hugo.pl@gmail.com>2011-04-07 15:23:18 -0300
commit4b3b716e1ce648d406d487e33ba355ed71e472d2 (patch)
treef4c384f31efca467d9129d60d9e4e4073679739a /examples
parenta786392a1232f90f8a3bd106c5594dbca8f8be05 (diff)
Added stardelegate example
Reviewer: Hugo Parente Lima <hugo.lima@openbossa.org> Marcelo Lira <marcelo.lira@openbossa.org>
Diffstat (limited to 'examples')
-rwxr-xr-xexamples/itemviews/addressbook/addressbook.py5
-rwxr-xr-xexamples/itemviews/stardelegate/stardelegate.py175
-rw-r--r--examples/itemviews/stardelegate/stareditor.py102
-rw-r--r--examples/itemviews/stardelegate/starrating.py102
4 files changed, 384 insertions, 0 deletions
diff --git a/examples/itemviews/addressbook/addressbook.py b/examples/itemviews/addressbook/addressbook.py
index b3138e6..a3fec1d 100755
--- a/examples/itemviews/addressbook/addressbook.py
+++ b/examples/itemviews/addressbook/addressbook.py
@@ -73,6 +73,11 @@ class MainWindow(QMainWindow):
self.editAction = self.createAction("&Edit Entry...", toolMenu, self.addressWidget.editEntry)
toolMenu.addSeparator()
self.removeAction = self.createAction("&Remove Entry", toolMenu, self.addressWidget.removeEntry)
+
+ # Disable the edit and remove menu items initally, as there are
+ # no items yet.
+ self.editAction.setEnabled(False)
+ self.removeAction.setEnabled(False)
# Wire up the updateActions slot
self.addressWidget.selectionChanged.connect(self.updateActions)
diff --git a/examples/itemviews/stardelegate/stardelegate.py b/examples/itemviews/stardelegate/stardelegate.py
new file mode 100755
index 0000000..a0390fa
--- /dev/null
+++ b/examples/itemviews/stardelegate/stardelegate.py
@@ -0,0 +1,175 @@
+#!/usr/bin/python
+
+"""**************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+*****************************************************************************
+** February 2011
+** - stardelegate example ported to PySide by Arun Srinivasan
+** <rulfzid@gmail.com>
+**************************************************************************"""
+
+from PySide.QtGui import (QItemDelegate, QStyledItemDelegate, QStyle)
+
+from starrating import StarRating
+from stareditor import StarEditor
+
+class StarDelegate(QStyledItemDelegate):
+ """ A subclass of QStyledItemDelegate that allows us to render our
+ pretty star ratings.
+ """
+
+ def __init__(self, parent=None):
+ super(StarDelegate, self).__init__(parent)
+
+ def paint(self, painter, option, index):
+ """ Paint the items in the table.
+
+ If the item referred to by <index> is a StarRating, we handle the
+ painting ourselves. For the other items, we let the base class
+ handle the painting as usual.
+
+ In a polished application, we'd use a better check than the
+ column number to find out if we needed to paint the stars, but
+ it works for the purposes of this example.
+ """
+ if index.column() == 3:
+ starRating = StarRating(index.data())
+
+ # If the row is currently selected, we need to make sure we
+ # paint the background accordingly.
+ if option.state & QStyle.State_Selected:
+ # The original C++ example used option.palette.foreground() to
+ # get the brush for painting, but there are a couple of
+ # problems with that:
+ # - foreground() is obsolete now, use windowText() instead
+ # - more importantly, windowText() just returns a brush
+ # containing a flat color, where sometimes the style
+ # would have a nice subtle gradient or something.
+ # Here we just use the brush of the painter object that's
+ # passed in to us, which keeps the row highlighting nice
+ # and consistent.
+ painter.fillRect(option.rect, painter.brush())
+
+ # Now that we've painted the background, call starRating.paint()
+ # to paint the stars.
+ starRating.paint(painter, option.rect, option.palette)
+ else:
+ QStyledItemDelegate.paint(self, painter, option, index)
+
+ def sizeHint(self, option, index):
+ """ Returns the size needed to display the item in a QSize object. """
+ if index.column() == 3:
+ starRating = StarRating(index.data())
+ return starRating.sizeHint()
+ else:
+ return QStyledItemDelegate.sizeHint(self, option, index)
+
+ # The next 4 methods handle the custom editing that we need to do.
+ # If this were just a display delegate, paint() and sizeHint() would
+ # be all we needed.
+
+ def createEditor(self, parent, option, index):
+ """ Creates and returns the custom StarEditor object we'll use to edit
+ the StarRating.
+ """
+ if index.column() == 3:
+ editor = StarEditor(parent)
+ editor.editingFinished.connect(self.commitAndCloseEditor)
+ return editor
+ else:
+ return QStyledItemDelegate.createEditor(self, parent, option, index)
+
+ def setEditorData(self, editor, index):
+ """ Sets the data to be displayed and edited by our custom editor. """
+ if index.column() == 3:
+ editor.starRating = StarRating(index.data())
+ else:
+ QStyledItemDelegate.setEditorData(self, editor, index)
+
+ def setModelData(self, editor, model, index):
+ """ Get the data from our custom editor and stuffs it into the model.
+ """
+ if index.column() == 3:
+ model.setData(index, editor.starRating.starCount)
+ else:
+ QStyledItemDelegate.setModelData(self, editor, model, index)
+
+ def commitAndCloseEditor(self):
+ """ Erm... commits the data and closes the editor. :) """
+ editor = self.sender()
+
+ # The commitData signal must be emitted when we've finished editing
+ # and need to write our changed back to the model.
+ self.commitData.emit(editor)
+ self.closeEditor.emit(editor)
+
+
+if __name__ == "__main__":
+ """ Run the application. """
+ from PySide.QtGui import (QApplication, QTableWidget, QTableWidgetItem,
+ QAbstractItemView)
+ import sys
+
+ app = QApplication(sys.argv)
+
+ # Create and populate the tableWidget
+ tableWidget = QTableWidget(4, 4)
+ tableWidget.setItemDelegate(StarDelegate())
+ tableWidget.setEditTriggers(QAbstractItemView.DoubleClicked |
+ QAbstractItemView.SelectedClicked)
+ tableWidget.setSelectionBehavior(QAbstractItemView.SelectRows)
+ tableWidget.setHorizontalHeaderLabels(["Title", "Genre", "Artist", "Rating"])
+
+ data = [ ["Mass in B-Minor", "Baroque", "J.S. Bach", 5],
+ ["Three More Foxes", "Jazz", "Maynard Ferguson", 4],
+ ["Sex Bomb", "Pop", "Tom Jones", 3],
+ ["Barbie Girl", "Pop", "Aqua", 5] ]
+
+ for r in range(len(data)):
+ tableWidget.setItem(r, 0, QTableWidgetItem(data[r][0]))
+ tableWidget.setItem(r, 1, QTableWidgetItem(data[r][1]))
+ tableWidget.setItem(r, 2, QTableWidgetItem(data[r][2]))
+ item = QTableWidgetItem()
+ item.setData(0, StarRating(data[r][3]).starCount)
+ tableWidget.setItem(r, 3, item)
+
+ tableWidget.resizeColumnsToContents()
+ tableWidget.resize(500, 300)
+ tableWidget.show()
+
+ sys.exit(app.exec_())
+ \ No newline at end of file
diff --git a/examples/itemviews/stardelegate/stareditor.py b/examples/itemviews/stardelegate/stareditor.py
new file mode 100644
index 0000000..63a0d56
--- /dev/null
+++ b/examples/itemviews/stardelegate/stareditor.py
@@ -0,0 +1,102 @@
+#!/usr/bin/python
+
+"""**************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+*****************************************************************************
+** February 2011
+** - stardelegate example ported to PySide by Arun Srinivasan
+** <rulfzid@gmail.com>
+**************************************************************************"""
+
+from PySide.QtGui import (QWidget, QPainter)
+from PySide.QtCore import Signal
+
+
+class StarEditor(QWidget):
+ """ The custome editor for editing StarRatings. """
+
+ # A signal to tell the delegate when we've finished editing.
+ editingFinished = Signal()
+
+ def __init__(self, parent=None):
+ """ Initialize the editor object, making sure we can watch mouse
+ events.
+ """
+ super(StarEditor, self).__init__(parent)
+
+ self.setMouseTracking(True)
+ self.setAutoFillBackground(True)
+
+ def sizeHint(self):
+ """ Tell the caller how big we are. """
+ return self.starRating.sizeHint()
+
+ def paintEvent(self, event):
+ """ Paint the editor, offloading the work to the StarRating class. """
+ painter = QPainter(self)
+ self.starRating.paint(painter, self.rect(), self.palette(), isEditable=True)
+
+ def mouseMoveEvent(self, event):
+ """ As the mouse moves inside the editor, track the position and
+ update the editor to display as many stars as necessary.
+ """
+ star = self.starAtPosition(event.x())
+
+ if (star != self.starRating.starCount) and (star != -1):
+ self.starRating.starCount = star
+ self.update()
+
+ def mouseReleaseEvent(self, event):
+ """ Once the user has clicked his/her chosen star rating, tell the
+ delegate we're done editing.
+ """
+ self.editingFinished.emit()
+
+ def starAtPosition(self, x):
+ """ Calculate which star the user's mouse cursor is currently
+ hovering over.
+ """
+ star = (x / (self.starRating.sizeHint().width() /
+ self.starRating.maxStarCount)) + 1
+ if (star <= 0) or (star > self.starRating.maxStarCount):
+ return -1
+
+ return star
+
+
+
+
diff --git a/examples/itemviews/stardelegate/starrating.py b/examples/itemviews/stardelegate/starrating.py
new file mode 100644
index 0000000..bad120f
--- /dev/null
+++ b/examples/itemviews/stardelegate/starrating.py
@@ -0,0 +1,102 @@
+#!/usr/bin/python
+
+"""**************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+*****************************************************************************
+** February 2011
+** - stardelegate example ported to PySide by Arun Srinivasan
+** <rulfzid@gmail.com>
+**************************************************************************"""
+
+from math import (cos, sin, pi)
+
+from PySide.QtGui import (QPainter, QPolygonF)
+from PySide.QtCore import (QPointF, QSize, Qt)
+
+PAINTING_SCALE_FACTOR = 20
+
+
+class StarRating(object):
+ """ Handle the actual painting of the stars themselves. """
+
+ def __init__(self, starCount=1, maxStarCount=5):
+ self.starCount = starCount
+ self.maxStarCount = maxStarCount
+
+ # Create the star shape we'll be drawing.
+ self.starPolygon = QPolygonF()
+ self.starPolygon.append(QPointF(1.0, 0.5))
+ for i in range(1, 5):
+ self.starPolygon.append(QPointF(0.5 + 0.5 * cos(0.8 * i * pi),
+ 0.5 + 0.5 * sin(0.8 * i * pi)))
+
+ # Create the diamond shape we'll show in the editor
+ self.diamondPolygon = QPolygonF()
+ diamondPoints = [QPointF(0.4, 0.5), QPointF(0.5, 0.4),
+ QPointF(0.6, 0.5), QPointF(0.5, 0.6),
+ QPointF(0.4, 0.5)]
+ for point in diamondPoints:
+ self.diamondPolygon.append(point)
+
+ def sizeHint(self):
+ """ Tell the caller how big we are. """
+ return PAINTING_SCALE_FACTOR * QSize(self.maxStarCount, 1)
+
+ def paint(self, painter, rect, palette, isEditable=False):
+ """ Paint the stars (and/or diamonds if we're in editing mode). """
+ painter.save()
+
+ painter.setRenderHint(QPainter.Antialiasing, True)
+ painter.setPen(Qt.NoPen)
+
+ if isEditable:
+ painter.setBrush(palette.highlight())
+ else:
+ painter.setBrush(palette.windowText())
+
+ yOffset = (rect.height() - PAINTING_SCALE_FACTOR) / 2
+ painter.translate(rect.x(), rect.y() + yOffset)
+ painter.scale(PAINTING_SCALE_FACTOR, PAINTING_SCALE_FACTOR)
+
+ for i in range(self.maxStarCount):
+ if i < self.starCount:
+ painter.drawPolygon(self.starPolygon, Qt.WindingFill)
+ elif isEditable:
+ painter.drawPolygon(self.diamondPolygon, Qt.WindingFill)
+ painter.translate(1.0, 0.0)
+
+ painter.restore() \ No newline at end of file