我覺得舊式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()
什麼是需要的PyGTK,然後忽略異常時,「規定」失敗的呢?你應該決定是否使用舊的pygtk或'gi.repository' – user4815162342
這是我從一些教程中得到的。 gi.repository是我正在使用的。我曾嘗試pygtk和gi.repository,但他們都沒有gdk,我不明白爲什麼。我已經通過gtk文檔手冊,該gdk應該在那裏。 – Kin
你在混淆舊的'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