与 pyside6 一起使用时,键绑定在 python-mpv 中不起作用
Keybinding does not work in python-mpv when using it together with pyside6
我使用库 https://github.com/jaseg/python-mpv 来控制 mpv 播放器,但是当它与 pyside6 一起使用时,键绑定不起作用(播放器完全不接受输入)。我究竟做错了什么?或者在 pyside6 中嵌入时无法使用它们?
(如果我 运行 没有嵌入的具有相同参数的播放器,一切正常)
import os
os.add_dll_directory(os.getcwd())
import mpv
from PySide6.QtWidgets import *
from PySide6.QtCore import *
mpvfolderpath = f"mpv.net/portable_config/"
import sys
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="gpu", # You may not need this
log_handler=print,
loglevel='debug',
input_default_bindings=True,
input_vo_keyboard=True)
@player.on_key_press('f')
def my_f_binding():
print("f работает!")
player.play('test.mp4')
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_())
如果键盘没有被处理(在我的测试中,只有当鼠标没有悬停在视频上时才会发生),按键事件会传播到 Qt window。这意味着我们可以在 keyPressEvent()
覆盖中处理这些事件,然后创建一个正确的 mpv 命令,该命令已经映射到 keypress()
函数。显然,对播放器的引用必须存在,因此您需要将其设为实例属性。
对于标准文字键,通常使用事件的 text()
, but for other keys such as arrows you need to map the event with mpv's key names 就足够了。使用字典当然更简单:
MpvKeys = {
Qt.Key.Key_Backspace: 'BS',
Qt.Key.Key_PageUp: 'PGUP',
Qt.Key.Key_PageDown: 'PGDWN',
Qt.Key.Key_Home: 'HOME',
Qt.Key.Key_End: 'END',
Qt.Key.Key_Left: 'LEFT',
Qt.Key.Key_Up: 'UP',
Qt.Key.Key_Right: 'RIGHT',
Qt.Key.Key_Down: 'DOWN',
# ...
}
class Test(QMainWindow):
def __init__(self, parent=None):
# ...
self.player = mpv.MPV(...)
def keyPressEvent(self, event):
# look up for the key in our mapping, otherwise use the event's text
key = MpvKeys.get(event.key(), event.text())
self.player.keypress(key)
注意:在我的测试中,我必须使用 vo='x11'
标志才能正确嵌入 window,并且还需要 osc=True
才能使用本机 OSD。
我使用库 https://github.com/jaseg/python-mpv 来控制 mpv 播放器,但是当它与 pyside6 一起使用时,键绑定不起作用(播放器完全不接受输入)。我究竟做错了什么?或者在 pyside6 中嵌入时无法使用它们? (如果我 运行 没有嵌入的具有相同参数的播放器,一切正常)
import os
os.add_dll_directory(os.getcwd())
import mpv
from PySide6.QtWidgets import *
from PySide6.QtCore import *
mpvfolderpath = f"mpv.net/portable_config/"
import sys
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="gpu", # You may not need this
log_handler=print,
loglevel='debug',
input_default_bindings=True,
input_vo_keyboard=True)
@player.on_key_press('f')
def my_f_binding():
print("f работает!")
player.play('test.mp4')
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_())
如果键盘没有被处理(在我的测试中,只有当鼠标没有悬停在视频上时才会发生),按键事件会传播到 Qt window。这意味着我们可以在 keyPressEvent()
覆盖中处理这些事件,然后创建一个正确的 mpv 命令,该命令已经映射到 keypress()
函数。显然,对播放器的引用必须存在,因此您需要将其设为实例属性。
对于标准文字键,通常使用事件的 text()
, but for other keys such as arrows you need to map the event with mpv's key names 就足够了。使用字典当然更简单:
MpvKeys = {
Qt.Key.Key_Backspace: 'BS',
Qt.Key.Key_PageUp: 'PGUP',
Qt.Key.Key_PageDown: 'PGDWN',
Qt.Key.Key_Home: 'HOME',
Qt.Key.Key_End: 'END',
Qt.Key.Key_Left: 'LEFT',
Qt.Key.Key_Up: 'UP',
Qt.Key.Key_Right: 'RIGHT',
Qt.Key.Key_Down: 'DOWN',
# ...
}
class Test(QMainWindow):
def __init__(self, parent=None):
# ...
self.player = mpv.MPV(...)
def keyPressEvent(self, event):
# look up for the key in our mapping, otherwise use the event's text
key = MpvKeys.get(event.key(), event.text())
self.player.keypress(key)
注意:在我的测试中,我必须使用 vo='x11'
标志才能正确嵌入 window,并且还需要 osc=True
才能使用本机 OSD。