convert pdf to tiff c# : Add signature pdf software Library dll winforms asp.net wpf web forms pyqt-book48-part1620

Figure 16.1. Two Views of Water Quality Data
The water quality dataset covers a six month period at one small water treatment works—
but with readings taken every 15 minutes, this adds up to just over 17 500 readings. What
this implies is that our view is going to need a vertical scrollbar. PyQt offers three ways of
getting scrollbars. One way is to create a widget that inherits QAbstractScrollArea;
this approach is used by the QGraphicsView and QTextEdit widgets. Another way is
to create a composite widget that includes a couple of QScrollBars. But PyQt's
documentation recommends the third way—using the much simpler QScrollArea
instead. The one disadvantage of using QScrollArea is that it is one of the few PyQt
classes not designed to be subclassed. Instead we must create an instance and add the
widget we want scrollbars for to it. To put this in perspective, here is the Water Quality
Data application's initializer:
class MainForm(QDialog):
def __init__(self, parent=None):
super(MainForm, self).__init__(parent)
self.model = WaterQualityModel(os.path.join(
os.path.dirname(__file__), "waterdata.csv.gz"))
self.tableView = QTableView()
self.tableView.setAlternatingRowColors(True)
self.tableView.setModel(self.model)
self.waterView = WaterQualityView()
self.waterView.setModel(self.model)
scrollArea = QScrollArea()
scrollArea.setBackgroundRole(QPalette.Light)
scrollArea.setWidget(self.waterView)
self.waterView.scrollarea = scrollArea
splitter = QSplitter(Qt.Horizontal)
splitter.addWidget(self.tableView)
splitter.addWidget(scrollArea)
splitter.setSizes([600, 250])
layout = QHBoxLayout()
layout.addWidget(splitter)
self.setLayout(layout)
self.setWindowTitle("Water Quality Data")
QTimer.singleShot(0, self.initialLoad)
Rapid GUI Programming with Python and Qt: The Definitive Guide to PyQt Programming
Page 477
Return to Table of
Contents
Rapid GUI Programming with Python and Qt: The Definitive Guide to PyQt Programming
Rapid GUI Programming with Python and Qt: The Definitive Guide to PyQt Programming
By Mark Summerfield ISBN: 9780132354189 Publisher: Prentice Hall
Prepared for Paul Waddell, Safari ID: pwaddell@u.washington.edu
Print Publication Date: 2007/10/19
User number: 905221 Copyright 2007, Safari Books Online, LLC.
This PDF is exclusively for your use in accordance with the Safari Terms of Service. No part of it may be reproduced or transmitted in any form by any means without the prior
written permission for reprints and excerpts from the publisher. Redistribution or other use that violates the fair use priviledge under U.S. copyright laws (see 17 USC107) or that
otherwise violates the Safari Terms of Service is strictly prohibited.
Add signature pdf - C# PDF File Permission Library: add, remove, update PDF file permission in C#.net, ASP.NET, MVC, WPF
Tell C# users how to set PDF file permissions, like printing, copying, modifying, extracting, annotating, form filling, etc
pdf signature; add signature to pdf acrobat
Add signature pdf - VB.NET PDF File Permission Library: add, remove, update PDF file permission in vb.net, ASP.NET, MVC, WPF
VB.NET Tutorial for How to Set PDF File Access Permissions Using XDoc.PDF for .NET
pdf sign; add jpg signature to pdf
The code above is the whole thing. The WaterQualityModel is a QAbstractTable-
Model subclass that provides read-only access to a water quality data file. The
WaterQualityView is the class we will develop in this section. One special thing that we
have done here is to create a QScrollArea widget and add the water quality view to it—
this basically means that the water quality view can be as wide and as tall as we like and
the scroll area will take care of scrolling issues.
We will see shortly that keyboard users can navigate in the water quality view using the up
and down arrow keys, and to ensure that the selected row is always visible we must pass
the scroll area to the water quality view so that our key press handler can interact with it.
Another thing that is special is that we have given initial sizes to the two parts of the
horizontal splitter so that at start up, they are roughly in the right proportions for the
widgets they are holding.
We will now review the WaterQualityView, beginning with some static data and the
initializer.
class WaterQualityView(QWidget):
FLOWCHARS = (unichr(0x21DC), unichr(0x21DD), unichr(0x21C9))
def __init__(self, parent=None):
super(WaterQualityView, self).__init__(parent)
self.scrollarea = None
self.model = None
self.setFocusPolicy(Qt.StrongFocus)
self.selectedRow = -1
self.flowfont = self.font()
size = self.font().pointSize()
if platform.system() == "Windows":
fontDb = QFontDatabase()
for face in [face.toLower() for face in fontDb.families()]:
if face.contains("unicode"):
self.flowfont = QFont(face, size)
break
else:
self.flowfont = QFont("symbol", size)
WaterQualityView.FLOWCHARS = (
chr(0xAC), chr(0xAE), chr(0xDE))
Setting the focus policy to anything (except Qt.NoFocus) means that the widget can
accept keyboard focus. We will discuss why we have done this, and the selectedRow
instance variable at the end of this section.
When water flow is going the wrong way, or too slowly, or too quickly, we want to indicate
the situation with a suitable character, for example, 
, and 
. These characters
are available in Unicode, but most of the default fonts supplied with Windows don't appear
to include the whole Unicode character set, so the arrows are all shown as 
characters.
Rapid GUI Programming with Python and Qt: The Definitive Guide to PyQt Programming
Page 478
Return to Table
of 
Contents
Rapid GUI Programming with Python and Qt: The Definitive Guide to PyQt Programming
Rapid GUI Programming with Python and Qt: The Definitive Guide to PyQt Programming
By Mark Summerfield ISBN: 9780132354189 Publisher: Prentice Hall
Prepared for Paul Waddell, Safari ID: pwaddell@u.washington.edu
Print Publication Date: 2007/10/19
User number: 905221 Copyright 2007, Safari Books Online, LLC.
This PDF is exclusively for your use in accordance with the Safari Terms of Service. No part of it may be reproduced or transmitted in any form by any means without the prior
written permission for reprints and excerpts from the publisher. Redistribution or other use that violates the fair use priviledge under U.S. copyright laws (see 17 USC107) or that
otherwise violates the Safari Terms of Service is strictly prohibited.
C# PDF Digital Signature Library: add, remove, update PDF digital
things. Add a signature or an empty signature field in any PDF file page. Search unsigned signature field in PDF document. Prepare
add signature to pdf reader; click to sign pdf
VB.NET PDF Digital Signature Library: add, remove, update PDF
things. Add a signature or an empty signature field in any PDF file page. Search unsigned signature field in PDF document. Prepare
adding a signature to a pdf file; sign pdf
(On Linux, if a Unicode character is not available in the current font, PyQt can usually find
the character in another font in which case it uses the found font just for that character.)
To solve this problem on Windows we iterate over the list of available fonts until we find
one with "Unicode" in its name. (For example, "Lucida Sans Unicode".) If we find such a
font, we store it as the flow characters' font; otherwise we fall back to the standard (but
non-Unicode) Symbol font and use the nearest equivalent characters in that font.
def setModel(self, model):
self.model = model
self.connect(self.model,
SIGNAL("dataChanged(QModelIndex,QModelIndex)"),
self.setNewSize)
self.connect(self.model, SIGNAL("modelReset()"),
self.setNewSize)
self.setNewSize()
Once a model is set on the view we connect to its data changed and reset signals so that
the view can be resized to match the available data.
def setNewSize(self):
self.resize(self.sizeHint())
self.update()
self.updateGeometry()
This method resizes the view to its preferred size, calls update() to schedule a repaint,
and updateGeometry() to tell any layout manager that is responsible for the view that
its size has changed. Because we put the view in a QScrollArea, the scroll area will
respond to changes in size by adjusting the scrollbars it provides.
def minimumSizeHint(self):
size = self.sizeHint()
fm = QFontMetrics(self.font())
size.setHeight(fm.height() * 3)
return size
We calculate the view's minimum size to be its preferred size's width and three characters
in height. In a layout this makes sense, but since a QScrollArea is used the minimum
size will in practice be whatever the scroll area decides.
def sizeHint(self):
fm = QFontMetrics(self.font())
size = fm.height()
return QSize(fm.width("9999-99-99 99:99 ") + (size * 4),
(size / 4) + (size * self.model.rowCount()))
We use the height of one character (including its inter-line spacing) as our unit of size for
both vertical and horizontal measurements. The view's preferred size is wide enough to
Rapid GUI Programming with Python and Qt: The Definitive Guide to PyQt Programming
Page 479
Return to Table
of 
Contents
Rapid GUI Programming with Python and Qt: The Definitive Guide to PyQt Programming
Rapid GUI Programming with Python and Qt: The Definitive Guide to PyQt Programming
By Mark Summerfield ISBN: 9780132354189 Publisher: Prentice Hall
Prepared for Paul Waddell, Safari ID: pwaddell@u.washington.edu
Print Publication Date: 2007/10/19
User number: 905221 Copyright 2007, Safari Books Online, LLC.
This PDF is exclusively for your use in accordance with the Safari Terms of Service. No part of it may be reproduced or transmitted in any form by any means without the prior
written permission for reprints and excerpts from the publisher. Redistribution or other use that violates the fair use priviledge under U.S. copyright laws (see 17 USC107) or that
otherwise violates the Safari Terms of Service is strictly prohibited.
C# PDF insert image Library: insert images into PDF in C#.net, ASP
How to insert and add image, picture, digital photo, scanned signature or logo into PDF document page in C#.NET class application?
pdf sign in; add signature pdf preview
C# HTML5 Viewer: Load, View, Convert, Annotate and Edit PDF
HTML5 Viewer for C# .NET enables you to create signatures to PDF, including freehand signature, text and date signature. If you need to add your own signatures
add signature pdf online; create pdf signature
show a timestamp plus four units of size to allow for the colored circles and the flow
character, and tall enough for all the rows in the model plus a quarter of the unit of size to
allow a tiny bit of margin.
The paint event isn't too difficult, but we will look at it in three parts, and only show the
code for one colored circle, since the code for all three is almost identical.
def paintEvent(self, event):
if self.model is None:
return
fm = QFontMetrics(self.font())
timestampWidth = fm.width("9999-99-99 99:99 ")
size = fm.height()
indicatorSize = int(size * 0.8)
offset = int(1.5 * (size - indicatorSize))
minY = event.rect().y()
maxY = minY + event.rect().height() + size
minY -= size
painter = QPainter(self)
painter.setRenderHint(QPainter.Antialiasing)
painter.setRenderHint(QPainter.TextAntialiasing)
If there is no model we do nothing and return. Otherwise we need to calculate some sizes.
Just like the sizeHint() we use the height of one character as our unit of size, setting
the indicatorSize (the diameter of the colored circles) to 80% of this amount. The
offset is a tiny amount of vertical spacing designed to make the circles align vertically
with the timestamp texts.
Given the large size of the datasets that the view might be asked to show it seems sensible
to only paint those items that are wholly or partially visible to the user. For this reason we
set the minimum y coordinate to the paint event rectangle's y coordinate (but minus one
size unit), and the maximum y coordinate to be the minimum plus the paint event's height
and plus one size unit. This means that we will paint from the item above the top-most
item that is wholly in the view (i.e., the one with the lowest y coordinate in range, since
point (0, 0) is the top-left corner), down to the item below the bottom-most item that is
wholly in the view, (i.e., the one with the highest y coordinate in range).
A paint event's event parameter contains the size of the region that needs repainting. Very
often we can disregard this information and simply paint the entire widget, but sometimes,
as here, we make use of the information to make our painting more efficient.
y = 0
for row in range(self.model.rowCount()):
x = 0
if minY <= y <= maxY:
painter.save()
painter.setPen(self.palette().color(QPalette.Text))
if row == self.selectedRow:
painter.fillRect(x, y + (offset * 0.8),
self.width(), size,
Rapid GUI Programming with Python and Qt: The Definitive Guide to PyQt Programming
Page 480
Return to Table
of 
Contents
Rapid GUI Programming with Python and Qt: The Definitive Guide to PyQt Programming
Rapid GUI Programming with Python and Qt: The Definitive Guide to PyQt Programming
By Mark Summerfield ISBN: 9780132354189 Publisher: Prentice Hall
Prepared for Paul Waddell, Safari ID: pwaddell@u.washington.edu
Print Publication Date: 2007/10/19
User number: 905221 Copyright 2007, Safari Books Online, LLC.
This PDF is exclusively for your use in accordance with the Safari Terms of Service. No part of it may be reproduced or transmitted in any form by any means without the prior
written permission for reprints and excerpts from the publisher. Redistribution or other use that violates the fair use priviledge under U.S. copyright laws (see 17 USC107) or that
otherwise violates the Safari Terms of Service is strictly prohibited.
C# HTML5 Viewer: Load, View, Convert, Annotate and Edit Word
Convert Microsoft Office Word to searchable PDF online, create Viewer for C# .NET Signatures supports add signatures to Word and remove signature from Word
adding signature to pdf file; export pdf to word sign in
C# WPF Viewer: Load, View, Convert, Annotate and Edit Tiff
functionalities. convert Tiff file to PDF, add annotations to Tiff, Create signature on tiff, etc. Please refer to more details below:
adding signature to pdf; add signature to pdf online
self.palette().highlight())
painter.setPen(self.palette().color(
QPalette.HighlightedText))
timestamp = self.model.data(
self.model.index(row, TIMESTAMP)).toDateTime()
painter.drawText(x, y + size,
timestamp.toString(TIMESTAMPFORMAT))
x += timestampWidth
temperature = self.model.data(
self.model.index(row, TEMPERATURE))
temperature = temperature.toDouble()[0]
if temperature < 20:
color = QColor(0, 0,
int(255 * (20 - temperature) / 20))
elif temperature > 25:
color = QColor(int(255 * temperature / 100), 0, 0)
else:
color = QColor(0, int(255 * temperature / 100), 0)
painter.setPen(Qt.NoPen)
painter.setBrush(color)
painter.drawEllipse(x, y + offset, indicatorSize,
indicatorSize)
x += size
We iterate over every row in the model, but only paint those with a y coordinate that is in
range. Once we have a row to paint, we set the pen (used for drawing text) to the palette's
text color. If the row is selected (something we will explain after covering the paint event),
we paint the background in the palette's highlight color, and set the pen to the palette's
highlighted text color.
Having set up the text color, and possibly painted the background, we then retrieve and
draw the row's timestamp. For each row we keep an x coordinate that tells us how far across
we are, and that we increment by the font metrics timestamp width we calculated earlier.
The first colored circle is used to indicate the water's temperature in °C. If the water is too
cool we use a color with a blue tint; if it is too warm we use a color with a red tint; otherwise
we use a green tint. Then we switch off the pen and set the brush to the color we have set
up and paint an ellipse to the right of the timestamp. The drawEllipse() method will
draw a circle in this case because the width and height of the rectangle in which the ellipse
is drawn are the same.
We then increment the x coordinate. Now we repeat the process for the other two colored
circle indicators, using the same tinting approach as we did for temperature. We have
omitted the code for these since it is structurally identical to the code used for the
temperature circle.
flow = self.model.data(
self.model.index(row, INLETFLOW))
flow = flow.toDouble()[0]
char = None
if flow <= 0:
Rapid GUI Programming with Python and Qt: The Definitive Guide to PyQt Programming
Page 481
Return to Table
of 
Contents
Rapid GUI Programming with Python and Qt: The Definitive Guide to PyQt Programming
Rapid GUI Programming with Python and Qt: The Definitive Guide to PyQt Programming
By Mark Summerfield ISBN: 9780132354189 Publisher: Prentice Hall
Prepared for Paul Waddell, Safari ID: pwaddell@u.washington.edu
Print Publication Date: 2007/10/19
User number: 905221 Copyright 2007, Safari Books Online, LLC.
This PDF is exclusively for your use in accordance with the Safari Terms of Service. No part of it may be reproduced or transmitted in any form by any means without the prior
written permission for reprints and excerpts from the publisher. Redistribution or other use that violates the fair use priviledge under U.S. copyright laws (see 17 USC107) or that
otherwise violates the Safari Terms of Service is strictly prohibited.
C# WinForms Viewer: Load, View, Convert, Annotate and Edit Tiff
Viewer provides other utility features for processing Tiff while in preview, such as convert Tiff file to PDF, add annotations to Tiff, Create signature on tiff
add signature block to pdf; pdf converter sign in
.NET PDF SDK - Description of All PDF Processing Control Feastures
Create signatures in existing PDF signature fields; Create signatures in new fields which hold the signature; Add signature image to PDF file. PDF Hyperlink Edit
add signature to pdf in preview; create pdf with signature field
char = WaterQualityView.FLOWCHARS[0]
elif flow < 3:
char = WaterQualityView.FLOWCHARS[1]
elif flow > 5.5:
char = WaterQualityView.FLOWCHARS[2]
if char is not None:
painter.setFont(self.flowfont)
painter.drawText(x, y + size, char)
painter.restore()
y += size
if y > maxY:
break
If the water flow is in the wrong direction, or is too slow or too fast, we draw a suitable
character, using the font and characters that were set in the initializer.
At the end we increment the y coordinate ready for the next row of data, but if we have
gone past the last row that is in view, we stop.
The code we have written so far is sufficient to provide a read-only view of the dataset. But
users often want to highlight an item. The easiest way to do this is to add a mouse press
event handler.
def mousePressEvent(self, event):
fm = QFontMetrics(self.font())
self.selectedRow = event.y() // fm.height()
self.update()
self.emit(SIGNAL("clicked(QModelIndex)"),
self.model.index(self.selectedRow, 0))
The unit of size used for all our calculations is the height of a character. We divide the
mouse position's y coordinate (which is relative to the top-left corner of the widget) by the
unit of size, to find which row the user clicked. We use integer division because row
numbers are whole numbers. Then we call update() to schedule a paint event. In the
paintEvent() we saw that the selected row is drawn using highlighted text and
background colors. We also emit a clicked() signal, with the model index of the first
column of the row that was clicked. The signal is not used by this application, but providing
it is good practice when implementing custom views.
Keyboard users are catered for already by the scroll area: They can scroll using the Page
Up and Page Down keys. But we ought to provide a means for keyboard users to select an
item. To do this we must make sure that the widget has a suitable focus policy—we did this
in the initializer—and we must also provide a key press event handler.
def keyPressEvent(self, event):
if self.model is None:
return
row = -1
if event.key() == Qt.Key_Up:
Rapid GUI Programming with Python and Qt: The Definitive Guide to PyQt Programming
Page 482
Return to Table
of 
Contents
Rapid GUI Programming with Python and Qt: The Definitive Guide to PyQt Programming
Rapid GUI Programming with Python and Qt: The Definitive Guide to PyQt Programming
By Mark Summerfield ISBN: 9780132354189 Publisher: Prentice Hall
Prepared for Paul Waddell, Safari ID: pwaddell@u.washington.edu
Print Publication Date: 2007/10/19
User number: 905221 Copyright 2007, Safari Books Online, LLC.
This PDF is exclusively for your use in accordance with the Safari Terms of Service. No part of it may be reproduced or transmitted in any form by any means without the prior
written permission for reprints and excerpts from the publisher. Redistribution or other use that violates the fair use priviledge under U.S. copyright laws (see 17 USC107) or that
otherwise violates the Safari Terms of Service is strictly prohibited.
VB.NET PDF insert image library: insert images into PDF in vb.net
project. Import graphic picture, digital photo, signature and logo into PDF document. Add images to any selected PDF page in VB.NET.
sign pdf online; add signature image to pdf
How to C#: Basic SDK Concept of XDoc.PDF for .NET
You may add PDF document protection functionality into your C# program. To be specific, you can edit PDF password and digital signature, and set PDF file
pdf export sign in; create signature pdf
row = max(0, self.selectedRow - 1)
elif event.key() == Qt.Key_Down:
row = min(self.selectedRow + 1, self.model.rowCount() - 1)
if row != -1 and row != self.selectedRow:
self.selectedRow = row
if self.scrollarea is not None:
fm = QFontMetrics(self.font())
y = fm.height() * self.selectedRow
self.scrollarea.ensureVisible(0, y)
self.update()
self.emit(SIGNAL("clicked(QModelIndex)"),
self.model.index(self.selectedRow, 0))
else:
QWidget.keyPressEvent(self, event)
We have chosen to support just two key presses: Up Arrow and Down Arrow. If the user
presses either of these we increment or decrement the selected row, make sure that the
selected row is in range, and then schedule a paint event. If the user navigates to the row
above the top-most visible row or below the bottom-most visible row, we tell the scroll area
to make sure that the row that has been scrolled to is visible—if necessary, the scroll area
will scroll to achieve this. We also emit a clicked() signal with the newly selected row's
model index. It is quite conventional to use a clicked() signal in this circumstance, since
in effect the user is "clicking" using the keyboard—after all, the signals and slots mechanism
is concerned with what the user wants rather than how they asked for it, and here they just
want to select a row.
If we do not handle the key press ourselves, i.e., for all other key presses, we pass the event
on to the base class.
The water quality view widget is visually very different from the table view shown beside
it, yet it did not require that much code to implement and was not too difficult to program.
We made the widget fairly efficient by reducing the amount of unnecessary painting. We
also made the painting code as simple as possible by ensuring that the widget was always
exactly the size necessary to display the entire dataset. The disadvantage of this approach
is that it pushes responsibility on to the programmer using our widget to use a
QScrollArea, although this saves us from having to implement scrolling ourselves.
The water quality view visualizes the data in one-to-one correspondence with the data in
the model, but we are not constrained to do this. It is also possible to create custom views
that show aggregated data. In this case for example, we could have shown one entry per
day, or per hour, perhaps by averaging each day or hour's readings.
Generic Delegates
As we have seen in earlier chapters, custom delegates allow us to exercise complete control
over the appearance and behavior of the data items that appear in views. While it is obvious
Rapid GUI Programming with Python and Qt: The Definitive Guide to PyQt Programming
Page 483
Return to Table
of 
Contents
Rapid GUI Programming with Python and Qt: The Definitive Guide to PyQt Programming
Rapid GUI Programming with Python and Qt: The Definitive Guide to PyQt Programming
By Mark Summerfield ISBN: 9780132354189 Publisher: Prentice Hall
Prepared for Paul Waddell, Safari ID: pwaddell@u.washington.edu
Print Publication Date: 2007/10/19
User number: 905221 Copyright 2007, Safari Books Online, LLC.
This PDF is exclusively for your use in accordance with the Safari Terms of Service. No part of it may be reproduced or transmitted in any form by any means without the prior
written permission for reprints and excerpts from the publisher. Redistribution or other use that violates the fair use priviledge under U.S. copyright laws (see 17 USC107) or that
otherwise violates the Safari Terms of Service is strictly prohibited.
that if we have many models we are likely to want a custom delegate for most if not all of
them, what is not so obvious, is that the custom delegates will very likely have a lot of
duplicate code.
[*]
[*]
This section is partly based on ideas from the author's whitepaper, "Qt 4's Model/View Delegates", available from http://www.ics.com/developers/papers/.
Imagine that we have just four models, each of which has an integer ID column, some
string columns holding plain text, a description column holding HTML text, and for some
of the models, one or two floating-point columns. All the models have the ID as their first
column, but the other columns don't match up, so each one requires its own custom
delegate. Providing the custom delegates is not a big undertaking, but the code dealing
with the integer IDs might be the same in all of them, similarly for the strings, HTML
strings, and floating-point numbers.
Now imagine that we have to write custom delegates for another half dozen new models:
Much of the code will again be duplicated—and this will probably make maintenance more
difficult.
What would be better, particularly for models that have one data type per column like
database tables, is if instead of creating a custom delegate for each model, we could
compose a delegate from a set of generic components. This would mean that the
maintenance would be confined to the generic components, and a bug fix in one would
automatically benefit any view that made use of it.
In code, the effect we are after is something like this:
self.table1 = QTableView()
self.table1.setModel(self.model1)
delegate1 = GenericDelegate(self)
delegate1.insertColumnDelegate(1, PlainTextColumnDelegate())
delegate1.insertColumnDelegate(2, PlainTextColumnDelegate())
delegate1.insertColumnDelegate(3, RichTextColumnDelegate())
delegate1.insertColumnDelegate(4, IntegerColumnDelegate())
self.table1.setItemDelegate(delegate1)
self.table2 = QTableView()
self.table2.setModel(self.model2)
delegate2 = GenericDelegate(self)
delegate2.insertColumnDelegate(1, PlainTextColumnDelegate())
delegate2.insertColumnDelegate(2, IntegerColumnDelegate())
delegate2.insertColumnDelegate(3, FloatColumnDelegate())
delegate2.insertColumnDelegate(4, FloatColumnDelegate())
delegate2.insertColumnDelegate(5, RichTextColumnDelegate())
self.table2.setItemDelegate(delegate2)
Here we have two separate models, but both use generic delegates that are composed of
predefined column delegates that are data type specific.
Rapid GUI Programming with Python and Qt: The Definitive Guide to PyQt Programming
Page 484
Return to Table
of 
Contents
Rapid GUI Programming with Python and Qt: The Definitive Guide to PyQt Programming
Rapid GUI Programming with Python and Qt: The Definitive Guide to PyQt Programming
By Mark Summerfield ISBN: 9780132354189 Publisher: Prentice Hall
Prepared for Paul Waddell, Safari ID: pwaddell@u.washington.edu
Print Publication Date: 2007/10/19
User number: 905221 Copyright 2007, Safari Books Online, LLC.
This PDF is exclusively for your use in accordance with the Safari Terms of Service. No part of it may be reproduced or transmitted in any form by any means without the prior
written permission for reprints and excerpts from the publisher. Redistribution or other use that violates the fair use priviledge under U.S. copyright laws (see 17 USC107) or that
otherwise violates the Safari Terms of Service is strictly prohibited.
With this approach we only ever have to create a single plain text column delegate, a single
rich text column delegate, and so on, for each data type we want to handle, such as integers,
floating-point numbers, dates, times, and date/times. In addition we might create some
project-specific column delegates to handle custom types, but for any given data type there
would only be one column delegate, drastically cutting down on code duplication, and
ensuring that any model can have a "custom" delegate simply by using a generic delegate
with suitable column delegates added.
In this section we will see how to create a GenericDelegate class and a couple of example
column delegates. Then we will see how they are used in the context of the application
shown in Figure 16.2.
Figure 16.2. A Table View Using Generic Delegates
The GenericDelegate class is simple, because it passes on almost all the work to other
classes.
class GenericDelegate(QItemDelegate):
def __init__(self, parent=None):
super(GenericDelegate, self).__init__(parent)
self.delegates = {}
The initializer calls super() as usual, and also creates an empty dictionary. The keys will
be column indexes and the values will be instances of QItemDelegate subclasses.
def insertColumnDelegate(self, column, delegate):
delegate.setParent(self)
self.delegates[column] = delegate
When a new column delegate is inserted into the generic delegate, the generic delegate
takes ownership of it, and inserts it into the dictionary.
def removeColumnDelegate(self, column):
if column in self.delegates:
del self.delegates[column]
Rapid GUI Programming with Python and Qt: The Definitive Guide to PyQt Programming
Page 485
Return to Table
of 
Contents
Rapid GUI Programming with Python and Qt: The Definitive Guide to PyQt Programming
Rapid GUI Programming with Python and Qt: The Definitive Guide to PyQt Programming
By Mark Summerfield ISBN: 9780132354189 Publisher: Prentice Hall
Prepared for Paul Waddell, Safari ID: pwaddell@u.washington.edu
Print Publication Date: 2007/10/19
User number: 905221 Copyright 2007, Safari Books Online, LLC.
This PDF is exclusively for your use in accordance with the Safari Terms of Service. No part of it may be reproduced or transmitted in any form by any means without the prior
written permission for reprints and excerpts from the publisher. Redistribution or other use that violates the fair use priviledge under U.S. copyright laws (see 17 USC107) or that
otherwise violates the Safari Terms of Service is strictly prohibited.
This method is included for completeness, but is not likely to be used. If a column delegate
is removed the generic delegate will simply use the QItemDelegate base class for that
column.
def paint(self, painter, option, index):
delegate = self.delegates.get(index.column())
if delegate is not None:
delegate.paint(painter, option, index)
else:
QItemDelegate.paint(self, painter, option, index)
The structure of this method is the key to how the GenericDelegate class works. We
begin by getting the column delegate for the given column. If we get a delegate we pass on
the work to it; otherwise we pass on the work to the base class.
def createEditor(self, parent, option, index):
delegate = self.delegates.get(index.column())
if delegate is not None:
return delegate.createEditor(parent, option, index)
else:
return QItemDelegate.createEditor(self, parent, option,
index)
This method follows the same pattern as the paint() method, except that it returns a
value (the editor that was created for it).
def setEditorData(self, editor, index):
delegate = self.delegates.get(index.column())
if delegate is not None:
delegate.setEditorData(editor, index)
else:
QItemDelegate.setEditorData(self, editor, index)
def setModelData(self, editor, model, index):
delegate = self.delegates.get(index.column())
if delegate is not None:
delegate.setModelData(editor, model, index)
else:
QItemDelegate.setModelData(self, editor, model, index)
These last two GenericDelegate methods follow the same pattern as the paint() and
createEditor() methods, using the column delegate if one has been set for the given
column, and using the QItemDelegate base class otherwise.
Now that we have seen the GenericDelegate's implementation, we can turn our
attention to the column delegates that can be inserted into it. In chap16/
genericdelegates.py we provide the IntegerColumnDelegate,
DateColumnDelegate, PlainTextColumnDelegate, and
Rapid GUI Programming with Python and Qt: The Definitive Guide to PyQt Programming
Page 486
Return to Table
of 
Contents
Rapid GUI Programming with Python and Qt: The Definitive Guide to PyQt Programming
Rapid GUI Programming with Python and Qt: The Definitive Guide to PyQt Programming
By Mark Summerfield ISBN: 9780132354189 Publisher: Prentice Hall
Prepared for Paul Waddell, Safari ID: pwaddell@u.washington.edu
Print Publication Date: 2007/10/19
User number: 905221 Copyright 2007, Safari Books Online, LLC.
This PDF is exclusively for your use in accordance with the Safari Terms of Service. No part of it may be reproduced or transmitted in any form by any means without the prior
written permission for reprints and excerpts from the publisher. Redistribution or other use that violates the fair use priviledge under U.S. copyright laws (see 17 USC107) or that
otherwise violates the Safari Terms of Service is strictly prohibited.
Documents you may be interested
Documents you may be interested