QGraphicsView 代理小部件上的 focusEvent

问题描述 投票:0回答:1

在 pyqt5 中,如果我有一个 QGraphicsView 小部件,并且在场景中我使用 addWidget 添加 QFrame 作为代理小部件。

有什么方法可以在 QFrame 聚焦时调用方法(例如鼠标单击)。

示例代码:

文件:run_me.py

from focus import Ui_Dialog
from PyQt5 import QtWidgets, QtCore, QtGui
from win32api import GetSystemMetrics
import sys
import time

class Run_me:
    
    def __init__(self):
        self.app = QtWidgets.QApplication(sys.argv)
        self.Dialog = QtWidgets.QDialog()
        self.ui = Ui_Dialog()
        self.ui.setupUi(self.Dialog)
        self.Dialog.showMaximized()
        
        self.max_width = int(0.9*GetSystemMetrics(0))
        self.max_height = int(0.85*GetSystemMetrics(1))
        
        self.Dialog.setFixedWidth(self.max_width)
        self.Dialog.setFixedHeight(self.max_height)
        
        self.center()
        
        self.frame = QtWidgets.QFrame()
        self.verticalLayout = QtWidgets.QVBoxLayout(self.frame)
        self.lineedit = QtWidgets.QLineEdit(self.frame)
        self.verticalLayout.addWidget(self.lineedit)


        self.scene = QtWidgets.QGraphicsScene()                    
        self.ui.graphicsView.setScene(self.scene)
        self.ui.graphicsView.setFixedHeight(self.ui.graphicsView.height())
        self.ui.graphicsView.setFixedWidth(self.ui.graphicsView.width())
        #self.ui.graphicsView.setSceneRect(0, 0, self.scene_width, self.total_height)

        self.proxy = self.scene.addWidget(self.frame)
        self.proxy.setPos(100,100)
        
        self._filter = Filter(self)
        self.frame.installEventFilter(self._filter)
        
        
        sys.exit(self.app.exec())
        
    def center(self):
        screen_width = GetSystemMetrics(0)
        screen_height = GetSystemMetrics(1)
        dw = self.app.desktop()
        taskbar_height = dw.screenGeometry().height() - dw.availableGeometry().height()
        taskbar_width = dw.screenGeometry().width() - dw.availableGeometry().width()
        if taskbar_height<100:
            available_screen_height = screen_height - taskbar_height
            available_screen_width = screen_width
        else:
            available_screen_height = screen_height
            available_screen_width = screen_width - taskbar_width
            
        qdialog_width = self.Dialog.frameSize().width()
        qdialog_height = self.Dialog.frameSize().height()
        
        x = (available_screen_width - qdialog_width) / 2
        y = (available_screen_height - qdialog_height) / 2
        width = self.Dialog.size().width()
        height = self.Dialog.size().height()
        self.Dialog.move(int(x),int(y))
        self.Dialog.setFixedWidth(width)
        self.Dialog.setFixedHeight(height)
    
    def frame_focused(self):
        print("Frame focused")

class Filter(QtCore.QObject):
    def __init__(self,main_self):
        super().__init__()
        self.main_self = main_self

        
    def eventFilter(self, widget, event):
        # FocusIn event
        if event.type() == QtCore.QEvent.FocusIn:
            self.main_self.frame_focused()
            return False
        else:
            # we don't care about other events
            return False

if __name__ == "__main__":
    program = Run_me()

文件 focus.py

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'telephone_calls.ui'
#
# Created by: PyQt5 UI code generator 5.15.9
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(599, 351)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(Dialog.sizePolicy().hasHeightForWidth())
        Dialog.setSizePolicy(sizePolicy)
        self.verticalLayout = QtWidgets.QVBoxLayout(Dialog)
        self.verticalLayout.setObjectName("verticalLayout")
        self.graphicsView = QtWidgets.QGraphicsView(Dialog)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.graphicsView.sizePolicy().hasHeightForWidth())
        self.graphicsView.setSizePolicy(sizePolicy)
        self.graphicsView.setStyleSheet("QGraphicsView#graphicsView{\n"
"    border: 1px solid #ABABAB;\n"
"    background:white;\n"
"}")
        self.graphicsView.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustIgnored)
        self.graphicsView.setObjectName("graphicsView")
        self.verticalLayout.addWidget(self.graphicsView)

        self.retranslateUi(Dialog)
        QtCore.QMetaObject.connectSlotsByName(Dialog)

    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "Στοιχεία ηχητικών κλήσεων"))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    Dialog = QtWidgets.QDialog()
    ui = Ui_Dialog()
    ui.setupUi(Dialog)
    Dialog.show()
    sys.exit(app.exec_())

python pyqt5 qgraphicsview
1个回答
0
投票

简单改变一下:

    self._filter = Filter(self)
    self.frame.installEventFilter(self._filter)

对此:

    self._filter = Filter(self)
    self.proxy.installEventFilter(self._filter)
© www.soinside.com 2019 - 2024. All rights reserved.