简体   繁体   English

如何检测鼠标单击使用PySide创建的GUI中显示的图像

[英]How to detect mouse click on images displayed in GUI created using PySide

Firstly, I'm new to Python, Qt and PySide so forgive me if this question seems too simple. 首先,我是Python,Qt和PySide的新手,请原谅我,如果这个问题看起来太简单了。

What I'm trying to do is to display a bunch of photos in a grid in a GUI constructed using PySide API. 我要做的是在使用PySide API构建的GUI中的网格中显示一堆照片。 Further, when a user clicks on a photo, I want to be able to display the information corresponding to that photo. 此外,当用户点击照片时,我希望能够显示与该照片相对应的信息。 Additionally, I would like the container/widget used for displaying the photo to allow for the photo to be changed eg I should be able to replace any photo in the grid without causing the entire grid of photos to be created from scratch again. 此外,我希望用于显示照片的容器/小部件允许更改照片,例如,我应该能够替换网格中的任何照片,而不会再次从头开始创建整个网格照片。

Initially I tried to use QLabel to display a QPixmap but I realized (whether mistakenly or not) that I have no way to detect mouse clicks on the label. 最初我尝试使用QLabel来显示QPixmap,但我意识到(无论是否错误)我无法检测标签上的鼠标点击。 After some searching, I got the impression that I should subclass QLabel (or some other relevant class) and somehow override QWidget's(QLabel's parent class) mousePressEvent() to enable mouse click detection. 经过一些搜索,我得到的印象是我应该继承QLabel(或其他一些相关的类)并以某种方式覆盖QWidget(QLabel的父类)mousePressEvent()以启用鼠标点击检测。 Problem is I'm not sure how to do that or whether there is any alternative widget I can use to contain my photos other than the QLabel without having to go through subclass customization. 问题是我不知道该怎么做或者是否有任何替代小部件我可以用来包含我的照片而不是QLabel而不必经过子类定制。

Can anyone suggest a more suitable container other than QLabel to display photos while allowing me to detect mouse clicks on the photo or provide some code snippet for subclassing QLabel to enable it to detect mouse clicks? 任何人都可以建议一个比QLabel更合适的容器来显示照片,同时允许我检测照片上的鼠标点击或提供一些代码片段用于子类化QLabel以使其能够检测鼠标点击吗?

Thanks in advance for any replies. 提前感谢您的回复。

I've added an example of how to emit a signal and connect to another slot. 我添加了一个如何发出信号并连接到另一个插槽的示例。 Also the docs are very helpful 文档也非常有用

from PySide.QtCore import *
from PySide.QtGui import *

import sys


class Main(QWidget):


    def __init__(self, parent=None):
        super(Main, self).__init__(parent)

        layout  = QHBoxLayout(self)

        picture = PictureLabel("pic.png", self)
        picture.pictureClicked.connect(self.anotherSlot)

        layout.addWidget(picture)
        layout.addWidget(QLabel("click on the picture"))

    def anotherSlot(self, passed):
        print passed
        print "now I'm in Main.anotherSlot"


class PictureLabel(QLabel):

    pictureClicked = Signal(str) # can be other types (list, dict, object...)

    def __init__(self, image, parent=None):
        super(PictureLabel, self).__init__(parent)        
        self.setPixmap(image)

    def mousePressEvent(self, event):
        print "from PictureLabel.mousePressEvent"
        self.pictureClicked.emit("emit the signal")

a = QApplication([])
m = Main()
m.show()
sys.exit(a.exec_())

Even if the question has been answered, i want to provide an other way that can be used in different situations (see below) : 即使问题已经得到解答,我想提供一种可以在不同情况下使用的其他方法(见下文):

from PySide.QtCore import *
from PySide.QtGui import *

import sys

class Main(QWidget):

    def __init__(self, parent=None):
        super(Main, self).__init__(parent)

        layout  = QHBoxLayout(self)
        picture = QLabel()
        picture.setPixmap("pic.png")
        layout.addWidget(picture)
        layout.addWidget(QLabel("click on the picture"))

        makeClickable(picture)
        QObject.connect(picture, SIGNAL("clicked()"), self.anotherSlot)

    def anotherSlot(self):
        print("AnotherSlot has been called")

def makeClickable(widget):
    def SendClickSignal(widget, evnt):
        widget.emit(SIGNAL('clicked()'))
    widget.mousePressEvent = lambda evnt: SendClickSignal(widget, evnt)


a = QApplication([])
m = Main()
m.show()
sys.exit(a.exec_())

This way doesn't imply subclassing QLabel so it can be used to add logic to a widget made with QtDeigner. 这种方式并不意味着对QLabel子类化,因此它可以用于向使用QtDeigner创建的小部件添加逻辑。

Pros : 优点:

  • Can be used over QTdesigner compiled files 可以在QTdesigner编译文件上使用
  • Can be applied to any kind of widget (you might need to include a super call to the overrided function to ensure widget's normal behavior) 可以应用于任何类型的小部件(您可能需要包含对覆盖函数的super调用以确保小部件的正常行为)
  • The same logic can be used to send other signals 可以使用相同的逻辑发送其他信号

Cons : 缺点:

  • You have to use the QObject syntax to connect signals and slots 您必须使用QObject语法来连接信号和插槽

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

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