同时在多个小部件中跟踪鼠标移动 [英] Track mouse movements in several widgets at the same time

查看:46
本文介绍了同时在多个小部件中跟踪鼠标移动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想跟踪鼠标移动以进行计算(进度值条)而鼠标用于绘制其中之一两个QGraphicsView.使用下面的代码,您可以在 QGraphicsView 中绘制 gridLayout 上的鼠标移动坐标,但不能同时进行.这怎么办?

<小时>

main.py

导入系统从 PyQt5.QtCore 导入 Qt从 PyQt5.QtGui 导入 QCursor、QPainterPath、QPen从 PyQt5.QtWidgets 导入 QApplication、QMainWindow、QGraphicsView、QGraphicsScene、QGraphicsPathItem从 PyQt5.uic 导入 loadUi应用程序 = 无类 MainWindow(QMainWindow):def __init__(self, parent=None):super().__init__(parent)loadUi("mainwindow.ui", self)self.showMaximized()self.setMouseTracking(True)self.centralWidget().setAttribute(Qt.WA_MouseTracking)self._old_x = QCursor.pos().x()self._old_y = QCursor.pos().y()self.verticalLayout_top.addWidget(GraphicsView())self.verticalLayout_bottom.addWidget(GraphicsView())@静态方法def _update_bar(progress_bar, delta):current_value = progress_bar.value()new_value = current_value + deltaprogress_bar.setValue(new_value)def mouseMoveEvent(self, event):new_x = event.x()new_y = event.y()如果 new_x >self._old_x:self._update_bar(self.progressBar_x_plus, new_x - self._old_x)如果 new_x self._old_y:self._update_bar(self.progressBar_y_plus, new_y - self._old_y)如果 new_y 

<小时>

mainwindow.ui

<string>X+</string></属性><属性名称=对齐"><set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set></属性></小部件></项目><item row="0" column="1"><widget class="QProgressBar" name="progressBar_x_plus"><属性名称=最大值"><number>1000</number></属性><属性名称=值"><数字>0</数字></属性></小部件></项目><item row="1" column="0"><widget class="QLabel" name="label_x_minus"><属性名称=文本"><string>X-</string></属性><属性名称=对齐"><set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set></属性></小部件></项目><item row="1" column="1"><widget class="QProgressBar" name="progressBar_x_minus"><属性名称=最大值"><number>1000</number></属性><属性名称=值"><数字>0</数字></属性></小部件></项目><item row="2" column="0"><widget class="QLabel" name="label_y_plus"><属性名称=文本"><string>Y+</string></属性><属性名称=对齐"><set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set></属性></小部件></项目><item row="2" column="1"><widget class="QProgressBar" name="progressBar_y_plus"><属性名称=最大值"><number>1000</number></属性><属性名称=值"><数字>0</数字></属性></小部件></项目><item row="3" column="0"><widget class="QLabel" name="label_y_minus"><属性名称=文本"><string>Y-</string></属性><属性名称=对齐"><set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set></属性></小部件></项目><item row="3" column="1"><widget class="QProgressBar" name="progressBar_y_minus"><属性名称=最大值"><number>1000</number></属性><属性名称=值"><数字>0</数字></属性></小部件></项目></布局></项目><item row="2" column="0"><layout class="QVBoxLayout" name="verticalLayout_bottom"/></项目></布局></小部件><widget class="QMenuBar" name="menubar"><属性名称=几何"><rect><x>0</x><y>0</y><宽度>1003</宽度><高度>24</高度></rect></属性></小部件><widget class="QStatusBar" name="statusbar"/></小部件><资源/><连接/></ui>

<小时>

更新 1:尝试在整个窗口中跟踪鼠标移动:

class MainWindow(QMainWindow):def __init__(self, parent=None):super().__init__(parent)loadUi("mainwindow.ui", self)self.showMaximized()self.global_pos = QCursor.pos()用于放置(self.verticalLayout_top,self.verticalLayout_bottom):视图 = GraphicsView()listener = MouseListener(view.viewport())listener.posChanged.connect(self.on_pos_changed)Lay.addWidget(查看)window_listener = MouseListener(self)window_listener.posChanged.connect(self.on_pos_changed)

