Python - After 1 second i cant exit the GUI, when ever the gtk.main() is called it never exit, how can i exit?

StackOverflow https://stackoverflow.com/questions/18981657

How can i exit the GUI after running gtk.main() ? its not exiting after 1 second Only way it exit is to use this:

$ echo "disconnect" | nc localhost 58887

import re,os, time, socket, datetime, threading, subprocess
import gobject, gtk

gobject.threads_init()

class gui(object):

  def listener(self, sock, *args):
    conn, addr = sock.accept()
    gobject.io_add_watch(conn, gobject.IO_IN, self.handler)
    return True

  def handler(self, conn, *args):
    line = conn.recv(4096)
    if not len(line):
      return False
    else:
      if line:
        if line.startswith("disconnect"):
          self.quit(self.window)
      return True

  def __init__(self):
    self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
    self.window.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(6400, 6400, 6440))
    self.window.set_size_request(300, 220)
    self.window.set_border_width(1)
    self.window.set_decorated(False)
    self.window.set_title("TPT")
    self.window.move(250,200)
    self.window.set_name("main window")
    self.window.connect("delete-event", gtk.main_quit)
    self.drawingarea = gtk.DrawingArea()
    self.window.add(self.drawingarea)

  def run(self):
    self.sock = socket.socket()
    self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    self.sock.bind(('', 58887))
    self.sock.listen(1)
    gobject.io_add_watch(self.sock, gobject.IO_IN, self.listener)    
    self.window.show_all()
    self.window.set_keep_above(True)
    if(self.window.get_window().get_state() == gtk.gdk.WINDOW_STATE_MAXIMIZED):
      self.window.unmaximize()    
    gtk.main()

    time.sleep(1)
    gtk.main_quit()

  def quit(self, window):
    gtk.main_quit()

if __name__=='__main__':
    os.system("lsof -i tcp:58887 | grep LISTEN | awk '{print $2}' | xargs kill -9;")
    s=gui()
    s.run()
    gobject.MainLoop.run()
有帮助吗?

解决方案

gtk.main() is a blocking function, thus the next line of code is not executed/interpreted until gtk.main_quit() has been called (asynchronously). One possible way to achieve what you are looking for could be by adding a timeout using gobject.timeout_add before calling gtk.main(), something on the lines of:

...
    if(self.window.get_window().get_state() == gtk.gdk.WINDOW_STATE_MAXIMIZED):
      self.window.unmaximize()
    gobject.timeout_add(1000, gtk.main_quit)
    gtk.main()
...

There is no need for the subsequent calls to sleep and main quit.
Also gobject.MainLoop.run() after s.run() is not necessary.

Hope this helps!

其他提示

For example this works almost.

Step 1: External program to trigger

#!/bin/bash
sleep 2
# do other task
ps aux | grep test.py | awk '{print $2}' | xargs kill -9;
# do other task, its my world i do what i want.... bla bla bla...:P

Step 2: Threading

import re,os, time, socket, datetime, threading, subprocess
import gobject, gtk

gobject.threads_init()

""" :::::::::::: Threading :::::::::::: """
def task1():
  os.system("export DISPLAY=:0.0 && xterm &")
  subprocess.Popen(["/var/tmp/test.sh"], stdout=subprocess.PIPE)
""" :::::::::::: Threading :::::::::::: """

class gui(object):

  def listener(self, sock, *args):
    conn, addr = sock.accept()
    gobject.io_add_watch(conn, gobject.IO_IN, self.handler)
    return True

  def handler(self, conn, *args):
    line = conn.recv(4096)
    if not len(line):
      return False
    else:
      if line:
        if line.startswith("disconnect"):
          self.quit(self.window)
      return True

  def __init__(self):
    self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
    self.window.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(6400, 6400, 6440))
    self.window.set_size_request(300, 220)
    self.window.set_border_width(1)
    self.window.set_decorated(False)
    self.window.set_title("TPT")
    self.window.move(250,200)
    self.window.set_name("main window")
    self.window.connect("delete-event", gtk.main_quit)
    self.drawingarea = gtk.DrawingArea()
    self.window.add(self.drawingarea)

  def run(self):
    self.sock = socket.socket()
    self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    self.sock.bind(('', 58887))
    self.sock.listen(1)
    gobject.io_add_watch(self.sock, gobject.IO_IN, self.listener)    
    self.window.show_all()
    self.window.set_keep_above(True)
    if(self.window.get_window().get_state() == gtk.gdk.WINDOW_STATE_MAXIMIZED):
      self.window.unmaximize()    

    """ :::::::::::: Threading :::::::::::: """
    t1 = threading.Thread(target=task1)
    t1.start()
    t1.join()
    """ :::::::::::: Threading :::::::::::: """

    gtk.main()


  def quit(self, window):
    gtk.main_quit()

if __name__=='__main__':
    os.system("lsof -i tcp:58887 | grep LISTEN | awk '{print $2}' | xargs kill -9;")
    s=gui()
    s.run()
    gobject.MainLoop.run()
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top