Объект gi.repository.Gtk не имеет атрибута gdk.

Я пытаюсь создать многопоточность с помощью GTK. Gtk.gdk необходим, но я получил ошибку об отсутствии атрибута gdk. Я использую Raspberry Pi с Raspbian.

Вот как я импортирую библиотеку 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.


person Kin    schedule 31.03.2013    source источник
comment
какой смысл требовать pygtk, а затем игнорировать исключение, когда требование не выполняется? вам следует решить, используете ли вы старый pygtk или gi.repository   -  person user4815162342    schedule 31.03.2013
comment
Это то, что я получаю от некоторых учебников. gi.repository - это тот, который я использую. Я пробовал и pygtk, и gi.repository, но у обоих нет gdk, и я не понимаю, почему. Я просмотрел руководство по документации gtk, какой gdk там должен быть.   -  person Kin    schedule 31.03.2013
comment
Вы путаете старый pygtk API, где можно было import gtk, а затем получить доступ к gtk.<identifier> и gtk.gdk.<identifier>. Это то, что вы написали в часто задаваемых вопросах в комментарий используется. Для GTK3 привязки pygtk больше не поддерживаются, и предполагается переключиться на gobject-introspection. Это второй стиль (не упомянутый в FAQ, который является старым FAQ по PyGTK), from gi.repository import Gtk, Gdk, а затем доступ к Gtk.<identifier> и Gdk.<identifier>.   -  person user4815162342    schedule 31.03.2013
comment
Спасибо за ваше объяснение. Я пробовал с import gtk и gtk.<identifier>, но это похоже на отсутствие многопоточности. Мой пользовательский интерфейс будет продолжать зависать до тех пор, пока задача не завершится. Я едва мог найти какие-либо ссылки на gdk.<identifier> threading, все используют gtk.gdk.<identifier>. Что, если я надеюсь использовать gtk.gdk.<identifier>? импортировав старый pygtk?   -  person Kin    schedule 31.03.2013
comment
В этот момент становится очень трудно следить за вами. Может быть, вы могли бы опубликовать отдельный вопрос, описывающий проблему с потоками, которая у вас была? Что бы вы ни делали, вы не должны смешивать старый и новый синтаксис — выбирайте между import gtk и from gi.repository import Gtk и последовательно используйте его.   -  person user4815162342    schedule 31.03.2013


Ответы (2)


Я думаю, что эквивалент gtk.gdk.threads_init() в старом стиле:

from gi.repository import Gdk
Gdk.threads_init()

Однако, как предупреждает часто задаваемые вопросы, многопоточность не является чистый способ достижения этой цели. Гораздо лучше использовать 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()
person unutbu    schedule 31.03.2013
comment
Спасибо за ответ, я тоже пользуюсь без проблем. Я пытаюсь следовать этому руководству faq.pygtk.org/ index.py?req=show&file=faq14.023.htp, который использовал как GObject.threads_init(), так и Gtk.gdk.threads_init() - person Kin; 31.03.2013
comment
Я также пытался импортировать из gi.repository Gdk Gdk.threads_init(). Он работает без ошибок. однако это похоже на отсутствие потоков. Мой пользовательский интерфейс продолжает зависать, пока задача не завершится. Я думаю, что Gdk равен Gtk.gdk? - person Kin; 31.03.2013
comment
На самом деле у меня много ошибок AttributeError в разных частях, например AttributeError: 'gi.repository.Gtk' object has no attribute 'settings_get_for_screen'. Похоже, что gi.repository.Gtk имеет много отличий от стандартной gtk. Как это решить? - person Luis A. Florit; 25.05.2020

Поскольку вы используете gtk из gi.repository.Gtk, вы можете попытаться получить gdk аналогичным образом, но учтите, что его атрибут может отличаться от исходного gtk.gdk.

from gi.repository import Gdk as gdk
person biendltb    schedule 14.12.2020