<小时>

更新 2

导入系统从 PyQt5.QtCore 导入 Qt、QObject、pyqtSignal、QPoint、QEvent从 PyQt5.QtGui 导入 QCursor、QPainterPath、QPen从 PyQt5.QtWidgets 导入 QApplication、QMainWindow、QGraphicsView、QGraphicsScene、QGraphicsPathItem、QWidget从 PyQt5.uic 导入 loadUi应用程序 = 无类鼠标监听器(QObject):posChanged = pyqtSignal(QPoint)def __init__(self, widget):super().__init__(小部件)self._widget = 小部件self._childrens = []self._setup_widget(self._widget)对于 self._widget.findChildren(QWidget) 中的 w:self._setup_widget(w)self._childrens.append(w)def _setup_widget(self, w):w.installEventFilter(self)w.setMouseTracking(True)def eventFilter(self, obj, event):# if obj in [self._widget] + self._childrens and event.type() == QEvent.MouseMove:如果 event.type() == QEvent.MouseMove:self.posChanged.emit(event.globalPos())如果 event.type() == QEvent.ChildAdded:obj = event.child()如果 obj.isWidgetType():self._setup_widget(obj)self._childrens.append(obj)如果 event.type() == QEvent.ChildRemoved:c = event.child()如果 c 在 self._childrens 中:c.removeEventFilter(self)self._childrens.remove(c)返回 super().eventFilter(obj, event)类 MainWindow(QMainWindow):def __init__(self, parent=None):super().__init__(parent)loadUi("mainwindow.ui", self)self.showMaximized()self.global_pos = QCursor.pos()用于放置(self.verticalLayout_top,self.verticalLayout_bottom):视图 = GraphicsView()listener = MouseListener(view.viewport())listener.posChanged.connect(self.on_pos_changed)Lay.addWidget(查看)# window_listener = MouseListener(self)# window_listener.posChanged.connect(self.on_pos_changed)@静态方法def _update_bar(progress_bar, delta):current_value = progress_bar.value()new_value = current_value + deltaprogress_bar.setValue(new_value)def on_pos_changed(self, pos):new_x = pos.x()new_y = pos.y()old_x = self.global_pos.x()old_y = self.global_pos.y()如果 new_x >旧_x:self._update_bar(self.progressBar_x_plus, new_x - old_x)如果 new_x <旧_x:self._update_bar(self.progressBar_x_minus, old_x - new_x)如果 new_y >old_y:self._update_bar(self.progressBar_y_plus, new_y - old_y)如果 new_y 

解决方案

问题在于 mousePressEvent 不一定从父小部件传播到子小部件(该行为取决于每种类型的小部件,例如 QLabel 如果它传播鼠标事件),此外,如果您想侦听其他小部件的事件,则覆盖 mouseMoveEvent 方法的策略是有限的.

考虑到上述情况,一个可能的解决方案是使用 eventFilter 来监听任何小部件的事件,另一个改进是使用全局位置而不是本地位置,这样当鼠标从 QGraphicsView 变化时不受影响由本地坐标系.

class MouseListener(QObject):posChanged = pyqtSignal(QPoint)def __init__(self, widget):super().__init__(小部件)self._widget = 小部件self._widget.setMouseTracking(True)self._widget.installEventFilter(self)def eventFilter(self, obj, event):如果 obj 是 self._widget 和 event.type() == QEvent.MouseMove:self.posChanged.emit(event.globalPos())返回 super().eventFilter(obj, event)类 MainWindow(QMainWindow):def __init__(self, parent=None):super().__init__(parent)loadUi("mainwindow.ui", self)self.showMaximized()self.global_pos = QCursor.pos()用于放置(self.verticalLayout_top,self.verticalLayout_bottom):视图 = GraphicsView()listener = MouseListener(view.viewport())listener.posChanged.connect(self.on_pos_changed)Lay.addWidget(查看)@静态方法def _update_bar(progress_bar, delta):current_value = progress_bar.value()new_value = current_value + deltaprogress_bar.setValue(new_value)def on_pos_changed(self, pos):new_x = pos.x()new_y = pos.y()old_x = self.global_pos.x()old_y = self.global_pos.y()如果 new_x >旧_x:self._update_bar(self.progressBar_x_plus, new_x - old_x)如果 new_x <旧_x:self._update_bar(self.progressBar_x_minus, old_x - new_x)如果 new_y >old_y:self._update_bar(self.progressBar_y_plus, new_y - old_y)如果 new_y 

