简体   繁体   中英

click event not work in pyqt5 with Qlabels

import sys
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
class memuActions(QLabel):
    clicked = pyqtSignal()
    def __init__(self,title,parent,width,height,src):
        QLabel.__init__(self, title ,parent=parent)
        self.cont=QLabel(parent)
        self.cont.resize(width,height)
        self.cont.setObjectName("cont")
        self.cont.setStyleSheet("#cont::hover{background-color:#EBEBEB;}")
        
        self.ico=QLabel(self.cont)
        self.ico.resize(self.cont.width(),40)
        self.ico.setPixmap(QPixmap(src))
        self.ico.setScaledContents(True)

        self.ds=QLabel(title,self.cont)
        self.ds.setWordWrap(True)
        self.ds.resize(self.cont.width(),25)
        self.ds.setAlignment(Qt.AlignCenter)
        self.ds.setStyleSheet("color:red;")
        self.ds.move(2,self.ico.height()+2)

    def move(self,x,y):
        self.cont.move(x,y)

    def mousePressEvent(self, event):
        self.clicked.emit()

        
class main(QMainWindow):
    def __init__(self):
        super().__init__()
        self.resize(800,600)

        af=memuActions("ASD",self,60,60,"aa.png")
        af.move(100,50)
        af.clicked.connect(self.a)


    def a(self):
        print("PL")

app=QApplication([])
win=main()
win.show()
sys.exit(app.exec_())
    


I want to define a click event for this class but no error is given and the code does not work properly.
In this class, I want to design a button that the user can click to call a function and perform a specific operation.

I want to run a method by clicking I am not fluent in English and I can not ask my question well. Thank you. Answer this question.

There are various problems with your code, with the most important being a general misunderstanding of the parent/child relation.

The memuActions instance is created with the window as parent, but self.cont is created with the same window as parent, so self.count and all its children will be child of the window, not of memuActions .

Another problem is related to the fact that you're not using layout managers , which will result in leaving the widget with the default size: all widgets created with a parent have a default size of 100x30.

Since you're creating all other widgets with the wrong parent, they are actually covering your menuActions widget, so it will never get a proper mouse click event.

If you want to create a custom widget with fixed geometries, and you don't add that widget to a layout, you must manually set its size, either by resize() or with setMinimumSize() . Since your widget is composed of many children, you must use childrenRect() to find the final size, which is a composite of all geometries of the children.

Then, the cont widget is covered by the pixmap label, it will never receive hover events. In order to avoid so, you must make the label transparent to mouse events, so that the widgets under it will receive them.

Finally, consider that Qt discourages using direct children of a main window, as you should always use a central widget :

Note: Creating a main window without a central widget is not supported. You must have a central widget even if it is just a placeholder.

You should anyway use a layout manager for that central widget, otherwise resizing the window might partially (or completely) hide its contents.

In any case, here's a corrected and working version of your code.

class memuActions(QLabel):
    clicked = pyqtSignal()
    def __init__(self, title, parent, width, height, src):
        QLabel.__init__(self, title, parent=parent)
        self.cont = QLabel(self)
        self.cont.resize(width, height)
        self.cont.setObjectName("cont")
        self.cont.setStyleSheet("#cont::hover{ background-color:#EBEBEB; }")
        
        self.ico = QLabel(self)
        self.ico.setAttribute(Qt.WA_TransparentForMouseEvents)
        self.ico.resize(width, 40)
        self.ico.setPixmap(QPixmap(src))
        self.ico.setScaledContents(True)

        self.ds = QLabel(title, self)
        self.ds.setWordWrap(True)
        self.ds.resize(width, 25)
        self.ds.setAlignment(Qt.AlignCenter)
        self.ds.setStyleSheet("color:red;")
        self.ds.move(2, self.ico.height() + 2)

        self.resize(self.childrenRect().size())

    def mousePressEvent(self, event):
        self.clicked.emit()

Note:
1. class (and constants) should always use capitalized names, so you should call your classes MemuActions and Main ;
2. please use spaces, avoiding them won't make any difference in performance or memory, and it only makes your code terrible and very annoying to read; read more about this and other very important aspects on the official Style Guide for Python Code (aka, PEP-8).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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