2013-09-22 2 views
0

나는이 Python 해골을 가지고 있는데, main.py가 좋고 server.py가 좋다. 하지만 chat() 순간에 GUI가 보이지만, gtk.main()이 실행되면 server.py 모듈이나 chat.py 자체에서 어떤 활동도 허용하지 않습니다.파이썬 - 내 전체 응용 프로그램을 차단하지 않고 멀티 태스킹을 수행 할 수있는 gtk.main()을 실행하는 방법은 무엇입니까?

어떻게 chat.py가 다른 클래스와 간섭하지 않고 멀티 태스킹처럼 실행되도록 유연하게 설정할 수 있습니까?

참고 : os.system ('/ var/tmp/chat.py')을 server.py에서 실행하면 아무런 문제가 없지만 문제는 발생하지 않습니다. (그렇게하면 해당 메소드를 피하려고합니다.)

어떤 생각, 왜, 어떻게 chat.py가 종료 될 때까지 전체 응용 프로그램을 차단하지 않고 독립적으로 작동하게 할 수 있습니까?

main.py :

#!/usr/bin/python 
from myglobal import bgcolors 
from myglobal import parsePresets 
from server import server 
from chat import chat 
t = server(58888) 
t.start() 

server.py

class server(threading.Thread): 
    def __init__(self, port): 
    threading.Thread.__init__(self) 
    self.port = port 
    self.selfv = chat() 
    self.selfv.run() 

    def run(self): 
    host = '' 
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
    s.bind((host, self.port)) 
    #s.setblocking(0) # non-blocking 
    s.listen(1) 
    conn, addr = s.accept() 
    serverFlag = True 
    while serverFlag: 
     try: 
     data = conn.recv(1024) 
     except socket.error: 
     s.listen(1) 
     conn, addr = s.accept() 
     continue 

     if not data: 
     s.listen(1) 
     conn, addr = s.accept() 
     else: 
     line = data 
     conn.send('ok') 
     conn.close() 

chat.py

class chat(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: 
     return True 

    def __init__(self): 
    self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) 
    self.window.set_size_request(800, 450) 
    self.window.move(0,0) 
    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(('', 58881)) 
    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() 

    def quit(self): 
    gtk.main_quit() 


#if __name__=='__main__': 
# s=SelfView() 
# s.run() 
    #gobject.MainLoop.run() 

답변

1

내가 코드를 테스트하기 때문에 내 대답은 너무 많은 일을 누락 매우 자신감이 없을 것입니다.

server 개체의 생성자는 gtk.main()을 호출하는 chat 개체의 run 메서드를 호출합니다. 이렇게하면 GTK의 이벤트 루프가 실행되기 시작하므로 사용자가 GUI를 닫을 때까지이 스레드에서 더 이상 발생하지 않습니다. 실제로 서버 스레드에 대한 start 메서드는 실행될 가능성이 없습니다.

다른 스레드에서 gtk.main()을 실행한다고 가정합니다. 이를 수행하는 방법을 제안하려면 내가하려는 일에 대해 더 많은 정보가 필요합니다. 아마도 chat 개체를 threading.Thread의 인스턴스로 만들어야 할 수도 있습니다.

+0

내가 언급 한 것처럼 chat.py를 만들었지 만 동일합니다. gtk.main()이 실행 되 자마자 다른 명령문이 작동하지 않습니다. – YumYumYum

+1

'gtk.main()'을 호출하면 사용자가 GUI를 종료 할 때까지 반환되지 않습니다. 이 작업은 별도의 스레드에서 수행해야합니다. 'gtk.main()'에 대한 호출은 별도의 스레드의'run' 메소드에 있어야합니다. – nickie

1

항상 메인 스레드에서 gui를 실행하십시오. gui가 시작되기 전에 다른 스레드에서 서버를 시작하십시오. gui가 종료 된 후에 청취자를 닫습니다.

+0

나는 또한 당신의 제안을 시도했으나 효과가 없었습니다. 실제로 모든 창을 닫을 때 주 창과 두 번째 창, 세 번째 창 등을 여는 하나의 프로토콜이 있습니다. 그래서 주요 응용 프로그램은 어떤 GUI를 실행할지 여부를 결정하는 제 경우에는 server.py입니다. – YumYumYum

+0

프로그램에서 gtk.main()을 한 번만 실행하십시오. 기본 GUI가 이미 표시된 상태에서 채팅 창을 표시하려면 show 또는 동등한 것을 호출하십시오. 메인 스레드에서 GUI 관련 항목을 호출하는 것을 잊지 마십시오. – ledzep2