2016-03-18 2 views
0

Мне нужно включить функцию из моего главного окна и запустить эту функцию, потому что она проверяет какое-либо состояние (это функция again(), и я удалил проверку из этого примера). Эта функция должна оставаться неизменной, как сейчас. Но главное окно висит. Пожалуйста помоги.Главное окно python зависает с таймером

# -*- coding: utf-8 -*- 
import pygtk 
pygtk.require("2.0") 
import gtk 
import gobject 
import time 
gtk.gdk.threads_init() 

class App: 
    def __init__(self): 
     self.okno = gtk.Window(gtk.WINDOW_TOPLEVEL) 
     self.okno.resize(400,150) 
     self.okno.show_all() 

     self.again() 


    def again(self): 
     i=0 
     while 1: 
      print i 
      i=i+1   

if __name__ == "__main__": 
    app = App() 
    gtk.threads_enter() 
    gtk.main() 
    gtk.threads_leave() 

ИЗМЕНЕНО:

# -*- coding: utf-8 -*- 
import pygtk 
pygtk.require("2.0") 
import gtk 
import gobject 
import time 
import threading, sys 

gtk.gdk.threads_init() 

class App(threading.Thread): 
    def __init__(self): 
     self.okno = gtk.Window(gtk.WINDOW_TOPLEVEL) 
     self.okno.resize(400,150) 
     self.okno.show_all() 
     self.again()   

    def again(self): 
     i=0 
     while 1: 
      print i 
      sys.stdout.flush() 
      i=i+1  
      time.sleep(1) 

if __name__ == "__main__": 
    gtk.threads_enter() 
    threading.Thread(target=App).start() 
    gtk.threads_leave() 
    gtk.main() 
+0

Вы не используете темы правильно. Вы должны сказать 'gtk.threads_enter()' непосредственно перед 'app = App()' и 'gtk.threads_leave()' сразу после. Тем не менее, вы даже не используете потоки, поэтому вы также должны изменить 'app = App()' на 'threading.Thread (target = App) .start()'. Вам нужно будет импортировать 'threading'. – zondo

+0

Зондо, спасибо. Я изменил свой код, но он работает не так, как ожидалось. Я что-то упускаю? – peter

+0

Скорее всего, печать чего-либо без пауз * и *, связанных с событиями окна, слишком велика для обработки. – zondo

ответ

1

Вы не можете использовать GTK API из разных потоков; только одному потоку разрешено использовать GTK, и это поток, который вызвал Gtk.main() (и инициализировал библиотеку, которая выполняется автоматически с помощью привязок Python при импорте модуля Gtk).

Правильный способ использования потока с GTK - создать рабочий поток для выполнения долговременного задания, и всякий раз, когда требуется обновить интерфейс, вы должны запланировать обратный вызов в основном цикле, используя GLib.idle_add(). Вызываемый вами пропуск в функцию idle_add() гарантированно вызывается в том же потоке, что и тот, который управляет основным контуром.

API-интерфейс threads_enter() и API, если вы используете рабочий поток (и эти функции не переносятся в любом случае, они устарели в GTK 3.0).