Am 12.01.2013 10:24, schrieb Niklas Koep:
Here's one. I'm using PyGTK 2.24 with gstreamer 0.10.36. Whenever gstreamer
reports an error on my playbin2's message bus I display the error in a
gtk.MessageDialog. This causes the app to deadlock unless I use a context
manager with gtk.gdk.lock. At first I suspected a threading issue, but
according to the gstreamer docs messages on the bus are emitted from the
main thread so I don't see how threading could be an issue. Nevertheless, I
verified this by retrieving the thread ids with libc via ctypes and they're
identical. Here's a minimal example of an app that demonstrates the issue:
http://pastebin.com/b4VTGy9q.
Any ideas of an obvious issue I'm overlooking? I'd greatly appreciate any
input. Cheers!
Calling gtk.Dialog.run() starts a second mainloop, which in a
non-threaded application will block the original mainloop until it
exits. This is useful for modal dialogs, but this is not what you want
here. I don't know in detail what is happening in your example, but my
guess would be that calling gtk.Dialog.run() also blocks the
glib.MainLoop driving gstreamer, causing havoc once it continues.
Working example below.
Cheers,
Christian
#!/usr/bin/env python2
"""
$ python2 --version
Python 2.7.3
$ pkg-config pygtk-2.0 --modversion
2.24.0
$ pkg-config --modversion gstreamer-0.10
0.10.36
"""
import gst
import gtk
gtk.gdk.threads_init()
import gobject
gobject.threads_init()
def main():
bin_ = gst.element_factory_make("playbin2")
bus = bin_.get_bus()
bus.add_signal_watch()
bus.connect("message", on_message)
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
window.set_size_request(300, 180)
window.connect("delete-event", quit, bin_)
vbox = gtk.VBox()
window.add(vbox)
button = gtk.Button("play")
button.connect("clicked", on_clicked, bin_)
vbox.pack_start(button, False)
button = gtk.Button("message")
button.connect("clicked", on_message_clicked, bin_)
vbox.pack_start(button, False)
window.show_all()
gtk.main()
def quit(window, event, bin_):
bin_.set_state(gst.STATE_NULL)
gtk.main_quit()
return False
def on_message_clicked (button, bin_):
err = gst.GError ("test", gst.CORE_ERROR_FAILED, "test")
msg = gst.message_new_error (bin_, err, "test error handling")
bin_.post_message (msg)
def on_clicked(button, bin_):
bin_.set_property("uri", "file:///tmp/test.mp3")
bin_.set_state(gst.STATE_PLAYING)
def on_message(bus, message):
if message.type == gst.MESSAGE_ERROR:
err, debug = message.parse_error()
# FIXME: without the context manager destroying the dialog causes a
# deadlock, but shouldn't this lock protection be redundant?
#with gtk.gdk.lock: error_dialog("Error", "%s" % err)
error_dialog("Error", "%s" % err)
def on_response(diag, res):
diag.destroy()
def error_dialog(text, secondary_text=""):
diag = gtk.MessageDialog(
flags=gtk.DIALOG_DESTROY_WITH_PARENT|gtk.DIALOG_MODAL,
type=gtk.MESSAGE_ERROR, buttons=gtk.BUTTONS_OK
)
diag.set_property("text", text)
diag.set_property("secondary-text", secondary_text)
diag.connect("response", on_response)
diag.show()
if __name__ == "__main__":
main()
_______________________________________________
pygtk mailing list [email protected]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://faq.pygtk.org/