summaryrefslogtreecommitdiff
path: root/lib/taurus/qt/qtgui/display/qpixmapwidget.py
blob: fcad541d2fa3c5ad24383e4b9198904713158a43 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
#!/usr/bin/env python

#############################################################################
##
## This file is part of Taurus
## 
## http://taurus-scada.org
##
## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain
## 
## Taurus is free software: you can redistribute it and/or modify
## it under the terms of the GNU Lesser General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
## 
## Taurus is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU Lesser General Public License for more details.
## 
## You should have received a copy of the GNU Lesser General Public License
## along with Taurus.  If not, see <http://www.gnu.org/licenses/>.
##
#############################################################################

"""This module contains a pure Qt widget that displays an image"""

__all__ = ["QPixmapWidget"]

__docformat__ = 'restructuredtext'

from taurus.external.qt import Qt
import taurus.qt.qtgui.resource

getPixmap = taurus.qt.qtgui.resource.getPixmap

class QPixmapWidget(Qt.QWidget):
    """This widget displays an image (pixmap). By default the pixmap is
    scaled to the widget size and the aspect ratio is kept.
    The default alignment of the pixmap inside the widget space is horizontal
    left, vertical center."""
    
    DefaultAlignment          = Qt.Qt.AlignLeft | Qt.Qt.AlignVCenter
    DefaultAspectRatioMode    = Qt.Qt.KeepAspectRatio
    DefaultTransformationMode = Qt.Qt.SmoothTransformation
    
    def __init__(self, parent=None, designMode=False):
        self._pixmap = Qt.QPixmap()
        self._pixmapDrawn = None
        self._alignment = self.DefaultAlignment
        self._pixmapAspectRatioMode = self.DefaultAspectRatioMode
        self._pixmapTransformationMode = self.DefaultTransformationMode
        
        Qt.QWidget.__init__(self, parent)
    
    def _getPixmap(self):
        if self._pixmapDrawn is None:
            self._pixmapDrawn = self.recalculatePixmap()
        return self._pixmapDrawn
    
    def recalculatePixmap(self):
        origPixmap = self._pixmap
        if origPixmap.isNull():
            return origPixmap
        return origPixmap.scaled(self.size(), self._pixmapAspectRatioMode,
                                 self._pixmapTransformationMode)
    
    def _setDirty(self):
        self._pixmapDrawn = None
    
    def paintEvent(self, paintEvent):
        """Overwrite the paintEvent from QWidget to draw the pixmap"""
        pixmap = self._getPixmap()
                
        w, h = self.width(), self.height()
        painter = Qt.QPainter(self)
        painter.setRenderHint(Qt.QPainter.Antialiasing)
        pw, ph = pixmap.width(), pixmap.height()
        align = self._alignment
        hAlign = align & Qt.Qt.AlignHorizontal_Mask
        vAlign = align & Qt.Qt.AlignVertical_Mask
        x, y = 0, 0
        if hAlign & Qt.Qt.AlignHCenter:
            x = (w - pw) / 2
        elif hAlign & Qt.Qt.AlignRight:
            x = w - pw
        if vAlign & Qt.Qt.AlignVCenter:
            y = (h - ph) / 2
        elif vAlign & Qt.Qt.AlignBottom:
            y = h - ph
        x, y = max(0, x), max(0, y)
        painter.drawPixmap(x, y, pixmap)

    def resizeEvent(self, event):
        self._setDirty()
        return Qt.QWidget.resizeEvent(self, event)
        
    @classmethod
    def getQtDesignerPluginInfo(cls):
        return {
            'module' : 'taurus.qt.qtgui.display',
            'group' : 'Taurus Display',
            'icon' : ":/designer/graphicsview.png",
            'container' : False,
        }

    #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
    # QT property definition
    #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
    
    def getPixmap(self):
        """Returns the pixmap.Returns None if no pixmap is set.
        :return: the current pixmap
        :rtype: PyQt4.Qt.QPixmap"""
        return self._pixmap

    def setPixmap(self, pixmap):
        """Sets the pixmap for this widget. Setting it to None disables pixmap
        :param pixmap: the new pixmap
        :type  pixmap: PyQt4.Qt.QPixmap"""
        # make sure to make a copy because of bug in PyQt 4.4. This is actually 
        # copying the internal bitmap, just the qpixmap, so there is no performance
        # penalty here
        self._pixmap = Qt.QPixmap(pixmap)
        self._setDirty()
        self.update()
        
    def resetPixmap(self):
        """Resets the pixmap for this widget."""
        self.setPixmap(Qt.QPixmap())
    
    def getAspectRatioMode(self):
        """Returns the aspect ratio to apply when drawing the pixmap.
        :return: the current aspect ratio
        :rtype: PyQt4.Qt.AspectRatioMode"""
        return self._pixmapAspectRatioMode
        
    def setAspectRatioMode(self, aspect):
        """Sets the aspect ratio mode to apply when drawing the pixmap.
        :param pixmap: the new aspect ratio mode
        :type  pixmap: PyQt4.Qt.AspectRatioMode"""
        self._pixmapAspectRatioMode = aspect
        self._setDirty()
        self.update()
    
    def resetAspectRatioMode(self):
        """Resets the aspect ratio mode to KeepAspectRatio"""
        self.setAspectRatioMode(self.DefaultAspectRatioMode)
        
    def getTransformationMode(self):
        """Returns the transformation mode to apply when drawing the pixmap.
        :return: the current transformation mode
        :rtype: PyQt4.Qt.TransformationMode"""
        return self._pixmapTransformationMode
        
    def setTransformationMode(self, transformation):
        """Sets the transformation mode to apply when drawing the pixmap.
        :param pixmap: the new transformation mode
        :type  pixmap: PyQt4.Qt.TransformationMode"""
        self._pixmapTransformationMode = transformation
        self._setDirty()
        self.update()
    
    def resetTransformationMode(self):
        """Resets the transformation mode to SmoothTransformation"""
        self.setTransformationMode(self.DefaultTransformationMode)

    def getAlignment(self):
        """Returns the alignment to apply when drawing the pixmap.
        :return: the current alignment
        :rtype: PyQt4.Qt.Alignment"""
        return self._alignment
        
    def setAlignment(self, alignment):
        """Sets the alignment to apply when drawing the pixmap.
        :param pixmap: the new alignment
        :type  pixmap: PyQt4.Qt.Alignment"""
        self._alignment = Qt.Qt.Alignment(alignment)
        self.update()
    
    def resetAlignment(self):
        """Resets the transformation mode to Qt.Qt.AlignLeft | Qt.Qt.AlignVCenter"""
        self.setAlignment(self.DefaultAlignment)
        
    #: This property holds the widget's pixmap
    #:
    #: **Access functions:**
    #:
    #:     * :meth:`QPixmapWidget.getPixmap`
    #:     * :meth:`QPixmapWidget.setPixmap`
    #:     * :meth:`QPixmapWidget.resetLedStatus`
    pixmap = Qt.pyqtProperty("QPixmap", getPixmap, setPixmap, 
                             resetPixmap, doc="the widget's pixmap")

    #: This property holds the widget's pixmap aspect ratio mode
    #:
    #: **Access functions:**
    #:
    #:     * :meth:`QPixmapWidget.getAspectRatioMode`
    #:     * :meth:`QPixmapWidget.setAspectRatioMode`
    #:     * :meth:`QPixmapWidget.resetAspectRatioMode`
    aspectRatioMode = Qt.pyqtProperty("Qt::AspectRatioMode", getAspectRatioMode, 
                                      setAspectRatioMode, resetAspectRatioMode,
                                      doc="the widget's pixmap aspect ratio mode")

    #: This property holds the widget's pixmap transformation mode
    #:
    #: **Access functions:**
    #:
    #:     * :meth:`QPixmapWidget.getTransformationMode`
    #:     * :meth:`QPixmapWidget.setTransformationMode`
    #:     * :meth:`QPixmapWidget.resetTransformationMode`
    transformationMode = Qt.pyqtProperty("Qt::TransformationMode", getTransformationMode, 
                                         setTransformationMode, resetTransformationMode,
                                         doc="the widget's pixmap transformation mode")
    
    #: This property holds the widget's pixmap alignment
    #:
    #: **Access functions:**
    #:
    #:     * :meth:`QPixmapWidget.getAlignment`
    #:     * :meth:`QPixmapWidget.setAlignment`
    #:     * :meth:`QPixmapWidget.resetAlignment`
    alignment = Qt.pyqtProperty("Qt::Alignment", getAlignment, setAlignment, 
                                resetAlignment, doc="the widget's pixmap alignment")

def demo():
    "QPixmap Widget"
    import demo.qpixmapwidgetdemo
    return demo.qpixmapwidgetdemo.main()

def main():
    return demo()
    
if __name__ == "__main__":
    main()