Как можно отследить наведение курсора мыши на виджеты?

У меня есть медиаплеер, в котором мне нужно фиксировать (для дальнейшего использования) наведение курсора на виджеты (QSlider, QPushButton) вот код:

from PyQt5.QtWidgets import (QApplication, QWidget, QPushButton, QHBoxLayout, QVBoxLayout, QLabel, 
                            QSlider, QStyle, QSizePolicy, QFileDialog) 
import sys
from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent
from PyQt5.QtMultimediaWidgets import QVideoWidget
from PyQt5.QtGui import QIcon
from PyQt5 import QtCore
from PyQt5 import Qt


class Window(Qt.QWidget):
def __init__(self):
    super().__init__()

    self.setWindowTitle("PyQt5 Media Player")
    self.setGeometry(350, 100, 700, 500)
    self.setWindowIcon(QIcon('player.png'))

    self.setStyleSheet(""" background-color: #000; """)

    self.init_ui()


    self.show()


def init_ui(self):

    self.menubar = Qt.QMenuBar()

    self.menubar.setStyleSheet("""color: #fff;
                            
                            """ )

    self.menufile = self.menubar.addMenu('&File')
    self.menufile.setStyleSheet("""menuFile:hover {
                                background-color: silver;
                                }""")



    action_1 = self.menufile.addAction('Open File')
    action_1.triggered.connect(self.open_file)

    #create media player object
    self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface)


    #create videowidget object

    videowidget = QVideoWidget()


    #create open button
    
    


    #create button for playing
    self.playBtn = QPushButton()
    self.playBtn.setEnabled(False)
    self.playBtn.setIcon(QIcon('F:/img_4_python/15.png'))
    self.playBtn.clicked.connect(self.play_video)



    #create slider
    self.slider = QSlider(QtCore.Qt.Horizontal)
    self.slider.setRange(0,0)
    self.slider.sliderMoved.connect(self.set_position)



    #create label
    self.label = QLabel()
    self.label.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum)


    #create hbox layout
    window = QWidget()
    hboxLayout = QHBoxLayout()
    hboxLayout.setContentsMargins(0,0,0,0)


    #set widgets to the hbox layout

    hboxLayout.addWidget(self.playBtn)
    hboxLayout.addWidget(self.slider)



    #create vbox layout
    vboxLayout = QVBoxLayout()
    vboxLayout.addWidget(videowidget)
    vboxLayout.setMenuBar(self.menubar)
    vboxLayout.addLayout(hboxLayout)
    vboxLayout.addWidget(self.label)


    self.setLayout(vboxLayout)

    self.mediaPlayer.setVideoOutput(videowidget)



    #media player signals

    self.mediaPlayer.stateChanged.connect(self.mediastate_changed)
    self.mediaPlayer.positionChanged.connect(self.position_changed)
    self.mediaPlayer.durationChanged.connect(self.duration_changed)


def open_file(self):
    filename, _ = QFileDialog.getOpenFileName(self, "Open Video")

    if filename != '':
        self.mediaPlayer.setMedia(QMediaContent(QtCore.QUrl.fromLocalFile(filename)))
        self.playBtn.setEnabled(True)


def play_video(self):
    if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
        self.mediaPlayer.pause()

    else:
        self.mediaPlayer.play()


def mediastate_changed(self, state):
    if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
        self.playBtn.setIcon(
            self.style().standardIcon(QStyle.SP_MediaPause)

        )

    else:
        self.playBtn.setIcon(
            self.style().standardIcon(QStyle.SP_MediaPlay)

        )

def position_changed(self, position):
    self.slider.setValue(position)


def duration_changed(self, duration):
    self.slider.setRange(0, duration)


def set_position(self, position):
    self.mediaPlayer.setPosition(position)


def handle_errors(self):
    self.playBtn.setEnabled(False)
    self.label.setText("Error: " + self.mediaPlayer.errorString())





app = QApplication(sys.argv)
window = Window()
sys.exit(app.exec_())

Ответы (1 шт):

Автор решения: S. Nick

У вас есть две возможности:

  1. void QObject::installEventFilter(QObject *filterObj)
    Устанавливает фильтр событий filterObj на этот object.
    Я реализовал этот подход для объекта playBtn

  2. Создайте класс унаследованный от виджета, с которым вы собираетесь манипулировать и переопределите в нем те методы, которые вам надо.
    Я реализовал этов подход для объекта slider


from PyQt5.QtWidgets import (QApplication, QWidget, QPushButton, QHBoxLayout, QVBoxLayout, QLabel, 
                            QSlider, QStyle, QSizePolicy, QFileDialog) 
