[Gtk-sharp-list] Best way to continuously update a Gtk.Image (V4L)
Sebastian
scut@nb.in-berlin.de
Sun, 18 Apr 2004 15:35:00 +0800
Hi *,
I hope to have solved all of my problems. Below is a summary for the
archives, as other people might face similar problems :)
On Sat, Apr 17, 2004 at 12:47:37PM +0800, Sebastian wrote:
> 1. Is just overwriting the Pixbuf byte array and queuing a redraw the
> proper way or may this pointer change somehow?
Seems to work.
> 2. How to call this from the Gtk# main loop? There is no main loop at the
> moment, and if I try to close the window, I get this message:
>
> (<unknown>:1970): Gtk-CRITICAL **: file gtkmain.c: line 1151
> (gtk_main_quit): assertion `main_loops != NULL' failed
>
> I do not want the user to have to click a start-button or the like.
I now use one main GTK loop plus Gdk.Threads.Enter/Leave calls.
See http://bobi.ifs.hr/ifs/razno/doc/gtk/gtkfaq-5.html#ss5.2 and
http://www.ijon.de/comp/tutorials/threads/gdkgtk.html (german).
...
using System.Threading;
...
public class V4lGtk
{
private static Thread capture = null;
public static void Main (string[] args)
{
Gdk.Threads.Init ();
Application.Init ();
V4lGtk vg = new V4lGtk ();
vg.Test ();
}
public void Test ()
{
Window win = new Window ("V4L GTK# test");
win.DeleteEvent += new DeleteEventHandler (Window_Delete);
Video4Linux vl = new Video4Linux ();
vl.Open ();
vl.SetCaptureSize (320, 240);
vl.PrepareCapture ();
Gdk.Pixbuf pb = new Gdk.Pixbuf (Gdk.Colorspace.Rgb, false,
8, vl.FrameWidth, vl.FrameHeight);
Image img = new Image (pb);
win.Add (img);
win.ShowAll ();
CaptureThread cth = new CaptureThread (vl, pb, img);
ThreadStart captureSt = new ThreadStart (cth.Start);
capture = new Thread (captureSt);
capture.Start ();
Console.WriteLine ("main GTK thread");
// The main loop, wrapped within .Enter and .Leave
Gdk.Threads.Enter ();
Application.Run ();
Gdk.Threads.Leave ();
}
static void Window_Delete (object obj, DeleteEventArgs args)
{
capture.Abort ();
Application.Quit ();
args.RetVal = true;
}
}
class CaptureThread
{
private CaptureThread ()
{
}
Video4Linux vl;
Gdk.Pixbuf pb;
Image img;
public CaptureThread (Video4Linux vl, Gdk.Pixbuf pb, Image img)
{
this.vl = vl;
this.pb = pb;
this.img = img;
}
public void Start ()
{
GdkPixbufConverter conv = new GdkPixbufConverter (vl, pb);
vl.StartCapture ();
while (true) {
vl.GetFrame ();
conv.ConvertCurrentFrame ();
// Wrapped inside Enter/Leave to not confuse GTK
Gdk.Threads.Enter ();
img.QueueDraw ();
Gdk.Threads.Leave ();
vl.FreeFrame ();
}
}
}
...
Is this the right way (I think so), or did I miss something?
ciao,
Sebastian
--
|\ _,,,--,,_ ,) scut@nb.in-berlin.de, http://segfault.net/~scut/pgp
/,`.-'`' -, ;-;;' 5453 AC95 1E02 FDA7 50D2 A42D 427E 6DEF 745A 8E07
_ |,4- ) )-,_ ) /\__________________________________________________________
~'---''(_/--' (_/-'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~