clicked signals around a QLabel

43 views
Skip to first unread message

likage

unread,
Dec 6, 2018, 2:59:27 PM12/6/18
to Python Programming for Autodesk Maya
Hi all,

I am trying to create a 'clicked' signal where it will only be triggered if User clicks anywhere within the icon.
In the following code:

class TestWin(QtGui.QWidget):
    def __init__(self, parent=None):
        super(TestWin, self).__init__(parent)
        self.init_ui()
    
    def init_ui(self):
        
        lyt = QtGui.QVBoxLayout()
        btn = QtGui.QPushButton('test button')
        
        lbl = QtGui.QLabel()
        icon_path = '/Desktop/people.png'
        lbl.setPixmap(icon_path)       
        
        lyt.addWidget(btn)
        lyt.addWidget(lbl)
        
        self.setLayout(lyt)
        
        # Signals
        btn.clicked.connect(self.btn_click)
        lbl.mousePressEvent = self.lbl_click
    
    def btn_click(self):
        print 'I am clicking on the button...'
    
    def lbl_click(self, event):
        print 'I am clicking on the label...'


my_win = TestWin()
my_win.show()

As soon as I resize the window bigger, clicking on any blank space will still prints the message 'I am clicking on the label'

I also tried using event filtering where as follows:

class TestWin(QtGui.QWidget):
    def __init__(self, parent=None):
        super(TestWin, self).__init__(parent)
        self.init_ui()
    
    def init_ui(self):
        ...
        ...
        
        # Signals
        btn.clicked.connect(self.btn_click)
        lbl.installEventFilter(self)
    
    def btn_click(self):
        ...
    
    def eventFilter(self, source, event):
        if event.type() == QtCore.QEvent.MouseButtonPress:
            print "The sender is:", source.text() # Returns me blank
        return super(TestWin, self).eventFilter(source, event)

but the `source.text()` is returning me nothing.

Any insights are appreciated!


Justin Israel

unread,
Dec 6, 2018, 4:00:57 PM12/6/18
to python_in...@googlegroups.com
This is caused by the fact that the event handling is on the QLabel and even though you think you are clicking on blank space, its just the part of the QLabel where the image no longer covers. You have the QLabel inside of a layout, which means it will expand when you resize the parent widget. So you have a couple options here. 

1) You can set label.setScaledContents(True) and have the icon resize to always fit the QLabel,

2) You can set the QLabel to not resize. This is done by calling label.setSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
It also means you will have gap between the button and image, so you could also call layout.addStretch() after adding them, to keep them pinned to the top.

Justin


--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/4913a8b5-eb22-4ffd-a3d2-268dc029ab8c%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

likage

unread,
Dec 6, 2018, 5:32:16 PM12/6/18
to Python Programming for Autodesk Maya
Hi Justin,

