Reputation: 627
I want to display some images on my GUI, first when I click on the button, to select first image, everything act normal, my image is displayed fitInView, but when I want to select the next image, dark magic happens.. my second image is not in center like the first one, is on top of the QGraphicsView, and also it seem like old image's QScenes doesn't disappear, I have the ScrollBar from risg and bottom and I can scrool until I have al blank on QGraphicsView, what is the problem? I can't figured out..
My code:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
# from PyQt4 import QtCore, QtWidgets
class Graph(QtWidgets.QGraphicsView):
def __init__(self, parent=None):
super(Graph, self).__init__(parent)
scene = QtWidgets.QGraphicsScene(self)
self.setScene(scene)
self.pixmap = QtGui.QPixmap()
self.m_pixmap_item = self.scene().addPixmap(self.pixmap)
def setPixmap(self, _pixmap):
self.pixmap = _pixmap
# self.m_pixmap_item = self.scene().addPixmap(self.pixmap)
self.m_pixmap_item.setPixmap(self.pixmap)
self.fitInView(self.m_pixmap_item, QtCore.Qt.KeepAspectRatio)
def resizeEvent(self, event):
if not self.m_pixmap_item.pixmap().isNull():
self.fitInView(self.m_pixmap_item, QtCore.Qt.KeepAspectRatio)
super(Graph, self).resizeEvent(event)
mainwindow part:
class Window(QtWidgets.QWidget):
def __init__(self):
super(Window, self).__init__()
self.setMinimumSize(640, 480)
# --> Create Class ResizbleRubberBand <-> Parent: QLabel
self.band = Graph(self)
# --> Create buttons & functions
self.fileOpen_btn = QtWidgets.QPushButton()
self.create_and_format_btn(self.fileOpen_btn, self.fileOpen, 'GUI/icons/file.png', 32)
btn_Layout = QtWidgets.QVBoxLayout()
btn_layout_1 = QtWidgets.QHBoxLayout()
btn_layout_1.addWidget(self.fileOpen_btn)
btn_Layout.addLayout(btn_layout_1)
layout = QtWidgets.QHBoxLayout(self)
layout.setAlignment(QtCore.Qt.AlignCenter)
layout.addWidget(self.band)
layout.addLayout(btn_Layout)
def create_and_format_btn(self, btn_name, btn_function, btn_icon, btn_iconsize):
btn_name.clicked.connect(btn_function)
btn_name.setIcon(QtGui.QIcon(btn_icon))
btn_name.setIconSize(QtCore.QSize(btn_iconsize, btn_iconsize))
def fileOpen(self):
path = QtWidgets.QFileDialog.getOpenFileName(self, 'Open File')
filename = path[0]
self.loadImage_On_Pixmap(filename)
def loadImage_On_Pixmap(self, file):
f = QtGui.QPixmap(file)
self.band.setPixmap(f)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = Window()
# window.setGeometry(800, 100, 600, 500)
window.show()
sys.exit(app.exec_())
First Image (Normal):
Second Image (Strange):
Upvotes: 1
Views: 170
Reputation: 13681
Try it:
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QFileDialog
class PhotoViewer(QtWidgets.QGraphicsView):
photoClicked = QtCore.pyqtSignal(QtCore.QPoint)
def __init__(self, parent):
super(PhotoViewer, self).__init__(parent)
self._zoom = 0
self._empty = True
self._scene = QtWidgets.QGraphicsScene(self)
self._photo = QtWidgets.QGraphicsPixmapItem()
self._scene.addItem(self._photo)
self.setScene(self._scene)
self.setTransformationAnchor(QtWidgets.QGraphicsView.AnchorUnderMouse)
self.setResizeAnchor(QtWidgets.QGraphicsView.AnchorUnderMouse)
self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.setBackgroundBrush(QtGui.QBrush(QtGui.QColor(30, 30, 30)))
self.setFrameShape(QtWidgets.QFrame.NoFrame)
def hasPhoto(self):
return not self._empty
def fitInView(self, scale=True):
rect = QtCore.QRectF(self._photo.pixmap().rect())
if not rect.isNull():
self.setSceneRect(rect)
if self.hasPhoto():
unity = self.transform().mapRect(QtCore.QRectF(0, 0, 1, 1))
self.scale(1 / unity.width(), 1 / unity.height())
viewrect = self.viewport().rect()
scenerect = self.transform().mapRect(rect)
factor = min(viewrect.width() / scenerect.width(),
viewrect.height() / scenerect.height())
self.scale(factor, factor)
self._zoom = 0
def setPhoto(self, pixmap=None):
self._zoom = 0
if pixmap and not pixmap.isNull():
self._empty = False
self.setDragMode(QtWidgets.QGraphicsView.ScrollHandDrag)
self._photo.setPixmap(pixmap)
else:
self._empty = True
self.setDragMode(QtWidgets.QGraphicsView.NoDrag)
self._photo.setPixmap(QtGui.QPixmap())
self.fitInView()
def wheelEvent(self, event):
if self.hasPhoto():
if event.angleDelta().y() > 0:
factor = 1.25
self._zoom += 1
else:
factor = 0.8
self._zoom -= 1
if self._zoom > 0:
self.scale(factor, factor)
elif self._zoom == 0:
self.fitInView()
else:
self._zoom = 0
def toggleDragMode(self):
if self.dragMode() == QtWidgets.QGraphicsView.ScrollHandDrag:
self.setDragMode(QtWidgets.QGraphicsView.NoDrag)
elif not self._photo.pixmap().isNull():
self.setDragMode(QtWidgets.QGraphicsView.ScrollHandDrag)
def mousePressEvent(self, event):
if self._photo.isUnderMouse():
self.photoClicked.emit(QtCore.QPoint(event.pos()))
super(PhotoViewer, self).mousePressEvent(event)
class Window(QtWidgets.QWidget):
def __init__(self):
super(Window, self).__init__()
self.viewer = PhotoViewer(self)
self.btnLoad = QtWidgets.QToolButton(self)
self.btnLoad.setIcon(QtGui.QIcon('im.png'))
self.btnLoad.setIconSize(QtCore.QSize(32, 32))
self.btnLoad.clicked.connect(self.loadImage)
layout = QtWidgets.QHBoxLayout(self)
layout.addWidget(self.viewer)
layout.addWidget(self.btnLoad)
def loadImage(self):
filename, _ = QtWidgets.QFileDialog.getOpenFileName(self, 'Open File')
if filename:
self.viewer.setPhoto(QtGui.QPixmap(filename))
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
window = Window()
window.setGeometry(400, 100, 640, 480)
window.show()
sys.exit(app.exec_())
Upvotes: 1