'gtk.gdk.Win32Window' object has no attribute 'get_xid' - python

Env - python2.7, gstreamer 1.0 on windows7
I was trying to run codes from http://bazaar.launchpad.net/~jderose/+junk/gst-examples/view/head:/video-player-1.0 on my env, and it's failing with AttributeError: 'gtk.gdk.Win32Window' object has no attribute 'get_xid'
I found minimum code to test get_xid and pasting it here:-
import gi
gi.require_version("GdkX11", "3.0")
gi.require_version('Gtk', '3.0')
from gi.repository import GdkX11, Gtk, GstVideo
class App:
def __init__(self):
win = Gtk.Window()
win.resize(400, 400)
win.connect('delete-event', Gtk.main_quit)
da = Gtk.DrawingArea()
win.add(da)
win.show_all()
import pdb;pdb.set_trace()
print da.get_property('window').get_xid()
if __name__ == "__main__":
App()
Gtk.main()
AttributeError: 'gtk.gdk.Win32Window' object has no attribute 'get_xid'
Ideally if i have imported GdkX11 then window object should have get_xid, But its not working on windows7 environment, looks like GdkX11 is not for windows user. Please suggest me how should I solve this issue.

On Windows machines, get_xid() will cause the issue you are seeing.
A workaround is provided in the following answer: Get the window handle in PyGI

Related

How to render MPV to GTK4 window on X11 with python?

How can mpv render to GTK4 window or widget?
In GTK3 it was quite easy to get XID (and put it as argument to MPV) but in GTK4 It seem have to be done with GtkX11 and X11Surface https://docs.gtk.org/gdk4-x11/method.X11Surface.get_xid.html
But I have not clue how to do that in python - can't get surface from window/widget.
#!/usr/bin/env python3
import gi
import mpv
gi.require_version('Gtk', '4.0')
gi.require_version('Gdk', '4.0')
gi.require_version('GdkX11', '4.0')
from gi.repository import Gtk, Gdk, GdkX11
class MainClass(Gtk.ApplicationWindow):
def __init__(self, app):
super(MainClass, self).__init__()
self.set_application(app)
self.set_default_size(600, 400)
self.connect("destroy", self.on_destroy)
widget = Gtk.Frame()
self.set_child(widget)
self.present()
# Can't get XID from widget there
self.mpv = mpv.MPV(wid=str(GdkX11.X11Surface.get_xid(widget)))
self.mpv.play("test.webm")
def on_destroy(self, widget, data=None):
self.mpv.terminate()
Gtk.main_quit()
def on_activate(app):
application = MainClass(app)
if __name__ == '__main__':
# This is necessary since like Qt, Gtk stomps over the locale settings needed by libmpv.
# Like with Qt, this needs to happen after importing Gtk but before creating the first mpv.MPV instance.
import locale
locale.setlocale(locale.LC_NUMERIC, 'C')
app = Gtk.Application()
app.connect('activate', on_activate)
app.run(None)
TypeError: argument self: Expected GdkX11.X11Surface, but got gi.repository.Gtk.Frame
I don't know if this is completely correct
GdkX11.X11Surface.get_xid() takes a X11Surface as a parameter
Try this:
self.mpv = mpv.MPV(wid=str(GdkX11.X11Surface.get_xid(self.get_surface())))
This worked for me

Why I receive this error about attribute in Python?

I have a problem in a simple Glade/Gtk project, I have some objects like Button, Text inputs etc. I have a basic error, gi.repository.Gtk has no attribute 'builder'. Any Ideas? Thanks in advance
Here's the error that I receive (https://imgur.com/a/14cEdn0)
import gi
gi.require_version('Gtk', '3.0')
import gi.repository
from gi.repository import Gtk
class Main:
def __init__(self):
gladeFile = Gtk.builder
self.builder = Gtk.Builder()
self.builder.add_from_file(gladeFile)
self.builder.connect_signals(self)
window = self.builder.get_object("button1")
window.show()
if __name__ == '__main__':
main = Main()
Gtk.main()
Looks like your gladeFile should be a string containing the path to your glade file, e.g. gladeFile = "example.glade".

python-vlc will not embed gtk widget into window, but open a new window instead

I'm working on a gtk3 front end for libvlc written in python using python-vlc. I'm following the gtk3 example from the python-vlc github page, but am experiencing strange behavior. I have a widget that looks like that:
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)
I embed it here:
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()
It works fine if I embed it into an empty Gtk.window. If, however, I add a HeaderBar to that window as well and then add a close button to that HeaderBar using set_show_close_button(True) it stops working as expected. The PlayerWidget will not be shown embedded anymore, but instead a new (second) window will be opened where the video is played. If I do not add the close button to the HeaderBar the widget gets embedded just fine.
A warning is thrown to the console: xcb_window window error: X server failure
I first thought it could be because I use gnome under wayland, but it occurs on X as well as on wayland.
Any help is appreciated.
Update 1: Added full code example. When I ran it today, the first time it actually worked as expected, but after that the same bug as described above occured again. Very weird.
As #mtz and #stovfl correctly pointed out, the problem was that I started the video playback (p.play()) before creating the window (p.show_window()).
As suggested I used GLib.idle_add(p.play) to let the window start the playback once it's ready. The GLib module can be imported using from gi.repository import GLib.

Playing video in Gtk in a window with a menubar

