简体   繁体   English

单击事件在带有 Qlabels 的 pyqt5 中不起作用

[英]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.我想为此 class 定义一个点击事件,但没有给出错误并且代码无法正常工作。
In this class, I want to design a button that the user can click to call a function and perform a specific operation.在这个 class 中,我想设计一个按钮,用户可以单击该按钮来调用 function 并执行特定操作。

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 . memuActions实例是使用 window 作为父级创建的,但self.cont是使用相同的 window 作为父级创建的,因此self.count及其所有子级将是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.另一个问题与您没有使用布局管理器这一事实有关,这将导致小部件保留默认大小:使用父级创建的所有小部件的默认大小为 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.由于您使用错误的父级创建所有其他小部件,它们实际上覆盖了您的menuActions小部件,因此它永远不会获得正确的鼠标单击事件。

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() .如果要创建具有固定几何形状的自定义小部件,并且不将该小部件添加到布局中,则必须通过resize()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.由于您的小部件由许多孩子组成,因此您必须使用childrenRect()来找到最终大小,这是孩子的所有几何形状的组合。

Then, the cont widget is covered by the pixmap label, it will never receive hover events.然后, cont小部件被像素图 label 覆盖,它永远不会收到 hover 事件。 In order to avoid so, you must make the label transparent to mouse events, so that the widgets under it will receive them.为了避免这种情况,您必须使 label 对鼠标事件透明,以便其的小部件能够接收它们。

Finally, consider that Qt discourages using direct children of a main window, as you should always use a central widget :最后,考虑到 Qt 不鼓励使用主 window 的直接子级,因为您应该始终使用中央小部件

Note: Creating a main window without a central widget is not supported.注意:不支持创建没有中央小部件的主 window。 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.无论如何,您应该为该中央小部件使用布局管理器,否则调整 window 的大小可能会部分(或完全)隐藏其内容。

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 ; 1. class(和常量)应始终使用大写名称,因此您应该调用您的类MemuActionsMain
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; 2.请使用空格,避免它们不会对性能或memory产生任何影响,它只会让你的代码变得糟糕而且阅读起来很烦人; read more about this and other very important aspects on the official Style Guide for Python Code (aka, PEP-8).Python 代码(又名 PEP-8)的官方样式指南中阅读有关此方面和其他非常重要方面的更多信息。

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

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