I just had the same problem and my solution is: JUST FOUR THICK LABELS THAT DRAW A SQUARE.
here is my code:
class MouseTracker(QtCore.QObject):
positionChanged = QtCore.pyqtSignal(QtCore.QEvent)
def __init__(self, widget):
super().__init__(widget)
self._widget = widget
self.widget.setMouseTracking(True)
self.widget.installEventFilter(self)
@property
def widget(self):
return self._widget
def eventFilter(self, o, e):
if e.type() == QtCore.QEvent.MouseButtonPress:
# print("pressed")
self.positionChanged.emit(e)
elif e.type() == QtCore.QEvent.MouseButtonRelease:
# print("release")
self.positionChanged.emit(e)
if o is self.widget and e.type() == QtCore.QEvent.MouseMove:
self.positionChanged.emit(e)
return super().eventFilter(o, e)
then the mainclass...
class MainWindow(QMainWindow):
def __init__(self, master=None):
QMainWindow.__init__(self, master)
self.setWindowTitle("Media Player")
# creating a basic vlc instance
self.instance = vlc.Instance()
# creating an empty vlc media player
self.mediaplayer = self.instance.media_player_new()
self.initUI()
self.isPaused = False
def initUI(self):
self.x0 = None
self.y0 = None
self.x1 = None
self.y1 = None
# Set up the user interface, signals & slots
self.statusBar().showMessage("Ready")
self.resize(640, 480)
self.widget = QWidget(self)
self.setCentralWidget(self.widget)
# In this widget, the video will be drawn
if sys.platform == "darwin": # for MacOS
from PyQt5.QtWidgets import QMacCocoaViewContainer
self.video_label = QMacCocoaViewContainer(0)
else:
self.video_label = QLabel()
tracker = MouseTracker(self.video_label)
tracker.positionChanged.connect(self.on_positionChanged)
self.positionslider = QSlider(Qt.Horizontal, self)
self.positionslider.setToolTip("Position")
self.positionslider.setMaximum(1000)
self.positionslider.sliderMoved.connect(self.setPosition)
#########Buttons#################
self.height_of_BTNS = 30
self.playbutton = QPushButton("Play")
self.playbutton.clicked.connect(self.PlayPause)
self.stopbutton = QPushButton("Stop")
self.stopbutton.clicked.connect(self.Stop)
self.volumeslider = QSlider(Qt.Horizontal, self)
self.volumeslider.setMaximum(100)
self.volumeslider.setValue(self.mediaplayer.audio_get_volume())
self.volumeslider.setToolTip("Volume")
self.volumeslider.valueChanged.connect(self.setVolume)
#################################
self.marker_label_top = QLabel(self)
self.marker_label_top.hide()
self.marker_label_top.raise_()
#################################
self.marker_label_btm = QLabel(self)
self.marker_label_btm.hide()
self.marker_label_btm.raise_()
#################################
self.marker_label_r = QLabel(self)
self.marker_label_r.hide()
self.marker_label_r.raise_()
#################################
self.marker_label_l = QLabel(self)
self.marker_label_l.hide()
self.marker_label_l.raise_()
self.hbuttonbox = QHBoxLayout()
self.hbuttonbox.addWidget(self.playbutton)
self.hbuttonbox.addWidget(self.stopbutton)
self.hbuttonbox.addWidget(self.volumeslider)
self.hbuttonbox.addStretch(1)
self.vboxlayout = QVBoxLayout()
self.vboxlayout.addWidget(self.video_label)
self.vboxlayout.addWidget(self.positionslider)
self.vboxlayout.addLayout(self.hbuttonbox)
self.widget.setLayout(self.vboxlayout)
##############################
self.label_position = QtWidgets.QLabel(self.video_label, alignment=QtCore.Qt.AlignCenter)
self.label_position.setStyleSheet('background-color: white; border: 1px solid black')
##############################
open = QAction("&Open", self)
open.triggered.connect(self.OpenFile)
exit = QAction("&Exit", self)
exit.triggered.connect(sys.exit)
menubar = self.menuBar()
filemenu = menubar.addMenu("&File")
filemenu.addAction(open)
filemenu.addSeparator()
filemenu.addAction(exit)
self.timer = QTimer(self)
self.timer.setInterval(200)
self.timer.timeout.connect(self.updateUI)
self.timer_1 = QTimer(self)
self.timer_1.setInterval(10000)
self.timer_1.timeout.connect(self.updateUI_info)
# Below functions must be FALSE in order to work mousetracker
self.mediaplayer.video_set_mouse_input(False)
self.mediaplayer.video_set_key_input(False)
self.show()
then the function that draw the square when the mouse button released. It actually draw 4 thick labels above the video_label. IMPORTANT TO SET FALSE the self.mediaplayer.video_set_mouse_input(False) and self.mediaplayer.video_set_key_input(False)
@QtCore.pyqtSlot(QtCore.QEvent)
def on_positionChanged(self, e):
if e.type() == QtCore.QEvent.MouseButtonPress:
self.statusBar().showMessage("Ready")
self.marker_label_top.hide()
self.marker_label_r.hide()
self.marker_label_l.hide()
self.marker_label_btm.hide()
print("Mouse press")
self.x0 = e.x()
self.y0 = e.y()
elif e.type() == QtCore.QEvent.MouseButtonRelease and self.x0 is not None and self.y0 is not None:
self.x1 = e.x()
self.y1 = e.y()
print("Mouse release")
if abs(self.x0 - self.x1) > 30 and abs(self.y0 - self.y1) > 30:
marker_width = self.x1 - self.x0
marker_height = self.y1 - self.y0
self.marker_label_top.setStyleSheet("border: 2px solid black;")
self.marker_label_top.resize(marker_width, 2)
self.marker_label_top.move(self.x0, self.y0)
self.marker_label_top.show()
self.marker_label_l.setStyleSheet("border: 2px solid black;")
self.marker_label_l.resize(2, marker_height)
self.marker_label_l.move(self.x0, self.y0)
self.marker_label_l.show()
self.marker_label_r.setStyleSheet("border: 2px solid black;")
self.marker_label_r.resize(2, marker_height)
self.marker_label_r.move(self.x1, self.y0)
self.marker_label_r.show()
self.marker_label_btm.setStyleSheet("border: 2px solid black;")
self.marker_label_btm.resize(marker_width, 2)
self.marker_label_btm.move(self.x0, self.y1)
self.marker_label_btm.show()
print(f"Values UI MOUSE TRACKER X: {self.x0} ,Y: {self.y0}, X1: {self.x1}, Y1: {self.y1}")
else:
self.statusBar().showMessage("Make it bigger")
# self.worker1.reset_values()
self.x0 = None
self.y0 = None
self.x1 = None
self.y1 = None
self.label_position.move(e.x(), e.y())
self.label_position.setText("(%d, %d)" % (e.x(), e.y()))
self.label_position.adjustSize()
self.label_position.show()
and the rest of the code
def PlayPause(self):
# Toggle play/pause status
if self.mediaplayer.is_playing():
self.mediaplayer.pause()
self.playbutton.setText("Play")
self.isPaused = True
else:
if self.mediaplayer.play() == -1:
self.OpenFile()
return
self.mediaplayer.play()
self.playbutton.setText("Pause")
self.timer.start()
self.timer_1.start()
self.isPaused = False
def Stop(self):
self.mediaplayer.stop()
self.playbutton.setText("Play")
def OpenFile(self, filename=None):
if filename == False:
filename = QFileDialog.getOpenFileName(self, "Open File", os.path.expanduser('~'))[0]
if not filename:
return
# # create the media
if sys.version < '3':
filename = vlc.unicode(filename)
self.media = self.instance.media_new(filename)
# put the media in the media player
self.mediaplayer.set_media(self.media)
# parse the metadata of the file
self.media.parse()
if sys.platform.startswith('linux'): # for Linux using the X Server
self.mediaplayer.set_xwindow(self.video_label.winId())
elif sys.platform == "win32": # for Windows
self.mediaplayer.set_hwnd(self.video_label.winId())
print(self.video_label.winId())
elif sys.platform == "darwin": # for MacOS
self.mediaplayer.set_nsobject(int(self.video_label.winId()))
self.PlayPause()
def setVolume(self, Volume):
self.mediaplayer.audio_set_volume(Volume)
def setPosition(self, position):
# setting the position to where the slider was dragged
self.mediaplayer.set_position(position / 1000.0)
def updateUI(self):
# updates the user interface
# setting the slider to the desired position
self.positionslider.setValue(int(self.mediaplayer.get_position() * 1000))
# self.mediaplayer.video_take_snapshot(num=0, psz_filepath='a.png', i_width=1920, i_height=1080)
if not self.mediaplayer.is_playing():
# no need to call this function if nothing is played
self.timer.stop()
if not self.isPaused:
# after the video finished, the play button stills shows
# "Pause", not the desired behavior of a media player
# this will fix it
self.Stop()
def updateUI_info(self):
fps = self.mediaplayer.get_fps()
sec = self.mediaplayer.get_time() / 1000
frame_no = int(round(sec * fps))
print(
f" Frame number Now: {frame_no} \n Frame Rate per Second: {fps} \n Current position in seconds {self.mediaplayer.get_time() / 1000} \n -------------------")
if __name__ == "__main__":
App = QApplication(sys.argv)
Root = MainWindow()
if sys.argv[1:]:
Root.OpenFile(sys.argv[1])
sys.exit(App.exec_())
enjoy :)