-
Notifications
You must be signed in to change notification settings - Fork 69
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Windows] Controls do not work in PyQT (?) #103
Comments
I don't know Qt that well myself, but I guess the problem is that Qt catches all input events and they never get forwarded to mpv. My first idea on how to make this work without rewriting all of libmpv's input bindings would be to catch all key press events on the player QWidget and forward them into mpv using the keypress command. There is also a The reason |
Thank you very much @jaseg for your helpful answer. I have tried using the keypress and keybind commands yet they do not seem to work #First I tried this
player.command('keybind esc stop')
player.command('keybind right seek 1 relative')
#And then I tried
player.keybind('esc stop')
player.keybind('right seek 1 relative') Example errors I get:
And when I tried using
Do you have any further suggestions? Thank you. |
@jaseg I have tried your recommendations and have written ...
from pynput import keyboard
def play(url, title):
#From https://stackoverflow.com/q/9377914/
class TitleBar(QWidget):
def __init__(self, parent):
super(MyBar, self).__init__()
self.parent = parent
print(self.parent.width())
self.layout = QHBoxLayout()
self.layout.setContentsMargins(0,0,0,0)
btn_size = 35
self.btn_close = QPushButton("x")
self.btn_close.clicked.connect(self.btn_close_clicked)
self.btn_close.setFixedSize(btn_size,btn_size)
self.btn_close.setStyleSheet("background-color: red;")
self.btn_min = QPushButton("-")
self.btn_min.clicked.connect(self.btn_min_clicked)
self.btn_min.setFixedSize(btn_size, btn_size)
self.btn_min.setStyleSheet("background-color: gray;")
self.btn_max = QPushButton("+")
self.btn_max.clicked.connect(self.btn_max_clicked)
self.btn_max.setFixedSize(btn_size, btn_size)
self.btn_max.setStyleSheet("background-color: gray;")
self.title.setFixedHeight(35)
self.title.setAlignment(Qt.AlignCenter)
self.layout.addWidget(self.btn_min)
self.layout.addWidget(self.btn_max)
self.layout.addWidget(self.btn_close)
self.setLayout(self.layout)
self.start = QPoint(0, 0)
self.pressing = False
def resizeEvent(self, QResizeEvent):
super(MyBar, self).resizeEvent(QResizeEvent)
self.title.setFixedWidth(self.parent.width())
def mousePressEvent(self, event):
self.start = self.mapToGlobal(event.pos())
self.pressing = True
def mouseMoveEvent(self, event):
if self.pressing:
self.end = self.mapToGlobal(event.pos())
self.movement = self.end-self.start
self.parent.setGeometry(self.mapToGlobal(self.movement).x(),
self.mapToGlobal(self.movement).y(),
self.parent.width(),
self.parent.height())
self.start = self.end
def mouseReleaseEvent(self, QMouseEvent):
self.pressing = False
def btn_close_clicked(self):
self.parent.close()
def btn_max_clicked(self):
self.parent.showMaximized()
def btn_min_clicked(self):
self.parent.showMinimized()
class MainWin(QMainWindow):
def on_press(self,key):
print('{0} pressed'.format(
key))
if key == keyboard.Key.right:
self.player.command('seek', '0.2', 'absolute+keyframes')
def on_release(self, key):
print('{0} released'.format(
key))
if key == keyboard.Key.esc:
try:
print("Quitting")
sys.exit('quit')
except KeyboardInterrupt:
sys.exit('quit')
def __init__(self, parent=None):
super().__init__(parent)
self.container = QWidget(self)
self.setCentralWidget(self.container)
self.container.setAttribute(Qt.WA_DontCreateNativeAncestors)
self.container.setAttribute(Qt.WA_NativeWindow)
self.setWindowTitle(title)
self.resize(1000, 563)
self.player = mpv.MPV(wid=str(int(self.container.winId())), ytdl=True, player_operation_mode='pseudo-gui',
script_opts='osc-layout=box,osc-seekbarstyle=bar,osc-deadzonesize=0,osc-minmousemove=3',
input_default_bindings=True,
input_vo_keyboard=True,
osc=True) #
#player.play(url)
# Collect events until released
with keyboard.Listener(
on_press=self.on_press,
on_release=self.on_release) as listener:
Thread(target = self.player.play, args=(url,)).start()
listener.join()
#Process(target=player.play, args=(url,)).start()
#player.wait_for_playback()
del self.player
#@player.command('keybind esc stop')
#def passthru():
# pass
#@player.command('keybind right seek 1 relative')
#def passthru():
# pass
app = QApplication(sys.argv)
import locale
locale.setlocale(locale.LC_NUMERIC, 'C')
win = MainWin()
win.show()
sys.exit(app.exec_())
play(url, title) it registers commands, but does them all in a seperate process, which upon exiting plays the video. I couldn't seem to get keypress or keybind to give me anything but my prior error.
Do you have suggestions? Thank you. |
Are you on windows? |
I found a stackoverflow post on keypresses in PyQt, I will try to tweak it to input to mpv. player commands aren't working
def __init__(self, parent=None): #, parent=None
super(MainWin, self).__init__(parent) #parent
self.container = QWidget(self)
self.setCentralWidget(self.container)
self.container.setAttribute(Qt.WA_DontCreateNativeAncestors)
self.container.setAttribute(Qt.WA_NativeWindow)
self.setWindowTitle(title)
self.resize(1000, 563)
self.player = mpv.MPV(wid=str(int(self.container.winId())), ytdl=True, player_operation_mode='pseudo-gui',
script_opts='osc-layout=box,osc-seekbarstyle=bar,osc-deadzonesize=0,osc-minmousemove=3',
input_default_bindings=True,
input_vo_keyboard=True,
osc=True) #
self.player.play(url)
#player.wait_for_playback()
del self.player
def keyPressEvent(self, event):
if event.key() == Qt.Key_Q:
print("Quitting")
sys.exit('quit')
elif event.key() == Qt.Key_Right:
self.player.command('seek', '0.2', 'absolute+keyframes')
event.accept() |
Sorry in my gist I forgot the options: |
That seems very likely, but I cannot run any VM because of credential guard (whatever that is). I'll continue tweaking the code; and if I cannot find a solution then I can mark it up to libmpv on windows |
Would love to have an update on this, I really like this module |
@reaganiwadha All I can say is that on my (Linux) machine, the example from the README works for me with OP's code, both for keyboard and for mouse input. I only needed to change their custom key binding handler a bit to mesh with both libmpv and PyQt's respective event loops. If things don't work for you, please post an example script that I can run to reproduce the behavior, post your Python, PyQt and libmpv versions, and tell us what operating system you're running things on. At this point, I suspect that this is a Windows-only issue. #!/usr/bin/env python3
import mpv
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class Test(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.container = QWidget(self)
self.setCentralWidget(self.container)
self.container.setAttribute(Qt.WA_DontCreateNativeAncestors)
self.container.setAttribute(Qt.WA_NativeWindow)
player = mpv.MPV(wid=str(int(self.container.winId())),
vo='x11', # You may not need this
loglevel='debug',
script_opts='osc-layout=box,osc-seekbarstyle=bar,osc-deadzonesize=0,osc-minmousemove=3',
input_default_bindings=True,
input_vo_keyboard=True,
osc=True)
@player.on_key_press('esc')
def my_key_binding(*args):
print('ESC pressed')
# Note: We can't just call sys.exit() here because that would only terminate the python interpreter, but not libmpv or PyQt.
player.quit() # Tell libmpv to terminate itself
QApplication.instance().quit() # Tell PyQt to terminate. This closes the window, and makes PyQt return from app.exec below.
player.loop = 'inf'
player.play('tests/test.webm')
app = QApplication(sys.argv)
# This is necessary since PyQT stomps over the locale settings needed by libmpv.
# This needs to happen after importing PyQT before creating the first mpv.MPV instance.
import locale
locale.setlocale(locale.LC_NUMERIC, 'C')
win = Test()
win.show()
sys.exit(app.exec_()) |
Take this code for instance.
It works pretty well, it plays video in the window and it read the video from the
url
variable and the window title fromtitle
. Yet despite me having set not only the pseudo-gui and keyboard bindings, neither of them initiate so inside my window is video playing with no keyboard or in-window controls. I am relatively new to PyQt, so maybe this is a simple to fix issue.Another oddity with the PyQt integration is that wait_for_playback() is automatic, and actually trying to call it prevents the video from playing.
I really like this module, and it is very handy for several of my video projects (ie this)
The text was updated successfully, but these errors were encountered: