import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *

#################################
class ImageView(QGraphicsView):
    def __init__(self, parent=None, origPixmap=None):
            """
            QGraphicsView that will show an image scaled to the current widget size
            using events
            """
            super(ImageView, self).__init__(parent)
            self.origPixmap = origPixmap
            QMetaObject.connectSlotsByName(self)
            self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
            self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)

            self.setTransformationAnchor(self.AnchorUnderMouse)
            self.setSceneRect(0, 0, self.origPixmap.height(), self.origPixmap.height())
            self.app = app
            self.action = None
            self.oldPos = None
            self.hvalue = self.vvalue = 0
            self.orgScale = [0,0]
            self.setBackgroundBrush(QBrush(QColor(60, 60, 60, 255), Qt.SolidPattern))
            
    def resizeEvent(self, event):
            size = event.size()
            item =  self.items()[0]
            #self.setSceneRect(0, 0, self.origPixmap.width()*10, self.origPixmap.height()*10)

            '''
            # Using current pixmap after n-resizes would get really blurry image
            pixmap = item.pixmap()
            pixmap = self.origPixmap
            pixmap = pixmap.scaled(size, Qt.KeepAspectRatio, Qt.SmoothTransformation)
            self.centerOn(1.0, 1.0)
            item.setPixmap(pixmap)
            '''

    def wheelEvent(self, event):
        factor = 1.41 ** ((event.delta()*.5) / 240.0)
        self.scale(factor, factor)

    def mousePressEvent(self,event):
        if (app.keyboardModifiers() == Qt.AltModifier  and event.button() == Qt.MiddleButton):
            self.setCursor(Qt.SizeAllCursor)
            self.action = 'Move'
            self.oldPos = event.pos()

        if (app.keyboardModifiers() == Qt.AltModifier  and event.button() == Qt.RightButton):
            self.setCursor(Qt.SizeVerCursor)
            self.oldPos = event.pos()
            self.action = 'Zoom'

    def mouseMoveEvent(self,event):
            if self.action == 'Move':
                if self.hvalue == 0  and self.vvalue == 0:
                    self.hvalue = self.horizontalScrollBar().value()
                    self.vvalue = self.verticalScrollBar().value()
                move = event.pos() - self.oldPos
                
                self.horizontalScrollBar().setValue(self.hvalue - move.x()*2)
                self.verticalScrollBar().setValue(self.vvalue - move.y()*2)


            if self.action == 'Zoom':
                if self.orgScale == [0,0]:
                        self.orgScale = [self.transform().m11(),self.transform().m22()]
                curScale = [self.transform().m11(),self.transform().m22()]
                scale = float(event.pos().x())/float(self.oldPos.x())
                self.setTransformationAnchor(self.AnchorViewCenter)
                
                value = self.orgScale[0]*scale/curScale[0]
                print value
                self.scale(value,value)

            super(ImageView,self).mouseMoveEvent(event)

    def mouseReleaseEvent(self,event):
        self.setCursor(Qt.ArrowCursor)
        self.action = self.oldPos = self.oldPos = None
        self.hvalue = self.vvalue = 0
        self.orgScale = [0,0]
        self.setTransformationAnchor(self.AnchorUnderMouse)

##############################
app = QApplication(sys.argv)

pic = QPixmap(r'D:\Pictures\86.jpg')
grview = ImageView(origPixmap=pic)

scene = QGraphicsScene()
a = scene.addPixmap(pic)
a.setPos(280,300)

grview.setScene(scene)
grview.show()

sys.exit(app.exec_())
