gpt4 book ai didi

python - PyQt - 拖放到不同的 QLabel 小部件中

转载 作者:行者123 更新时间:2023-12-01 01:22:51 25 4
gpt4 key购买 nike

我使用的是 Windows、Python 3.6、OpenCV3 和 PyQt5。我有一个主窗口,其中有两个 QLabel 小部件(label1label2)。我想将不同的视频文件拖放到两个 QLabel 小部件中。我的脚本显示两个视频文件中每个文件的第一帧。

  • 如果我将文件通过 label1 拖动到 label2 中,然后释放鼠标,则第一个视频帧显示在 label1 中(不是我想要)。

  • 如果我将label1周围的文件拖动到label2中,然后释放鼠标,则第一个视频帧显示在 label2 中(需要效果)。

  • 如果我将文件通过 label2 拖动到 label1 中,然后释放鼠标,则第一个视频帧显示在 label1 中(需要效果)。

我希望视频显示在 label2 中,无论我是拖动文件还是穿过label1 。有建议吗?

import sys, cv2
from PyQt5.QtWidgets import QApplication, QLabel, QFrame, QMainWindow
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtCore import Qt

class Example(QMainWindow):

def __init__(self):
super().__init__()
self.initUI()

def initUI(self):

self.setGeometry(200, 300, 800, 600)
self.setAcceptDrops(True)
self.setMouseTracking(True)

self.label1 = QLabel(self)
self.label1.move(10, 10)
self.label1.resize(780, 280)
self.label1.setFrameShape(QFrame.Box)
self.label1.setAcceptDrops(True)

self.label2 = QLabel(self)
self.label2.move(10, 310)
self.label2.resize(780, 280)
self.label2.setFrameShape(QFrame.Box)
self.label2.setAcceptDrops(True)

self.label1.setText("Label 1")
self.label2.setText("Label 2")
self.show()

def dragEnterEvent(self, e):
if e.mimeData().hasUrls:
e.accept()
else:
e.ignore()

def dropEvent(self, e):
if e.mimeData().hasUrls:
e.accept()
for url in e.mimeData().urls():
if self.label1.underMouse():
fname = str(url.toLocalFile())
self.openFile1(fname)
elif self.label2.underMouse():
fname = str(url.toLocalFile())
self.openFile2(fname)
else:
e.ignore()

def openFile1(self, filename):
self.cap1 = cv2.VideoCapture(str(filename))
self.cap1.set(cv2.CAP_PROP_POS_FRAMES, 0)
width = self.cap1.get(cv2.CAP_PROP_FRAME_WIDTH)
height = self.cap1.get(cv2.CAP_PROP_FRAME_HEIGHT)
ret, frame = self.cap1.read()
if ret == True:
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
img = QImage(frame, frame.shape[1], frame.shape[0], QImage.Format_RGB888)
pix = QPixmap.fromImage(img)
pix = self.scalePix(self.label1, pix, width, height)
self.label1.setPixmap(pix)

def openFile2(self, filename):
self.cap2 = cv2.VideoCapture(str(filename))
self.cap2.set(cv2.CAP_PROP_POS_FRAMES, 0)
width = self.cap2.get(cv2.CAP_PROP_FRAME_WIDTH)
height = self.cap2.get(cv2.CAP_PROP_FRAME_HEIGHT)
ret, frame = self.cap2.read()
if ret == True:
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
img = QImage(frame, frame.shape[1], frame.shape[0], QImage.Format_RGB888)
pix = QPixmap.fromImage(img)
pix = self.scalePix(self.label1, pix, width, height)
self.label2.setPixmap(pix)

def scalePix(self, label, p, width, height):
window_width = label.width()
ratio = height / width
window_height = int(ratio * window_width)
window_height = label.height()
window_width = int(1 / ratio * window_height)
p = p.scaledToWidth(window_width, Qt.SmoothTransformation)
p = p.scaledToHeight(window_height, Qt.SmoothTransformation)
return p

if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())

最佳答案

文档表明 underMouse()拖放过程中可能会失败:

bool QWidget::underMouse() const

Returns true if the widget is under the mouse cursor; otherwise returns false.

This value is not updated properly during drag and drop operations.

所以最好不要使用,相反我们可以创建一个自定义的QLabel来实现拖放:

import sys, cv2
from PyQt5 import QtCore, QtGui, QtWidgets

class OpenCVLabel(QtWidgets.QLabel):
def __init__(self, *args, **kwargs):
super(OpenCVLabel, self).__init__(*args, **kwargs)
self.setFrameShape(QtWidgets.QFrame.Box)
self.setAcceptDrops(True)

def dragEnterEvent(self, e):
if e.mimeData().hasUrls():
e.accept()
else:
e.ignore()

def dropEvent(self, e):
if e.mimeData().hasUrls():
e.accept()
for url in e.mimeData().urls():
self.openFile(url.toLocalFile())
else:
e.ignore()

def openFile(self, filename):
cap = cv2.VideoCapture(str(filename))
cap.set(cv2.CAP_PROP_POS_FRAMES, 0)
width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
ret, frame = cap.read()
if ret:
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
img = QtGui.QImage(frame, frame.shape[1], frame.shape[0], QtGui.QImage.Format_RGB888)
pix = QtGui.QPixmap.fromImage(img)
pix = pix.scaled(self.size(), QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation)
self.setPixmap(pix)

class Example(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.initUI()

def initUI(self):
label1 = OpenCVLabel("label1")
label2 = OpenCVLabel("label2")
central_widget = QtWidgets.QWidget()
self.setCentralWidget(central_widget)
lay = QtWidgets.QVBoxLayout(central_widget)
lay.addWidget(label1)
lay.addWidget(label2)
self.resize(780, 560)

if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())

关于python - PyQt - 拖放到不同的 QLabel 小部件中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53639933/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com