Thank you for getting back. I had thought using the above example may help me out but turns out not. :(
And so, I have decided to paste the code here in hopes of some guidance/ insights if any...


example_widget.jpg

The above 2 codes are used to created a widget (see attached) where I am trying to induce a 'clicked' connection towards that play icon.

And it appears that I am unable to use either QPushButton or a QLabel to replace it, by doing so, it will cause an error.



Justin Israel

unread,
Dec 6, 2018, 9:29:49 PM12/6/18
to python_in...@googlegroups.com
Well you can't put a normal QWidget into a QGraphicsScene unless you wrap it in a QGraphicsProxyWidget. But if you start doing this a lot then you are going to start reducing your performance back towards a normal QWidget setup. It would be better to just implement your own clickable icon item with a QGraphicsPixmapItem

Best to avoid QWidget as much as possible if you are in a QGraphicsScene. Usually they are only used in proxies when you really need to integrate existing widgets.

Justin


--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.

likage

unread,
Dec 7, 2018, 2:24:27 PM12/7/18
to Python Programming for Autodesk Maya
I am slightly confused now...
I apologize in advance, not an excuse but this is my first time dealing with QGraphicsXXX and have it integrated with the 'normal' widgets..

In the BaseWidget script - filled_round_rect(), it appears that the icon creation is made there and so I added this part in:

def filled_round_rect():
   ...
   ...
   painter.fillPath(rounded_rect, colour)

    # I added the following line
   self.pixmapItem = QtGui.QGraphicsPixmapItem(self.type_icon())

    if self.ICON:
       top_right = self.boundingRect().topRight()
       painter.drawPixmap(
           top_right.x() - 35,
           top_right.y() + 5,
           self.pixmapItem # I replace this with self.type_icon()
       )


and got the following error... I had thought that it will work, as the BaseWidget is within QGraphicsScene?

# TypeError: # 'PySide2.QtGui.QPainter.drawPixmap' called with wrong argument types:
#   PySide2.QtGui.QPainter.drawPixmap(float, float, PySide2.QtWidgets.QGraphicsPixmapItem)
# Supported signatures:
#   PySide2.QtGui.QPainter.drawPixmap(PySide2.QtCore.QPoint, PySide2.QtGui.QPixmap)
#   PySide2.QtGui.QPainter.drawPixmap(PySide2.QtCore.QPoint, PySide2.QtGui.QPixmap, PySide2.QtCore.QRect)
#   PySide2.QtGui.QPainter.drawPixmap(PySide2.QtCore.QPointF, PySide2.QtGui.QPixmap)
#   PySide2.QtGui.QPainter.drawPixmap(PySide2.QtCore.QPointF, PySide2.QtGui.QPixmap, PySide2.QtCore.QRectF)
#   PySide2.QtGui.QPainter.drawPixmap(PySide2.QtCore.QRect, PySide2.QtGui.QPixmap)
#   PySide2.QtGui.QPainter.drawPixmap(PySide2.QtCore.QRect, PySide2.QtGui.QPixmap, PySide2.QtCore.QRect)
#   PySide2.QtGui.QPainter.drawPixmap(PySide2.QtCore.QRectF, PySide2.QtGui.QPixmap, PySide2.QtCore.QRectF)
#   PySide2.QtGui.QPainter.drawPixmap(int, int, PySide2.QtGui.QPixmap)
#   PySide2.QtGui.QPainter.drawPixmap(int, int, PySide2.QtGui.QPixmap, int, int, int, int)
#   PySide2.QtGui.QPainter.drawPixmap(int, int, int, int, PySide2.QtGui.QPixmap)
#  PySide2.QtGui.QPainter.drawPixmap(int, int, int, int, PySide2.QtGui.QPixmap, int, int, int, int)


Justin Israel

unread,
Dec 7, 2018, 2:50:22 PM12/7/18
to python_in...@googlegroups.com
Sorry, I had misunderstood part of your previous question based on your original example of wanting to do a clickable icon with a Qlabel or Qpushbutton. And I thought you were trying to integrate QWidget into QGraphicsScene. It is still true that you should avoid them as much as possible and do all drawing through QGraphicsItem classes. 

Your current error is exactly what the exception says. You can't pass a QGraphics item to the QPainter draw like that. You don't even need a custom draw call if you are using a QGraphicsPixmapItem for your icon. Just add it as a child to your item and position it where it needs to go. It will draw itself and also give you the mouse press handler for its bounds. 
Otherwise if you continue drawing your own pixmap (which is fine) then you have to handle the mouse press in that main item and test if it hits the bounds for the icon you drew. I find it's a bit easier if the items are just composed and encapsulate their own event handling. Just think of parent-child composition with QGraphicsItems

Hope that makes sense. 



--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.

likage

unread,
Dec 18, 2018, 9:12:59 PM12/18/18
to Python Programming for Autodesk Maya
Hi Justin,

jumping back onto this thread... So, I managed to get a QPushButton, converted into a QGraphicsProxyWidget, and have it implemented into a horizontal QGraphicsLinearLayout together with the title.

But, currently I have an issue where this horizontal layout though is being added into a vertical QGraphicsLinearLayout, the button got 'pushed' out as I was using `insertStretch` on the title.
Wondering if you know of any ways in which I can either force a width limit, or set the button to a fixed postion?

Justin Israel

unread,
Dec 18, 2018, 9:36:57 PM12/18/18
to python_in...@googlegroups.com
If you want to give me a small code example that I can see, I would be happy to make suggestions. 
 

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages