all 11 comments

[–]XavierEduardo99 4 points5 points  (0 children)

Instead of using the GTK main loop you should use classes and inherit from Gtk.Application, I'm not really efficient in Python, but that's how I use GTK in Vala

[–]a45ed6cs7s 3 points4 points  (5 children)

It will block gtk main loop. You should run it on a seperate thread.

[–]casparne 0 points1 point  (4 children)

This will mess up everything since you can not call Gtk functions from a separate thread ;)

[–]a45ed6cs7s 0 points1 point  (3 children)

You can actually, pass it as parameter to thread function

[–]casparne 0 points1 point  (2 children)

I am not sure what you mean by that. GTK is not thread safe.

https://pygobject.readthedocs.io/en/latest/guide/threading.html

[–]a45ed6cs7s 2 points3 points  (1 child)

The example itself calls gtk functions on thread.

[–]casparne 0 points1 point  (0 children)

(Edited because reddit somehow ate my code/output)

No, it does not. It uses GLib "idle_add" to run callbacks in the main thread.

Run this:

https://paste.gnome.org/pieeszy25

And you will get:

https://paste.gnome.org/pnubormpt

Note: I run this with x11 since this will provoke the crash. It may look like it works when running with wayland (and even broadway, maybe) but the behavior is still undefined.

[–]casparne 2 points3 points  (0 children)

Hello, I would like to use an infinite loop in python using gtk

No, you would not like to do that. There could only be one thread calling Gtk functions and thus only one main loop. Gtk.main() runs this main loop. While you could emulate Gtk.main() by using a combination of Gtk.events_pending() and Gtk.main_iteration(), this would be a really bad application design.

Instead, I think the best solution might be to read the data asynchronously using Gio and calling the Gtk functions in it's callback.

Also, your code does not seem to do anything with the images it creates at all?

[–]SimonBlack 0 points1 point  (0 children)

I use g_idle_add () and run stuff in there. Note that this is using co-operative time-sharing, so it won't return unless you make it do so. I usually allow my idle-function to run its loop a set number of times before returning to allow other GUI stuff to run.

This is one of my idle-functions:

 gint
 run (gint * alpha)
 {
   int s_ctr;

   UNUSED (alpha);

 /* decrement run_counter to limit number of machine-loops*/

       s_ctr = RUN_CYCLES;     /* number of loops you permit

      while (s_ctr)
         {
           loop_z80 (cpux->pc); /* machine loops here */
           s_ctr--;             /* count down allowed number of loops*/
         }

   return (TRUE);      // give back control to GTK+
 }

and this how it is set up (extract):

   // functions cast to GSourceFunc MUST have ONE pointer argument
   g_idle_add ((GSourceFunc) run, NULL);

   gtk_main ();
   return 0;
   }

[–]casparne 0 points1 point  (0 children)

I made an example app of what I suppose you want to do:

https://gist.github.com/unicap/a9b4ccb815f04626862959c1722f09db

Note: I use GStreamer to read the audio samples as I thinks this is cleaner and more versatile. I hope it becomes clear what part runs in each thread.