1

I am working on a project with PyQt5 which has QFrames. I am using mouse press event to trigger a function on clicking frame as below :

frame.mousePressEvent = lambda x: print_name(x, name)

Above line is not executed at the start, It is executed after user has done some work in UI.

I am getting the behaviour I want but here is the problem:

If the user clicks the frame after the above line of code is executed, it works fine but if the user clicks on the frame before the above line of the code is executed and later again clicks the frame (after code is executed), I am not getting the same behaviour. Basically nothing happens.

I want to know where is the problem and how do I solve it?

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Charlie
  • 33
  • 4

1 Answers1

2

The problem is caused because PyQt5 caches the methods so if the method is assigned then it cannot be changed. Instead of following the bad practice of assigning methods to mousePressEvent there are other better alternatives such as:

  1. Implement inheritance

    class Frame(QFrame):
        def mousePressEvent(self, event):
            super().mousePressEvent(event)
            print(event)
    
  2. Use an event filter

    class MouseObserver(QObject):
        def __init__(self, widget):
            super().__init__(widget)
            self._widget = widget
            self.widget.installEventFilter(self)
    
        @property
        def widget(self):
            return self._widget
    
        def eventFilter(self, obj, event):
            if obj is self.widget and event.type() == QEvent.MouseButtonPress:
                print(event)
            return super().eventFilter(obj, event)
    

    Then

    observer = MouseObserver(frame)
    

The second seems the most appropriate for your case.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • Can you explain what's happening in the 2nd implementation? Like step by step theoretically – Charlie Oct 20 '21 at 05:15
  • @Charlie What do not you understand? Typically I expect the OP to do some research and not just wait for a step by step tutorial which is not my style. – eyllanesc Oct 20 '21 at 05:17
  • Sorry for the earlier comment. I won't repeat it. I did the research and understood the implementation better. I had used the 1st implementation before and it seems to make every frame clickable which I don't want. My query how is the second solution different from first one. I suppose in the second as we are passing the frame as input only that frame is made clickable. I was not familiar with the events concepta in pyqt before so I had doubts. Sorry. – Charlie Oct 20 '21 at 07:56