Search code examples
pythongtkpython-3.xpygobjectgtk3

Python. Doing some work on background with Gtk GUI


  • python 3.2.2
  • gtk3 3.2.2
  • python-gobject 3.0.2

I'm trying to display a GUI and do some work in the background. As I understand it should look something like this:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-


import time
from threading import Thread
from gi.repository import Gtk, Gdk

class Gui():
        def run(self):
                self.Window = Gtk.Window()
                self.Window.set_border_width(8)
                self.Window.set_title("Некий GUI")
                self.Window.connect('destroy', lambda x: self.stop())

                self.outBut = Gtk.Button.new_from_stock(Gtk.STOCK_OK)
                self.outBut.set_size_request(150, 35)
                self.outBut.connect('clicked', lambda x: self.passfun)
                self.Window.add(self.outBut)

                self.Window.show_all()

        def stop(self):
                Gtk.main_quit()

        def passfun(self):
                pass

class LoopSleep(Thread):
        def run(self):
                i = 1
                while True:
                        print(i)
                        i = i + 1
                        #time.sleep(1)



gui = Gui()
gui.run()

loopSleep = LoopSleep()
loopSleep.start()

Gdk.threads_init()
Gdk.threads_enter()
Gtk.main()
Gdk.threads_leave()

But it does not work. Several cycles occurs when you press the button. And the cycle runs after the window is closed. But not together.

What I do wrong?


Solution

  • Can't claim to be any expert on python threading nor gtk3 but after playing around a little with your example I found something that appears to work the way you want it. Instead of sub classing Thread i use threading.start(target=loop_sleep), and placed that inside Gui.

    Glib.threads_init() also seem to be needed.

    #!/usr/bin/env python3
    from gi.repository import Gtk,Gdk, GLib
    import threading 
    import time
    
    class Gui(Gtk.Window):
      def __init__(self):
          self.Window = Gtk.Window()
          self.Window.set_border_width(8)
          self.Window.set_title("Некий GUI")
          self.Window.connect('destroy', lambda x: self.stop())
    
          self.outBut = Gtk.Button.new_from_stock(Gtk.STOCK_OK)
          self.outBut.set_size_request(150, 35)
          self.Window.connect('destroy', lambda x: self.stop())
          self.Window.add(self.outBut)
    
          self.Window.show_all()
          threading.Thread(target=loop_sleep).start()
    
      def stop(self):
          Gtk.main_quit()
    
      def passfun(self):
          pass
    
    def loop_sleep():
          i = 1
          while True:
               print(i)
               i = i + 1
               #time.sleep(1)
    
    
    
    app = Gui()
    GLib.threads_init()
    Gdk.threads_init()
    Gdk.threads_enter()
    Gtk.main()
    Gdk.threads_leave()