import sys
from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent
from PyQt5.QtMultimediaWidgets import QVideoWidget
from PyQt5.QtGui import QIcon
from PyQt5 import QtCore
from PyQt5 import Qt


class Slider(QSlider):                                                 # +++ 2. Slider
    def __init__(self, *args, **kwargs):
        super(Slider, self).__init__(*args, **kwargs)
   
    def enterEvent(self, event):
        print('Enter')
        app.instance().setOverrideCursor(QtCore.Qt.OpenHandCursor)
        super(Slider, self).enterEvent(event)

    def leaveEvent(self, event):
        print('Leave')
        app.instance().restoreOverrideCursor()
        super(Slider, self).leaveEvent(event) 


class Window(Qt.QWidget):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("PyQt5 Media Player")
        self.setGeometry(350, 100, 700, 500)
        self.setWindowIcon(QIcon('player.png'))
        self.setStyleSheet(""" background-color: #000; """)

        self.init_ui()
        self.show()

    def init_ui(self):
        self.menubar = Qt.QMenuBar()
        self.menubar.setStyleSheet("""color: #fff;
                                """ )

        self.menufile = self.menubar.addMenu('&File')
        self.menufile.setStyleSheet("""menuFile:hover {
                                    background-color: silver;
                                    }""")

        action_1 = self.menufile.addAction('Open File')
        action_1.triggered.connect(self.open_file)

        #create media player object
        self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface)

        #create videowidget object
        videowidget = QVideoWidget()

        #create open button

#create button for playing
        self.playBtn = QPushButton()
        self.playBtn.installEventFilter(self)                         # 1. installEventFilter
        
        
        self.playBtn.setEnabled(False)
        self.playBtn.setIcon(QIcon('F:/img_4_python/15.png'))
        self.playBtn.clicked.connect(self.play_video)

#create slider
        self.slider = Slider(QtCore.Qt.Horizontal, self)               # 2. Slider 
        self.slider.setRange(0,0)
        self.slider.sliderMoved.connect(self.set_position)

        #create label
        self.label = QLabel()
        self.label.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum)

        #create hbox layout
        window = QWidget()
        hboxLayout = QHBoxLayout()
        hboxLayout.setContentsMargins(0,0,0,0)

        #set widgets to the hbox layout
        hboxLayout.addWidget(self.playBtn)
        hboxLayout.addWidget(self.slider)

        #create vbox layout
        vboxLayout = QVBoxLayout()
        vboxLayout.addWidget(videowidget)
        vboxLayout.setMenuBar(self.menubar)
        vboxLayout.addLayout(hboxLayout)
        vboxLayout.addWidget(self.label)

        self.setLayout(vboxLayout)

        self.mediaPlayer.setVideoOutput(videowidget)

        #media player signals
        self.mediaPlayer.stateChanged.connect(self.mediastate_changed)
        self.mediaPlayer.positionChanged.connect(self.position_changed)
        self.mediaPlayer.durationChanged.connect(self.duration_changed)
        
# +++ 
    def eventFilter(self, source, event):                                   # 1. installEventFilter
        if source == self.playBtn and event.type() == QtCore.QEvent.Enter:
            print(f'playBtn: QEvent.Enter')
        elif source == self.playBtn and event.type() == QtCore.QEvent.Leave:
            print(f'playBtn: QEvent.Leave')           
        return super().eventFilter(source, event)


    def open_file(self):
        filename, _ = QFileDialog.getOpenFileName(self, "Open Video")
        if filename != '':
            self.mediaPlayer.setMedia(QMediaContent(QtCore.QUrl.fromLocalFile(filename)))
            self.playBtn.setEnabled(True)

    def play_video(self):
        if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
            self.mediaPlayer.pause()

        else:
            self.mediaPlayer.play()

    def mediastate_changed(self, state):
        if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
            self.playBtn.setIcon(
                self.style().standardIcon(QStyle.SP_MediaPause)
            )
        else:
            self.playBtn.setIcon(
                self.style().standardIcon(QStyle.SP_MediaPlay)
            )

    def position_changed(self, position):
        self.slider.setValue(position)

    def duration_changed(self, duration):
        self.slider.setRange(0, duration)

    def set_position(self, position):
        self.mediaPlayer.setPosition(position)

    def handle_errors(self):
        self.playBtn.setEnabled(False)
        self.label.setText("Error: " + self.mediaPlayer.errorString())


app = QApplication(sys.argv)
window = Window()
sys.exit(app.exec_())
→ Ссылка