块信号不适用于QGraphicscene Selection已更改

2024-09-29 21:31:53 发布

您现在位置:Python中文网/ 问答频道 /正文

在我取消选择所选项目后,selectionChanged信号将触发,尽管之前调用了blockSignals(True)。您可以看到,圆将移动两次而不是一次。为什么会发生这种情况?如何防止信号触发

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *

class Template(QMainWindow):

    def __init__(self):
        super().__init__()
        self.scene = QGraphicsScene(0, 0, 200, 400)
        c = self.scene.addEllipse(8, 8, 34, 34, Qt.black, Qt.black)
        c.setPos(0, 350)
        c.setFlag(QGraphicsItem.ItemIsSelectable)
        self.scene.selectionChanged.connect(self.move)
        
        view = QGraphicsView(self.scene)
        view.setRenderHint(QPainter.Antialiasing)
        self.setCentralWidget(view)        

    def move(self):
        selected = self.scene.selectedItems()
        if selected:
            selected[0].moveBy(0, -50)
            self.scene.blockSignals(True)
            selected[0].setSelected(False)
            self.scene.blockSignals(False)

        
if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = Template()
    window.show()
    sys.exit(app.exec_())

我还要说明,我对这个具体的例子不感兴趣,有很多变通方法可以根据需要移动圆。这只是为了提供一个可视化

我对一般情况感兴趣:selectionChanged信号连接到插槽,在该函数中,您需要取消选择一个项目,而不需要再次调用插槽。


Tags: 项目fromimportselfviewtrue信号sys
1条回答
网友
1楼 · 发布于 2024-09-29 21:31:53

该问题是由鼠标引起的,因为在执行移动鼠标的逻辑后,它仍然在项目上,导致其选择生成双镜头。一个可能的解决方案是释放鼠标后取消选择

class GraphicsScene(QGraphicsScene):
    def mouseReleaseEvent(self, event):
        super().mouseReleaseEvent(event)
        for item in self.selectedItems():
            item.setSelected(False)
        self.blockSignals(False)


class Template(QMainWindow):
    def __init__(self):
        super().__init__()
        self.scene = GraphicsScene(0, 0, 200, 400, self)
        self.scene.selectionChanged.connect(self.handle_selection_changed)

        c = self.scene.addEllipse(8, 8, 34, 34, Qt.black, Qt.black)
        c.setPos(0, 350)
        c.setFlag(QGraphicsItem.ItemIsSelectable)

        view = QGraphicsView(self.scene)
        view.setRenderHint(QPainter.Antialiasing)
        self.setCentralWidget(view)

    def handle_selection_changed(self):
        self.scene.blockSignals(True)
        for item in self.scene.selectedItems():
            item.moveBy(0, -50)

相关问题 更多 >

    热门问题