更新:

class GraphicsView(QGraphicsView):def __init__(self):super().__init__()# ...def mousePressEvent(self, event):if event.buttons() &Qt.LeftButton:self.start = self.mapToScene(event.pos())self.path.moveTo(self.start)super().mousePressEvent(事件)def mouseMoveEvent(self, event):if event.buttons() &Qt.LeftButton:self.end = self.mapToScene(event.pos())self.path.lineTo(self.end)self.start = self.endself.item.setPath(self.path)super().mouseMoveEvent(事件)

更新:

在这种情况下,您不仅必须将 eventFilter 应用于 QGraphicsView 的视口,还必须应用于窗口的所有子项.

class MouseListener(QObject):posChanged = pyqtSignal(QPoint)def __init__(self, widget):super().__init__(小部件)self._widget = 小部件self._childrens = []self._setup_widget(self._widget)对于 self._widget.findChildren(QWidget) 中的 w:self._setup_widget(w)self._childrens.append(w)def _setup_widget(self, w):w.installEventFilter(self)w.setMouseTracking(True)def eventFilter(self, obj, event):如果 obj 在 [self._widget] + self._childrens 和 event.type() == QEvent.MouseMove:self.posChanged.emit(event.globalPos())如果 event.type() == QEvent.ChildAdded:obj = event.child()如果 obj.isWidgetType():self._setup_widget(obj)self._childrens.append(obj)如果 event.type() == QEvent.ChildRemoved:c = event.child()如果 c 在 self._childrens 中:c.removeEventFilter(self)self._childrens.remove(c)返回 super().eventFilter(obj, event)类 MainWindow(QMainWindow):def __init__(self, parent=None):super().__init__(parent)loadUi("mainwindow.ui", self)self.showMaximized()self.global_pos = QCursor.pos()侦听器 = 鼠标侦听器(自我)listener.posChanged.connect(self.on_pos_changed)用于放置(self.verticalLayout_top,self.verticalLayout_bottom):视图 = GraphicsView()Lay.addWidget(查看)# ...

I would like to track the mouse movement for calculation (of values for progress bars) while the mouse is used to draw in one of the two QGraphicsView. With the code below you can draw either in a QGraphicsView or get the coordinates of mouse movements over the gridLayout, but not both at once. How can this be done?


main.py

import sys
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QCursor, QPainterPath, QPen
from PyQt5.QtWidgets import QApplication, QMainWindow, QGraphicsView, QGraphicsScene, QGraphicsPathItem
from PyQt5.uic import loadUi

app = None


class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        loadUi("mainwindow.ui", self)
        self.showMaximized()
        self.setMouseTracking(True)
        self.centralWidget().setAttribute(Qt.WA_MouseTracking)

        self._old_x = QCursor.pos().x()
        self._old_y = QCursor.pos().y()

        self.verticalLayout_top.addWidget(GraphicsView())
        self.verticalLayout_bottom.addWidget(GraphicsView())

    @staticmethod
    def _update_bar(progress_bar, delta):
        current_value = progress_bar.value()
        new_value = current_value + delta
        progress_bar.setValue(new_value)

    def mouseMoveEvent(self, event):
        new_x = event.x()
        new_y = event.y()

        if new_x > self._old_x:
            self._update_bar(self.progressBar_x_plus, new_x - self._old_x)
        if new_x < self._old_x:
            self._update_bar(self.progressBar_x_minus, self._old_x - new_x)

        if new_y > self._old_y:
            self._update_bar(self.progressBar_y_plus, new_y - self._old_y)
        if new_y < self._old_y:
            self._update_bar(self.progressBar_y_minus, self._old_y - new_y)

        self._old_x = new_x
        self._old_y = new_y


