简体   繁体   English

PyQt5:检查是否在输入事件中按住了鼠标

[英]PyQt5: Check if mouse is held down in enter-event

My actual application is much more complicated than this, but the example below sums up the majority of my problem. 我的实际应用比这复杂得多,但是下面的示例总结了我的大部分问题。 I have multiple QLabels that I've subclassed to make them clickable. 我有多个QLabel,这些子类已被子类化以使其可单击。 The labels display 16x16 images which requires a process of loading the images via Pillow, converting them to ImageQt objects, and then setting the pixmap of the label. 标签显示16x16图像,这需要通过Pillow加载图像,将其转换为ImageQt对象,然后设置标签的像素图的过程。 In the example, I have 3 clickable QLabels that run the print_something function each time I click on them. 在示例中,我有3个可单击的QLabel,它们每次单击时都会运行print_something函数。 My goal is to be able to hold the mouse down, and for each label I hover over, the function gets called. 我的目标是能够按住鼠标,然后将鼠标悬停在每个标签上,然后调用该函数。 Any pointers would be great. 任何指针都很棒。

from PyQt5 import QtCore, QtWidgets, QtGui
from PIL import Image
from PIL.ImageQt import ImageQt
import sys


class ClickableLabel(QtWidgets.QLabel):

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

    clicked = QtCore.pyqtSignal()

    def mousePressEvent(self, ev):
        if app.mouseButtons() & QtCore.Qt.LeftButton:
            self.clicked.emit()


class MainWindow(QtWidgets.QMainWindow):

    def __init__(self):
        super().__init__()
        central_widget = QtWidgets.QWidget()

        self.setFixedSize(300, 300)
        image = Image.open("16x16image.png")
        image_imageqt = ImageQt(image)

        hbox = QtWidgets.QHBoxLayout()
        hbox.setSpacing(0)
        hbox.addStretch()

        label01 = ClickableLabel()
        label01.setPixmap(QtGui.QPixmap.fromImage(image_imageqt))
        label01.clicked.connect(self.print_something)
        hbox.addWidget(label01)

        label02 = ClickableLabel()
        label02.setPixmap(QtGui.QPixmap.fromImage(image_imageqt))
        label02.clicked.connect(self.print_something)
        hbox.addWidget(label02)

        label03 = ClickableLabel()
        label03.setPixmap(QtGui.QPixmap.fromImage(image_imageqt))
        label03.clicked.connect(self.print_something)
        hbox.addWidget(label03)

        hbox.addStretch()

        central_widget.setLayout(hbox)

        self.setCentralWidget(central_widget)

    def print_something(self):
        print("Printing something..")


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    main_window = MainWindow()
    main_window.show()
    sys.exit(app.exec_())

The cause of the problem is stated in the docs for QMouseEvent : 问题的原因在QMouseEvent的文档中进行了说明

Qt automatically grabs the mouse when a mouse button is pressed inside a widget; 当在小部件内按下鼠标按钮时,Qt会自动抓住鼠标。 the widget will continue to receive mouse events until the last mouse button is released. 小部件将继续接收鼠标事件,直到释放最后一个鼠标按钮。

It does not look like there is a simple way around this, so something hackish will be required. 似乎没有解决此问题的简单方法,因此将需要一些技巧。 One idea is to initiate a fake drag and then use dragEnterEvent instead of enterEvent . 一个想法是启动一个假的拖动,然后使用dragEnterEvent而不是enterEvent Something like this should probably work: 这样的事情可能应该起作用:

class ClickableLabel(QtWidgets.QLabel):
    clicked = QtCore.pyqtSignal()

    def __init__(self):
        super().__init__()
        self.setAcceptDrops(True)
        self.dragstart = None

    def mousePressEvent(self, event):
        if event.buttons() & QtCore.Qt.LeftButton:
            self.dragstart = event.pos()
            self.clicked.emit()

    def mouseReleaseEvent(self, event):
        self.dragstart = None

    def mouseMoveEvent(self, event):
        if (self.dragstart is not None and
            event.buttons() & QtCore.Qt.LeftButton and
            (event.pos() - self.dragstart).manhattanLength() >
             QtWidgets.qApp.startDragDistance()):
            self.dragstart = None
            drag = QtGui.QDrag(self)
            drag.setMimeData(QtCore.QMimeData())
            drag.exec_(QtCore.Qt.LinkAction)

    def dragEnterEvent(self, event):
        event.acceptProposedAction()
        if event.source() is not self:
            self.clicked.emit()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM