2013-03-31 50 views
4

我試圖用GTK創建一個多線程。需要Gtk.gdk,但我收到有關沒有gdk屬性的錯誤。我使用Raspbian的樹莓派。'gi.repository.Gtk'對象沒有屬性'gdk'

這是我如何導入GTK庫。

try: 
    import pygtk 
    pygtk.require("2.0") 
except: 
    pass 

try: 
    from gi.repository import Gtk 
except: 
    print("GTK Not Available") 
    sys.exit(1) 

Gtk.gdk.threads_init() 

這是我收到的錯誤。

AttributeError'gi.repository.Gtk」對象有沒有屬性 'GDK'

任何想法?

更新: 我下面這個教程http://faq.pygtk.org/index.py?req=show&file=faq14.023.htp 其同時使用GObject.threads_init()& Gtk.gdk.threads_init()。我沒有問題,但使用GObject但gdk。

+0

什麼是需要的PyGTK,然後忽略異常時,「規定」失敗的呢?你應該決定是否使用舊的pygtk或'gi.repository' – user4815162342

+0

這是我從一些教程中得到的。 gi.repository是我正在使用的。我曾嘗試pygtk和gi.repository,但他們都沒有gdk,我不明白爲什麼。我已經通過gtk文檔手冊,該gdk應該在那裏。 – Kin

+0

你在混淆舊的'pygtk' API,其中'import gtk'然後訪問'gtk。 '和'gtk.gdk。 '。這是你在評論中寫的[FAQ條目](http://faq.pygtk.org/index.py?req=show&file=faq14.023.htp)正在使用的內容。對於GTK3,不再維護pygtk綁定,並且其中一個應該切換到gobject-introspection。這是第二種風格(*不*在常見問題解答中提到,這是舊的PyGTK常見問題解答),從gi.repository import Gtk,Gdk',然後訪問'Gtk。 '和'Gdk。 '。 – user4815162342

回答

2

我覺得舊式gtk.gdk.threads_init()相當於是:

from gi.repository import Gdk 
Gdk.threads_init() 

然而,隨着FAQ warns,線程是不是一個乾淨的方式來實現這一目標。更好的方法是在GUI空閒時使用GObject.idle_add來運行一個函數。


"""Show a shell command's output in a gtk.TextView without freezing the UI""" 

import os 
import locale 
import subprocess 
import shlex 
import gi.repository.Gtk as gtk 
from gi.repository import GObject 
PIPE = subprocess.PIPE 

encoding = locale.getpreferredencoding() 


def utf8conv(x): 
    return unicode(x, encoding).encode('utf8') 


class MyWindow: 
    def __init__(self): 
     sw = gtk.ScrolledWindow() 
     sw.set_policy(gtk.PolicyType.AUTOMATIC, gtk.PolicyType.AUTOMATIC) 
     textview = gtk.TextView() 
     textbuffer = textview.get_buffer() 
     sw.add(textview) 
     win = gtk.Window() 
     win.resize(300, 500) 
     win.connect('delete-event', gtk.main_quit) 

     self.button_sim = gtk.Button(u"Press me!") 
     self.button_abort = gtk.Button("Abort") 
     self.button_quit = gtk.Button("Quit") 

     command = 'ls -R %s' % (os.getcwd(),) 
     self.button_sim.connect(
      "clicked", self.on_button_clicked, textview, textbuffer, command) 
     self.button_abort.connect("clicked", self.on_abort) 
     self.button_quit.connect("clicked", self.main_quit) 

     vbox = gtk.VBox() 
     vbox.pack_start(self.button_sim, expand=False, fill=False, padding=0) 
     vbox.pack_start(self.button_abort, expand=False, fill=False, padding=0) 
     vbox.pack_start(self.button_quit, expand=False, fill=False, padding=0) 
     vbox.pack_start(sw, expand=True, fill=True, padding=0) 
     win.add(vbox) 
     win.show_all() 

    def read_output(self, view, buffer, command): 
     yield True # allow the UI to refresh 
     proc = subprocess.Popen(
      shlex.split(command), stderr=PIPE, stdout=PIPE) 
     while True: 
      if self.job_aborted: 
       print('user aborted') 
       proc.terminate() 
       break 

      try: 
       line = proc.stdout.readline() 
       if line: 
        it = buffer.get_end_iter() 
        buffer.place_cursor(it) 
        buffer.insert(it, utf8conv(line)) 
        view.scroll_to_mark(buffer.get_insert(), 0.1, 
             use_align=False, xalign=0.5, yalign=0.5) 

      except IOError: 
       pass 

      yield True 

     yield False 

    def on_button_clicked(self, button, view, buffer, command): 
     self.job_aborted = False 
     GObject.idle_add(self.read_output(view, buffer, command).next) 

    def on_abort(self, button): 
     self.job_aborted = True 

    def main_quit(self, obj): 
     self.job_aborted = True 
     gtk.main_quit() 


if __name__ == "__main__": 
    app = MyWindow() 
    gtk.main() 
+0

感謝您的回覆,我使用這個也沒有問題。我正在嘗試遵循本教程http://faq.pygtk.org/index.py?req=show&file=faq14.023.htp,它同時使用了GObject.threads_init()和 Gtk.gdk.threads_init() – Kin

+0

I曾嘗試從gi.repository導入Gdk Gdk.threads_init()以及。它運行沒有錯誤。但它就像不是線程。我的用戶界面繼續凍結,直到任務完成。我在想Gdk是否等於Gtk.gdk? – Kin