class GraphicsView(QGraphicsView):
    def __init__(self):
        super().__init__()
        self.start = None
        self.end = None

        self.setScene(QGraphicsScene())
        self.path = QPainterPath()
        self.item = GraphicsPathItem()
        self.scene().addItem(self.item)

        self.contents_rect = self.contentsRect()
        self.setSceneRect(0, 0, self.contents_rect.width(), self.contents_rect.height())
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

    def mousePressEvent(self, event):
        self.start = self.mapToScene(event.pos())
        self.path.moveTo(self.start)

    def mouseMoveEvent(self, event):
        self.end = self.mapToScene(event.pos())
        self.path.lineTo(self.end)
        self.start = self.end
        self.item.setPath(self.path)


class GraphicsPathItem(QGraphicsPathItem):
    def __init__(self):
        super().__init__()
        pen = QPen()
        pen.setColor(Qt.black)
        pen.setWidth(5)
        self.setPen(pen)


def main():
    global app
    app = QApplication(sys.argv)
    main_window = MainWindow()
    main_window.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()


mainwindow.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>1003</width>
    <height>703</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Mouse Pointer</string>
  </property>
  <property name="locale">
   <locale language="English" country="UnitedKingdom"/>
  </property>
  <widget class="QWidget" name="centralwidget">
   <layout class="QGridLayout" name="gridLayout_2">
    <item row="0" column="0">
     <layout class="QVBoxLayout" name="verticalLayout_top"/>
    </item>
    <item row="1" column="0">
     <layout class="QGridLayout" name="gridLayout">
      <item row="0" column="0">
       <widget class="QLabel" name="label_x_plus">
        <property name="text">
         <string>X+</string>
        </property>
        <property name="alignment">
         <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
        </property>
       </widget>
      </item>
      <item row="0" column="1">
       <widget class="QProgressBar" name="progressBar_x_plus">
        <property name="maximum">
         <number>1000</number>
        </property>
        <property name="value">
         <number>0</number>
        </property>
       </widget>
      </item>
      <item row="1" column="0">
       <widget class="QLabel" name="label_x_minus">
        <property name="text">
         <string>X-</string>
        </property>
        <property name="alignment">
         <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
        </property>
       </widget>
      </item>
      <item row="1" column="1">
       <widget class="QProgressBar" name="progressBar_x_minus">
        <property name="maximum">
         <number>1000</number>
        </property>
        <property name="value">
         <number>0</number>
        </property>
       </widget>
      </item>
      <item row="2" column="0">
       <widget class="QLabel" name="label_y_plus">
        <property name="text">
         <string>Y+</string>
        </property>
        <property name="alignment">
         <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
        </property>
       </widget>
      </item>
      <item row="2" column="1">
       <widget class="QProgressBar" name="progressBar_y_plus">
        <property name="maximum">
         <number>1000</number>
        </property>
        <property name="value">
         <number>0</number>
        </property>
       </widget>
      </item>
      <item row="3" column="0">
       <widget class="QLabel" name="label_y_minus">
        <property name="text">
         <string>Y-</string>
        </property>
        <property name="alignment">
         <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
        </property>
       </widget>
      </item>
      <item row="3" column="1">
       <widget class="QProgressBar" name="progressBar_y_minus">
        <property name="maximum">
         <number>1000</number>
        </property>
        <property name="value">
         <number>0</number>
        </property>
       </widget>
      </item>
     </layout>
    </item>
    <item row="2" column="0">
     <layout class="QVBoxLayout" name="verticalLayout_bottom"/>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>1003</width>
     <height>24</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>


Update 1: Attempt to track mouse movements over the entire window:

class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        loadUi("mainwindow.ui", self)
        self.showMaximized()
        self.global_pos = QCursor.pos()

        for lay in (self.verticalLayout_top, self.verticalLayout_bottom):
            view = GraphicsView()
            listener = MouseListener(view.viewport())
            listener.posChanged.connect(self.on_pos_changed)
            lay.addWidget(view)

        window_listener = MouseListener(self)
        window_listener.posChanged.connect(self.on_pos_changed)


Update 2

import sys
from PyQt5.QtCore import Qt, QObject, pyqtSignal, QPoint, QEvent
from PyQt5.QtGui import QCursor, QPainterPath, QPen
from PyQt5.QtWidgets import QApplication, QMainWindow, QGraphicsView, QGraphicsScene, QGraphicsPathItem, QWidget
from PyQt5.uic import loadUi

app = None


class MouseListener(QObject):
    posChanged = pyqtSignal(QPoint)

    def __init__(self, widget):
        super().__init__(widget)
        self._widget = widget
        self._childrens = []

        self._setup_widget(self._widget)

        for w in self._widget.findChildren(QWidget):
            self._setup_widget(w)
            self._childrens.append(w)

    def _setup_widget(self, w):
        w.installEventFilter(self)
        w.setMouseTracking(True)

    def eventFilter(self, obj, event):
        # if obj in [self._widget] + self._childrens and event.type() == QEvent.MouseMove:
        if event.type() == QEvent.MouseMove:
            self.posChanged.emit(event.globalPos())

        if event.type() == QEvent.ChildAdded:
            obj = event.child()
            if obj.isWidgetType():
                self._setup_widget(obj)
                self._childrens.append(obj)

        if event.type() == QEvent.ChildRemoved:
            c = event.child()
            if c in self._childrens:
                c.removeEventFilter(self)
                self._childrens.remove(c)
        return super().eventFilter(obj, event)


class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        loadUi("mainwindow.ui", self)
        self.showMaximized()
        self.global_pos = QCursor.pos()

        for lay in (self.verticalLayout_top, self.verticalLayout_bottom):
            view = GraphicsView()
            listener = MouseListener(view.viewport())
            listener.posChanged.connect(self.on_pos_changed)
            lay.addWidget(view)

        # window_listener = MouseListener(self)
        # window_listener.posChanged.connect(self.on_pos_changed)

    @staticmethod
    def _update_bar(progress_bar, delta):
        current_value = progress_bar.value()
        new_value = current_value + delta
        progress_bar.setValue(new_value)

    def on_pos_changed(self, pos):
        new_x = pos.x()
        new_y = pos.y()
        old_x = self.global_pos.x()
        old_y = self.global_pos.y()
        if new_x > old_x:
            self._update_bar(self.progressBar_x_plus, new_x - old_x)
        if new_x < old_x:
            self._update_bar(self.progressBar_x_minus, old_x - new_x)
        if new_y > old_y:
            self._update_bar(self.progressBar_y_plus, new_y - old_y)
        if new_y < old_y:
            self._update_bar(self.progressBar_y_minus, old_y - new_y)
        self.global_pos = pos


class GraphicsView(QGraphicsView):
    def __init__(self):
        super().__init__()
        self.start = None
        self.end = None

        self.setScene(QGraphicsScene())
        self.path = QPainterPath()
        self.item = GraphicsPathItem()
        self.scene().addItem(self.item)

        self.contents_rect = self.contentsRect()
        self.setSceneRect(0, 0, self.contents_rect.width(), self.contents_rect.height())
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

    def mousePressEvent(self, event):
        if event.buttons() & Qt.LeftButton:
            self.start = self.mapToScene(event.pos())
            self.path.moveTo(self.start)
        # super().mousePressEvent(event)

    def mouseMoveEvent(self, event):
        if event.buttons() & Qt.LeftButton:
            self.end = self.mapToScene(event.pos())
            self.path.lineTo(self.end)
            self.start = self.end
            self.item.setPath(self.path)
        # super().mouseMoveEvent(event)


class GraphicsPathItem(QGraphicsPathItem):
    def __init__(self):
        super().__init__()
        pen = QPen()
        pen.setColor(Qt.black)
        pen.setWidth(5)
        self.setPen(pen)


def main():
    global app
    app = QApplication(sys.argv)
    main_window = MainWindow()
    main_window.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()

解决方案

The problem is that the mousePressEvent does not necessarily propagate from the parent widget to the child widget (that behavior depends on each type of widget, for example QLabel if it propagates the mouse events), in addition to your strategy of overriding the mouseMoveEvent method is limited if you want Listen to the events of other widgets.

Considering the above, a possible solution is to use an eventFilter to listen to the events of any widget, and another improvement is to use the global position instead of the local one so that when the mouse changes from QGraphicsView it is not affected by the local coordinate system.

class MouseListener(QObject):
    posChanged = pyqtSignal(QPoint)

    def __init__(self, widget):
        super().__init__(widget)
        self._widget = widget
        self._widget.setMouseTracking(True)
        self._widget.installEventFilter(self)

    def eventFilter(self, obj, event):
        if obj is self._widget and event.type() == QEvent.MouseMove:
            self.posChanged.emit(event.globalPos())
        return super().eventFilter(obj, event)


class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        loadUi("mainwindow.ui", self)
        self.showMaximized()
        self.global_pos = QCursor.pos()
        for lay in (self.verticalLayout_top, self.verticalLayout_bottom):
            view = GraphicsView()
            listener = MouseListener(view.viewport())
            listener.posChanged.connect(self.on_pos_changed)
            lay.addWidget(view)

    @staticmethod
    def _update_bar(progress_bar, delta):
        current_value = progress_bar.value()
        new_value = current_value + delta
        progress_bar.setValue(new_value)

    def on_pos_changed(self, pos):
        new_x = pos.x()
        new_y = pos.y()
        old_x = self.global_pos.x()
        old_y = self.global_pos.y()
        if new_x > old_x:
            self._update_bar(self.progressBar_x_plus, new_x - old_x)
        if new_x < old_x:
            self._update_bar(self.progressBar_x_minus, old_x - new_x)
        if new_y > old_y:
            self._update_bar(self.progressBar_y_plus, new_y - old_y)
        if new_y < old_y:
            self._update_bar(self.progressBar_y_minus, old_y - new_y)
        self.global_pos = pos

Update:

class GraphicsView(QGraphicsView):
    def __init__(self):
        super().__init__()
        # ...

    def mousePressEvent(self, event):
        if event.buttons() & Qt.LeftButton:
            self.start = self.mapToScene(event.pos())
            self.path.moveTo(self.start)
        super().mousePressEvent(event)

    def mouseMoveEvent(self, event):
        if event.buttons() & Qt.LeftButton:
            self.end = self.mapToScene(event.pos())
            self.path.lineTo(self.end)
            self.start = self.end
            self.item.setPath(self.path)
        super().mouseMoveEvent(event)

Update:

In this case you must apply the eventFilter not only to the viewport of the QGraphicsView but to all the children of the window.

class MouseListener(QObject):
    posChanged = pyqtSignal(QPoint)

    def __init__(self, widget):
        super().__init__(widget)
        self._widget = widget
        self._childrens = []

        self._setup_widget(self._widget)

        for w in self._widget.findChildren(QWidget):
            self._setup_widget(w)
            self._childrens.append(w)

    def _setup_widget(self, w):
        w.installEventFilter(self)
        w.setMouseTracking(True)

    def eventFilter(self, obj, event):
        if obj in [self._widget] + self._childrens and event.type() == QEvent.MouseMove:
            self.posChanged.emit(event.globalPos())

        if event.type() == QEvent.ChildAdded:
            obj = event.child()
            if obj.isWidgetType():
                self._setup_widget(obj)
                self._childrens.append(obj)

        if event.type() == QEvent.ChildRemoved:
            c = event.child()
            if c in self._childrens:
                c.removeEventFilter(self)
                self._childrens.remove(c)
        return super().eventFilter(obj, event)


class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        loadUi("mainwindow.ui", self)
        self.showMaximized()
        self.global_pos = QCursor.pos()
        listener = MouseListener(self)
        listener.posChanged.connect(self.on_pos_changed)

        for lay in (self.verticalLayout_top, self.verticalLayout_bottom):
            view = GraphicsView()
            lay.addWidget(view)
        # ...

这篇关于同时在多个小部件中跟踪鼠标移动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