I'm constructing a GUI for showing photographs (from a folder) in a grid using QGraphicsScene
and QGraphicsPixmapItem
(code below). Now I want to open the corresponding original image when clicking on one of the QGraphicsPixmapItems
. I overrode MousePressEvent and made the program do "something" if I click inside the QGraphicsScene
, but now I wonder how to retrieve the information which item was clicked in order to open the corresponding image.
import sys
from PyQt5 import QtWidgets, QtCore
from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QGraphicsPixmapItem
from PyQt5.QtCore import Qt, QRect
from PyQt5.QtGui import QPixmap
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.showMaximized()
self.central()
def central(self):
self.scene = QtWidgets.QGraphicsScene(QtCore.QRectF(0, 0, 1080, 1000), self)
self.graphicsview = QtWidgets.QGraphicsView(self.scene)
self.setCentralWidget(self.graphicsview)
self.resize(1000, 1000)
list = ['./images/1.JPG', './images/2.JPG', './images/3.JPG', './images/4.JPG',
'./images/5.JPG', './images/6.JPG', './images/7.JPG', './images/8.JPG']
self.t_list = []
for n in range(len(list)):
self.label = QLabel()
self.u_pixmap = QPixmap(list[n])
imgsize = min(self.u_pixmap.width(), self.u_pixmap.height())
rect = QRect(
int((self.u_pixmap.width() - imgsize) / 2),
int((self.u_pixmap.height() - imgsize) / 2), imgsize, imgsize)
self.v_pixmap = self.u_pixmap.copy(rect)
self.pixmap = self.v_pixmap.scaled(200, 200, Qt.KeepAspectRatio, Qt.SmoothTransformation)
self.item = QGraphicsPixmapItem()
self.item.setPixmap(self.pixmap)
self.scene.addItem(self.item)
g = 210
a = 5
y = int(n/a)
x = n - (y * a)
self.item.setOffset(x * g, y * g)
def mousePressEvent(self, event):
if event.button() == Qt.RightButton:
print("item clicked")
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MainWindow()
sys.exit(app.exec_())
To find the original pixmap corresponding to an item in the graphics view, you could store it as data in the item via QGraphicsItem.setData()
, e.g.
def central(self):
....
self.v_pixmap = self.u_pixmap.copy(rect)
self.pixmap = self.v_pixmap.scaled(200, 200, Qt.KeepAspectRatio, Qt.SmoothTransformation)
self.item = QGraphicsPixmapItem()
self.item.setPixmap(self.pixmap)
self.item.setData(0, self.v_pixmap)
....
This would allow you to retrieve the original pixmap from the item via item.data(0)
.
To find the item under the mouse cursor, you could use QGraphicsView.itemAt
in MainWindow.mousePressEvent
. The position of the mouse cursor is given by event.pos()
. However, this position is relative to the local coordinate system of the main window. To match these coordinates to the coordinate system of the graphics view you need to map them to a coordinate system that is common to both the graphics view and the main window such as the global coordinate system. With this in mind, MainWindow.mousePressEvent
would become something like
def mousePressEvent(self, event):
if event.button() == Qt.RightButton:
print("item clicked")
pos = self.mapToGlobal(event.pos())
pos1 = self.graphicsview.mapFromGlobal(pos)
item = self.graphicsview.itemAt(pos1)
if item:
u_pixmap = item.data(0)
if u_pixmap:
self.label.setPixmap(u_pixmap)
self.label.show()