Как можно отследить наведение курсора мыши на виджеты?
У меня есть медиаплеер, в котором мне нужно фиксировать (для дальнейшего использования) наведение курсора на виджеты (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
→ Ссылка
У вас есть две возможности:
void
QObject::installEventFilter(QObject *filterObj)
Устанавливает фильтр событийfilterObjна этотobject.
Я реализовал этот подход для объектаplayBtnСоздайте класс унаследованный от виджета, с которым вы собираетесь манипулировать и переопределите в нем те методы, которые вам надо.
Я реализовал этов подход для объекта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_())