Qiang Zhang
Qiang Zhang

Reputation: 952

the qlabel can not trigger the mouse release event

I have a parent QLabel, and create a child QLabel to show some text. When I click on the child QLabel, the mousePressEvent on parent QLabel is OK but the mouseReleaseEvent can not be trigger. The code is:

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *

class MyLabel(QLabel):

    def __init__(self):
        super(MyLabel, self).__init__()
        self.label = QLabel('hello<br/> world', self)
        self.label.adjustSize()
        self.label.setStyleSheet(
            "background-color: {};".format(QColor(255, 0, 0).name())
        )
        self.label.move(QPoint(50, 50))
        self.label.setFrameShape(QFrame.NoFrame)

    def mousePressEvent(self, QMouseEvent):
        super(MyLabel, self).mousePressEvent(QMouseEvent)
        print('press')

    def mouseReleaseEvent(self, QMouseEvent):
        super(MyLabel, self).mouseReleaseEvent(QMouseEvent)
        print('release')

class Window(QLabel):
    def __init__(self):
        super(Window, self).__init__()
        self.layout = QVBoxLayout()
        self.setLayout(self.layout)
        self.label = MyLabel()
        self.label.setFrameShape(QFrame.Box)
        self.label.setStyleSheet("border-width: 2px;border-style: solid;border-color: rgb(0, 255, 0);")
        self.layout.addWidget(self.label)

if __name__ == "__main__":

    app = QApplication(sys.argv)
    window = Window()
    window.resize(640, 480)
    window.show()
    sys.exit(app.exec_())

I find the reason is the text in the child QLabel. If I show the text as 'hello world' rather than 'hello<.br/> world', the mouse release signal is OK when I click on the 'hello world' QLabel. So, if I need to show 'hello <.br/> world', how to fixed this bug?

Upvotes: 1

Views: 1269

Answers (2)

eyllanesc
eyllanesc

Reputation: 243897

In the case of mousePressEvent the event is passed from parent to son, and the son will not be passed if the parent accepts it, but by default the parent ignores it for what the son consumes it, but unlike mouseReleaseEvent the son consumes the event so the parent will not be notified.

If you want to better understand the concepts of mouse events, read the following article:

In this case there is another alternative that avoids disabling the widget as indicated by @Romha Korev that is to activate the flag Qt::WA_TransparentForMouseEvents:

self.label = QLabel('hello<br/> world', self)
self.label.setAttribute(Qt.WA_TransparentForMouseEvents)

This will make the widget below the QLabel receive the mouse events as if the QLabel did not exist.

Upvotes: 5

Dimitry Ernot
Dimitry Ernot

Reputation: 6584

When you press the mouse button above the hello world label, the MyLabel will broadcast the event to its children.

So the hello world label will be the final receiver. And once it will receive the press event, it will automatically the receiver for the release event.

If you want to process all the event in MyLabel, you just need to disable the label by adding self.label.setDisabled(True) in the constructor: the press event will be limited to MyLabel and it will also receive the release event.

Upvotes: 0

Related Questions