Почему при выводе списка изображений в QGraphicsScene они перекрывают QRubberBand?
Есть список картинок, которые выводятся в QGraphicsScene наподобие видео.
С помощью QRubberBand проходят вычисления координат выделенной области, но при этом его не видно под выводящимися изображениями (он как первый слой торта), т.е. он как бы приклеен к QGraphicsScene.
Я хочу понять причину по которой он не отображается поверх выводимых изображений.
Сейчас это выглядит вот так:
Я хочу понять причины по которым не видно QRubberBand и было бы хорошо, если получится вывести его как на втором скриншоте.
main.py
import sys
import coordCatch
from PyQt5.Qt import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5 import QtWidgets, QtCore
class graphicsScene(QtWidgets.QGraphicsScene):
clicked = pyqtSignal()
def __init__(self, parent=None):
super(graphicsScene, self).__init__(parent)
self.xpos = None
self.ypos = None
self.selecting = False
self.setSceneRect(0,0,1063,1418)
self.selection = QtWidgets.QRubberBand(QtWidgets.QRubberBand.Rectangle)
self.addWidget(self.selection)
self.originQPoint = None
self.originCropPoint = None
self.currentQRect = None
def mousePressEvent(self, event):
self.selecting = True
self.originQPoint = event.scenePos()
self.selection.hide()
self.originCropPoint = event.scenePos()
self.clicked.emit()
def mouseMoveEvent(self, event):
if self.originQPoint is not None and self.selecting:
rect = QtCore.QRect(self.originQPoint.toPoint(),
event.scenePos().toPoint())
self.selection.setGeometry(rect)
self.selection.show()
def mouseReleaseEvent(self, event):
self.selecting = False
self.selection.hide()
self.currentQRect = QtCore.QRect(self.originCropPoint.toPoint(),
event.scenePos().toPoint())
print(self.currentQRect)
class ProcessWorker(QObject):
imageChanged = pyqtSignal(QImage)
def doWork(self):
self.image_list = ['E:/Projects/QGraphicsView + mpl/pngForDispleying/1.jpg',
'E:/Projects/QGraphicsView + mpl/pngForDispleying/2.jpg',
'E:/Projects/QGraphicsView + mpl/pngForDispleying/3.jpg',
'E:/Projects/QGraphicsView + mpl/pngForDispleying/4.jpg',
'E:/Projects/QGraphicsView + mpl/pngForDispleying/5.jpg',
'E:/Projects/QGraphicsView + mpl/pngForDispleying/6.jpg',
'E:/Projects/QGraphicsView + mpl/pngForDispleying/7.jpg',
'E:/Projects/QGraphicsView + mpl/pngForDispleying/8.jpg',
'E:/Projects/QGraphicsView + mpl/pngForDispleying/9.jpg']
f = 0
while True:
if f <= len(self.image_list) - 1:
img = QImage(self.image_list[f])
self.imageChanged.emit(img)
QThread.msleep(150)
f += 1
else:
f = 0
img = QImage(self.image_list[f])
self.imageChanged.emit(img)
QThread.msleep(1)
class ExampleApp(QtWidgets.QMainWindow, coordCatch.Ui_MainWindow):
def __init__(self):
super(ExampleApp, self).__init__()
self.setupUi(self)
self.resize(840, 740)
self.gscene = graphicsScene()
self.graphicsView.setScene(self.gscene)
self.graphicsView.show()
self.graphicsView.setFixedSize(710, 610)
self.pixmap = QGraphicsPixmapItem()
self.graphicsView.scene().addItem(self.pixmap)
self.workerThread = QThread()
self.worker = ProcessWorker()
self.worker.moveToThread(self.workerThread)
self.workerThread.finished.connect(self.worker.deleteLater)
self.workerThread.started.connect(self.worker.doWork)
self.worker.imageChanged.connect(self.setImage)
self.workerThread.start()
@pyqtSlot(QImage)
def setImage(self, image):
pixmap = QPixmap.fromImage(image)
self.pixmap.setPixmap(pixmap)
def main():
app = QtWidgets.QApplication(sys.argv)
window = ExampleApp()
window.show()
app.exec_()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
main()
coordCatch.py
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(642, 491)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.graphicsView = QtWidgets.QGraphicsView(self.centralwidget)
self.graphicsView.setGeometry(QtCore.QRect(10, 10, 441, 331))
self.graphicsView.setObjectName("graphicsView")
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
self.colorLayout = QtWidgets.QVBoxLayout()
self.nameLayout = QtWidgets.QVBoxLayout()
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
Ответы (1 шт):
Пожалуйста не публикуйте строки кода, которые не нужны в минимально-воспроизводимом примере.
Замените строку:
self._item_color = QColor(0, 0, 255, 0)
например так:
self._item_color = QColor(0, 0, 255, 55)
main.py:
import sys
# ???import random
# ???import pyautogui
from PyQt5 import QtWidgets, QtCore, QtGui
from PyQt5.Qt import *
from coordCatch import Ui_MainWindow
# ???import numpy as np
# ???import matplotlib as mpl
# ???import matplotlib.pyplot as plt
# ???from matplotlib.pyplot import *
# ???from PIL import Image
# ???from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
# --> v <----------------------------------------------------------------------------
class GraphicsScene(QtWidgets.QGraphicsScene):
clicked = pyqtSignal()
def __init__(self, parent=None):
super(GraphicsScene, self).__init__(parent)
self._pos = QPointF()
self._current_item = None
# self._item_color = QColor(0, 0, 255, 0)
self._item_color = QColor(0, 0, 255, 55) # <---- !!!
self.xpos = None
self.ypos = None
self.selecting = False
# self.setSceneRect(0, 0, 1063, 1418)
self.setSceneRect(0, 0, 800, 600)
self.selection = QtWidgets.QRubberBand(QtWidgets.QRubberBand.Rectangle)
self.addWidget(self.selection)
#print(type(self.selection))
self.originQPoint = None
#self.selection = None
self.originCropPoint = None
self.currentQRect = None
def mousePressEvent(self, event):
#self.selection = QtWidgets.QRubberBand(QtWidgets.QRubberBand.Rectangle)
self.selecting = True
self.originQPoint = event.scenePos()
self.selection.hide()
self.originCropPoint = event.scenePos()
self._pos = event.scenePos()
self._current_item = QGraphicsRectItem()
self._current_item.setBrush(self._item_color)
self._current_item.setPen(QPen(QColor("#f8f4ff"), 3, QtCore.Qt.DashLine))
self.addItem(self._current_item)
self._current_item.setRect(QRectF(self._pos, self._pos))
self.clicked.emit()
def mouseMoveEvent(self, event):
if self.originQPoint is not None and self.selecting:
rect = QtCore.QRect(self.originQPoint.toPoint(),
event.scenePos().toPoint())
self.selection.setGeometry(rect)
self.selection.show()
if self._current_item:
rect = QRectF(self._pos, event.scenePos()).normalized()
self._current_item.setRect(rect)
def mouseReleaseEvent(self, event):
self.selecting = False
self.selection.hide()
self.currentQRect = QtCore.QRect(self.originCropPoint.toPoint(),
event.scenePos().toPoint())
print(self.currentQRect)
self.removeItem(self._current_item)
self._current_item = None
# ??? global rectangle
# ??? rectangle = self.currentQRect.getRect()
#self.moved.emit(self.currentQRect)
class ProcessWorker(QObject):
imageChanged = pyqtSignal(QImage)
def doWork(self):
self.image_list = [
'lena.jpg', # !!! установите свои изображения
'audience_A.png',
'audience_B.png',
'audience_C.png',
'audience_D.png',
'Ok.png',
]
f = 0
while True:
# if f <= 8:
# ----------------> vvvvvvvvvvvvvvvvvvvvvvvv <----------------------------------
if f <= len(self.image_list) - 1:
img = QImage(self.image_list[f])
self.imageChanged.emit(img)
QThread.msleep(1500)
f += 1
else:
f = 0
img = QImage(self.image_list[f])
self.imageChanged.emit(img)
QThread.msleep(1)
class ExampleApp(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self):
super(ExampleApp, self).__init__()
self.setupUi(self)
# ??? self.counter = 0
self.resize(840, 640)
self.gscene = GraphicsScene()
self.graphicsView.setScene(self.gscene)
self.graphicsView.show()
self.graphicsView.setFixedSize(710, 610)
#self.pic = 'E:\RQC Projects\QGraphicsView + mpl\my.png'
#self.image = QImage(self.pic)
self.pixmap = QGraphicsPixmapItem()
self.graphicsView.scene().addItem(self.pixmap)
self.workerThread = QThread()
self.worker = ProcessWorker()
self.worker.moveToThread(self.workerThread)
self.workerThread.finished.connect(self.worker.deleteLater)
self.workerThread.started.connect(self.worker.doWork)
self.worker.imageChanged.connect(self.setImage)
self.workerThread.start()
@pyqtSlot(QImage)
def setImage(self, image):
pixmap = QPixmap.fromImage(image)
self.pixmap.setPixmap(pixmap)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = ExampleApp()
window.show()
sys.exit(app.exec_())
Update:
Попробуйте так:
main.py:
import sys
from PyQt5 import QtWidgets, QtCore, QtGui
from PyQt5.Qt import *
from coordCatch import Ui_MainWindow # !
class GraphicsScene(QtWidgets.QGraphicsScene):
clicked = pyqtSignal()
def __init__(self, parent=None):
super(GraphicsScene, self).__init__(parent)
# ??? self.xpos = None
# ??? self.ypos = None
self.selecting = False
self.setSceneRect(0, 0, 1063, 1418)
self.selection = QtWidgets.QRubberBand(QtWidgets.QRubberBand.Rectangle)
#--- self.addWidget(self.selection)
self.originQPoint = None
self.originCropPoint = None
self.currentQRect = None
self.startPos = None # +++
def mousePressEvent(self, event):
self.selecting = True
self.originQPoint = event.scenePos()
self.selection.hide()
self.originCropPoint = event.scenePos()
self.clicked.emit()
self.startPos = event.lastScreenPos() # +++
def mouseMoveEvent(self, event):
if self.originQPoint is not None and self.selecting:
lastScreenPos = event.lastScreenPos() # +++
rect = QtCore.QRect(self.startPos, lastScreenPos) # +++
# print(f'def mouseMoveEvent(self, event): rect = {rect}')
self.selection.setGeometry(rect)
self.selection.show()
def mouseReleaseEvent(self, event):
self.selecting = False
self.selection.hide()
self.currentQRect = QtCore.QRect(
self.originCropPoint.toPoint(),
event.scenePos().toPoint()
)
print(self.currentQRect) # ???
class ProcessWorker(QObject):
imageChanged = pyqtSignal(QImage)
def doWork(self):
self.image_list = [
'lena.jpg', # !!! установите свои изображения
'audience_A.png',
'audience_B.png',
'audience_C.png',
'audience_D.png',
'Ok.png',
]
f = 0
while True:
if f <= len(self.image_list) - 1:
img = QImage(self.image_list[f])
self.imageChanged.emit(img)
QThread.msleep(3500)
f += 1
else:
f = 0
img = QImage(self.image_list[f])
self.imageChanged.emit(img)
QThread.msleep(1)
class ExampleApp(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self):
super(ExampleApp, self).__init__()
self.setupUi(self)
self.resize(840, 740)
self.gscene = GraphicsScene()
self.graphicsView.setScene(self.gscene)
# ??? self.graphicsView.show()
self.graphicsView.setFixedSize(710, 610)
self.pixmap = QGraphicsPixmapItem()
self.graphicsView.scene().addItem(self.pixmap)
self.workerThread = QThread()
self.worker = ProcessWorker()
self.worker.moveToThread(self.workerThread)
self.workerThread.finished.connect(self.worker.deleteLater)
self.workerThread.started.connect(self.worker.doWork)
self.worker.imageChanged.connect(self.setImage)
self.workerThread.start()
@pyqtSlot(QImage)
def setImage(self, image):
pixmap = QPixmap.fromImage(image)
self.pixmap.setPixmap(pixmap)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = ExampleApp()
window.show()
app.exec_()
coordCatch.py:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(642, 491)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.graphicsView = QtWidgets.QGraphicsView(self.centralwidget)
self.graphicsView.setGeometry(QtCore.QRect(10, 10, 441, 331)) # 441, 331
self.graphicsView.setObjectName("graphicsView")
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
# ??? self.colorLayout = QtWidgets.QVBoxLayout()
# ??? self.nameLayout = QtWidgets.QVBoxLayout()
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))



