python-vlc 不会将 gtk 小部件嵌入 window,而是打开一个新的 window
python-vlc will not embed gtk widget into window, but open a new window instead
我正在为 libvlc
使用 python-vlc
编写 python 的 gtk3
前端。我遵循 python-vlc github page 中的 gtk3
示例,但遇到了 st运行ge 行为。我有一个看起来像这样的小部件:
import gi
import sys
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
class PlayerWidget(Gtk.DrawingArea):
__gtype_name__ = 'VLCWidget'
def __init__(self, instance):
Gtk.DrawingArea.__init__(self)
self.player = instance.media_player_new()
def handle_embed(*args):
if sys.platform == 'win32':
self.player.set_hwnd(self.get_window().get_handle())
else:
self.player.set_xwindow(self.get_window().get_xid())
return True
self.connect("realize", handle_embed)
self.set_size_request(320, 200)
我把它嵌入这里:
import vlc
import sys
from widgets.player import PlayerWidget
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
class VideoPlayer(Gtk.Window):
CONST_APP_NAME = "video player"
def __init__(self):
Gtk.Window.__init__(self)
if 'linux' in sys.platform:
self.instance = vlc.Instance("--no-xlib")
else:
self.instance = vlc.Instance()
self.set_default_size(800, 600)
header = Gtk.HeaderBar(title=self.CONST_APP_NAME)
header.set_subtitle("Filename.mp4")
header.set_show_close_button(True) # this one is the troublemaker
self.set_titlebar(header)
self.connect("destroy", Gtk.main_quit)
self.player_widget = PlayerWidget(self.instance)
self.add(self.player_widget)
def show_window(self):
self.show_all()
Gtk.main()
def set_media(self, fname):
self.player_widget.player.set_media(self.instance.media_new(fname))
def play(self):
self.player_widget.play()
if not len(sys.argv) > 0:
print('Please provide a filename')
sys.exit(1)
p = VideoPlayer()
p.set_media(sys.argv[1])
p.play()
p.show_window()
p.instance.release()
如果我将它嵌入到一个空 Gtk.window 中,它工作正常。但是,如果我也向 window 添加 HeaderBar
,然后使用 set_show_close_button(True)
向 HeaderBar
添加关闭按钮,它将按预期停止工作。 PlayerWidget
将不再显示嵌入,而是将在播放视频的位置打开一个新的(第二个)window。如果我不将关闭按钮添加到 HeaderBar
小部件嵌入就好了。
向控制台发出警告:xcb_window window error: X server failure
我最初认为这可能是因为我在 wayland 下使用 gnome,但它发生在 X
以及 wayland
.
感谢任何帮助。
更新 1:添加了完整的代码示例。当我今天 运行 它时,第一次它确实按预期工作,但之后又出现了与上述相同的错误。很奇怪。
正如@mtz 和@stovfl 正确指出的那样,问题是我在创建 window (p.show_window()
) 之前开始了视频播放 (p.play()
)。
按照建议,我使用 GLib.idle_add(p.play)
让 window 在准备就绪后开始播放。可以使用 from gi.repository import GLib
.
导入 GLib 模块
我正在为 libvlc
使用 python-vlc
编写 python 的 gtk3
前端。我遵循 python-vlc github page 中的 gtk3
示例,但遇到了 st运行ge 行为。我有一个看起来像这样的小部件:
import gi
import sys
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
class PlayerWidget(Gtk.DrawingArea):
__gtype_name__ = 'VLCWidget'
def __init__(self, instance):
Gtk.DrawingArea.__init__(self)
self.player = instance.media_player_new()
def handle_embed(*args):
if sys.platform == 'win32':
self.player.set_hwnd(self.get_window().get_handle())
else:
self.player.set_xwindow(self.get_window().get_xid())
return True
self.connect("realize", handle_embed)
self.set_size_request(320, 200)
我把它嵌入这里:
import vlc
import sys
from widgets.player import PlayerWidget
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
class VideoPlayer(Gtk.Window):
CONST_APP_NAME = "video player"
def __init__(self):
Gtk.Window.__init__(self)
if 'linux' in sys.platform:
self.instance = vlc.Instance("--no-xlib")
else:
self.instance = vlc.Instance()
self.set_default_size(800, 600)
header = Gtk.HeaderBar(title=self.CONST_APP_NAME)
header.set_subtitle("Filename.mp4")
header.set_show_close_button(True) # this one is the troublemaker
self.set_titlebar(header)
self.connect("destroy", Gtk.main_quit)
self.player_widget = PlayerWidget(self.instance)
self.add(self.player_widget)
def show_window(self):
self.show_all()
Gtk.main()
def set_media(self, fname):
self.player_widget.player.set_media(self.instance.media_new(fname))
def play(self):
self.player_widget.play()
if not len(sys.argv) > 0:
print('Please provide a filename')
sys.exit(1)
p = VideoPlayer()
p.set_media(sys.argv[1])
p.play()
p.show_window()
p.instance.release()
如果我将它嵌入到一个空 Gtk.window 中,它工作正常。但是,如果我也向 window 添加 HeaderBar
,然后使用 set_show_close_button(True)
向 HeaderBar
添加关闭按钮,它将按预期停止工作。 PlayerWidget
将不再显示嵌入,而是将在播放视频的位置打开一个新的(第二个)window。如果我不将关闭按钮添加到 HeaderBar
小部件嵌入就好了。
向控制台发出警告:xcb_window window error: X server failure
我最初认为这可能是因为我在 wayland 下使用 gnome,但它发生在 X
以及 wayland
.
感谢任何帮助。
更新 1:添加了完整的代码示例。当我今天 运行 它时,第一次它确实按预期工作,但之后又出现了与上述相同的错误。很奇怪。
正如@mtz 和@stovfl 正确指出的那样,问题是我在创建 window (p.show_window()
) 之前开始了视频播放 (p.play()
)。
按照建议,我使用 GLib.idle_add(p.play)
让 window 在准备就绪后开始播放。可以使用 from gi.repository import GLib
.