2013-03-31 1 views
4

J'essaye de créer un filetage multiple avec GTK. Gtk.gdk est nécessaire mais j'ai reçu une erreur concernant l'absence d'attribut gdk. J'utilise un Raspberry Pi avec Raspbian.L'objet 'gi.repository.Gtk' n'a pas d'attribut 'gdk'

Voici comment j'importe la bibliothèque 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() 

et c'est l'erreur que j'ai reçue.

AttributeError'gi.repository.Gtk » objet n'a pas d'attribut 'gdk'

Toute idée?

Mises à jour: Je suis ce tutoriel http://faq.pygtk.org/index.py?req=show&file=faq14.023.htp qui utilisent à la fois GObject.threads_init() & Gtk.gdk.threads_init(). Je n'ai aucun problème en utilisant GObject mais gdk.

+0

quel est le point d'exiger pygtk et en ignorant l'exception lorsque "besoin" échoue? vous devriez décider si vous utilisez le vieux pygtk ou 'gi.repository' – user4815162342

+0

C'est ce que je reçois de certains tutoriels. gi.repository est celui que j'utilise. J'avais essayé à la fois pygtk et gi.repository mais les deux n'ont pas de gdk, ce que je ne comprends pas pourquoi. J'ai passé en revue le manuel de documentation de gtk, lequel gdk devrait être là. – Kin

+0

Vous confondez l'ancienne API 'pygtk' où l'on devrait' importer gtk' et ensuite accéder 'gtk. 'et' gtk.gdk. '. C'est ce que [l'entrée FAQ] (http://faq.pygtk.org/index.py?req=show&file=faq14.023.htp) que vous avez écrit dans le commentaire utilise. Pour GTK3, les liaisons pygtk ne sont plus maintenues et l'on est supposé passer à l'introspection gobject. C'est le 2ème style (* pas * mentionné dans la FAQ, qui est l'ancienne FAQ de PyGTK), 'de gi.repository importer Gtk, Gdk' et ensuite accéder' Gtk. 'et' Gdk. '. – user4815162342

Répondre

2

Je pense que l'équivalent de l'ancien style gtk.gdk.threads_init() est:

from gi.repository import Gdk 
Gdk.threads_init() 

Cependant, comme le FAQ warns, le filetage est pas un moyen propre pour atteindre cet objectif. Une meilleure façon est d'utiliser GObject.idle_add pour exécuter une fonction à chaque fois que l'interface graphique est inactive.


"""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

Merci pour votre réponse, je l'utilise aussi sans problème. J'essaie de suivre ce tutoriel http://faq.pygtk.org/index.py?req=show&file=faq14.023.htp qui utilisait à la fois GObject.threads_init() & Gtk.gdk.threads_init() – Kin

+0

I avait essayé de gi.repository importer Gdk Gdk.threads_init() aswell. Il fonctionne sans erreur. Cependant, c'est comme ne pas enfiler. Mon interface utilisateur continue de geler jusqu'à ce que la tâche se termine. Ce que je pense est Gdk égal à Gtk.gdk? – Kin