2

我正在开发一个使用 python 编写的gtk3前端。我正在遵循python-vlc github 页面中的示例,但我遇到了奇怪的行为。我有一个看起来像这样的小部件:libvlcpython-vlcgtk3

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 中,它工作正常。但是,如果我也向该窗口添加一个HeaderBar,然后向该窗口添加一个关闭按钮,则HeaderBar使用set_show_close_button(True)它会按预期停止工作。将PlayerWidget不再显示嵌入,而是将在播放视频的位置打开一个新的(第二个)窗口。如果我不向HeaderBar小部件添加关闭按钮,则嵌入就好了。

向控制台抛出警告:xcb_window window error: X server failure

我首先认为这可能是因为我在 wayland 下使用了 gnome,但它发生在 onX和 on 上wayland

任何帮助表示赞赏。

更新 1:添加了完整的代码示例。当我今天运行它时,它第一次真正按预期工作,但之后再次出现与上述相同的错误。很奇怪。

4

1 回答 1

0

正如@mtz 和@stovfl 正确指出的那样,问题是我p.play()在创建窗口()之前开始了视频播放( p.show_window())。

正如建议的那样,我曾经GLib.idle_add(p.play)让窗口准备好后开始播放。GLib 模块可以使用from gi.repository import GLib.

于 2019-05-14T09:05:13.663 回答