I have created a video player in Gtk3 using Gstreamer in Python3. It works except when I add a GtkMenuBar (place 2). It will then either show a black screen, or fail with an exception. The exception references the XInitThreads, which I am calling (Place 1) (I took this from the pitivi project) but this does not seem to make a diffrence.
Question: How do I make this work?
Other things I would like to know:
Why would the menubar break this?
This will clearly break on anything not X, is there some prebuilt component the abstracts this logic and is crossplatform that I am missing?
System:
python3
Gtk3
Ubuntu 16.04
The exception:
[xcb] Unknown request in queue while dequeuing
[xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
[xcb] Aborting, sorry about that.
python3: ../../src/xcb_io.c:179: dequeue_pending_request: Assertion `!xcb_xlib_unknown_req_in_deq' failed.
The code (in as small a form as possible to demonstrate the concept):
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('Gst', '1.0')
gi.require_version('GstVideo', '1.0')
from gi.repository import Gtk, xlib
from gi.repository import Gst, Gdk, GdkX11, GstVideo
Gst.init(None)
Gst.init_check(None)
# Place 1
from ctypes import cdll
x11 = cdll.LoadLibrary('libX11.so')
x11.XInitThreads()
# [xcb] Unknown request in queue while dequeuing
# [xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
# [xcb] Aborting, sorry about that.
# python3: ../../src/xcb_io.c:179: dequeue_pending_request: Assertion `!xcb_xlib_unknown_req_in_deq' failed.
# (foo.py:31933): Gdk-WARNING **: foo.py: Fatal IO error 11 (Resource temporarily unavailable) on X server :1.
class PipelineManager(object):
def __init__(self, window, pipeline):
self.window = window
if isinstance(pipeline, str):
pipeline = Gst.parse_launch(pipeline)
self.pipeline = pipeline
bus = pipeline.get_bus()
bus.set_sync_handler(self.bus_callback)
pipeline.set_state(Gst.State.PLAYING)
def bus_callback(self, bus, message):
if message.type is Gst.MessageType.ELEMENT:
if GstVideo.is_video_overlay_prepare_window_handle_message(message):
Gdk.threads_enter()
Gdk.Display.get_default().sync()
win = self.window.get_property('window')
if isinstance(win, GdkX11.X11Window):
message.src.set_window_handle(win.get_xid())
else:
print('Nope')
Gdk.threads_leave()
return Gst.BusSyncReply.PASS
pipeline = Gst.parse_launch('videotestsrc ! xvimagesink sync=false')
window = Gtk.ApplicationWindow()
header_bar = Gtk.HeaderBar()
header_bar.set_show_close_button(True)
# window.set_titlebar(header_bar) # Place 2
drawing_area = Gtk.DrawingArea()
drawing_area.connect('realize', lambda widget: PipelineManager(widget, pipeline))
window.add(drawing_area)
window.show_all()
def on_destroy(win):
try:
Gtk.main_quit()
except KeyboardInterrupt:
pass
window.connect('destroy', on_destroy)
Gtk.main()
When searching through documentation on a separate issue, I came across a reference to the gtksink widget. This seems to be the correct way to put video in a gtk window, but unfortunately none of the tutorials on this use it.
Using the gtksink widget fixes all the problems and greatly reduces code complexity.
The revised code:
from pprint import pprint
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('Gst', '1.0')
gi.require_version('GstVideo', '1.0')
from gi.repository import Gtk, Gst
Gst.init(None)
Gst.init_check(None)
class GstWidget(Gtk.Box):
def __init__(self, pipeline):
super().__init__()
self.connect('realize', self._on_realize)
self._bin = Gst.parse_bin_from_description('videotestsrc', True)
def _on_realize(self, widget):
pipeline = Gst.Pipeline()
factory = pipeline.get_factory()
gtksink = factory.make('gtksink')
pipeline.add(gtksink)
pipeline.add(self._bin)
self._bin.link(gtksink)
self.pack_start(gtksink.props.widget, True, True, 0)
gtksink.props.widget.show()
pipeline.set_state(Gst.State.PLAYING)
window = Gtk.ApplicationWindow()
header_bar = Gtk.HeaderBar()
header_bar.set_show_close_button(True)
window.set_titlebar(header_bar) # Place 2
widget = GstWidget('videotestsrc')
widget.set_size_request(200, 200)
window.add(widget)
window.show_all()
def on_destroy(win):
try:
Gtk.main_quit()
except KeyboardInterrupt:
pass
window.connect('destroy', on_destroy)
Gtk.main()

Need a simple "Hello World" example using the Webkit library in Python

Does anyone know of a simple "Hello World" example for using the Webkit library in Python? I have a GTK window, and inside I want to put Webkit.
With Python/mozembed (Mozilla/Gecko), this is simple:
mozembed = gtkmozembed.MozEmbed()
mozembed.load_url('http://google.com/')
..and I have already created my browser, how do I do this with WebKit?
Did you check the Python bindings for the WebKit GTK+ port. In one of the directory there are demos on how to use it, including a browser: python demos/tabbed_browser.py
You could check also the slides of a FOSDEM by Alp Toker on WebKit GTK+ (pdf) Developing hybrid Web/GTK+ rich internet applications.
import gtk
import webkit
view = webkit.WebView()
sw = gtk.ScrolledWindow()
sw.add(view)
win = gtk.Window(gtk.WINDOW_TOPLEVEL)
win.add(sw)
win.show_all()
view.open("http://w3.org/")
gtk.main()
That should give you good hints for starting.
Now with WebKitGtk2
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('WebKit2', '4.0')
from gi.repository import Gtk, WebKit2
window = Gtk.Window()
window.set_default_size(800, 600)
window.connect("destroy", Gtk.main_quit)
scrolled_window = Gtk.ScrolledWindow()
webview = WebKit2.WebView()
webview.load_uri("https://google.cl")
scrolled_window.add(webview)
window.add(scrolled_window)
window.show_all()
Gtk.main()

Categories

Resources