python-vlc не будет вставлять виджет gtk в окно, но вместо этого откроет новое окно - PullRequest
1 голос
/ 08 мая 2019

Я работаю над gtk3 интерфейсом для libvlc, написанным на python с использованием python-vlc.Я следую примеру gtk3 со страницы python-vlc github , но у меня странное поведение.У меня есть виджет, который выглядит так:

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

Сначала я подумал, что это может быть из-заЯ использую gnome под Wayland, но это происходит на X, а также на wayland.

Любая помощь приветствуется.

Обновление 1: добавлен пример полного кода.Когда я запускал его сегодня, в первый раз он действительно работал как ожидалось, но после этого снова возникла та же ошибка, что и описанная выше.Очень странно.

1 Ответ

0 голосов
/ 14 мая 2019

Как правильно отметили @mtz и @stovfl, проблема заключалась в том, что я начал воспроизведение видео (p.play()) перед созданием окна (p.show_window()).

Как и предполагалось, я использовал GLib.idle_add(p.play)чтобы позволить окну начать воспроизведение, как только оно будет готово.Модуль GLib можно импортировать с помощью from gi.repository import GLib.

...