Как изменить текстовое представление из другого процесса? - PullRequest
1 голос
/ 14 февраля 2012

Так что я делаю графический интерфейс для получения твитов. Я сделал окно события, которое будет принимать сигнал и изменять текстовое представление. Я использую многопроцессорность, чтобы изменить текстовое представление, но оно просто не меняется. Я даже пытался изменить размер окна. Но ничего не меняется. Я могу получить текстовый буфер textview, но не могу изменить его.

import pygtk
pygtk.require('2.0')
import gtk
from multiprocessing import Process

class multi:
    def __init__(self):
        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.window.set_size_request(800,400)
        self.window.set_title("Twitter Box")
        self.window.set_border_width(4)
        self.window.connect("destroy", self.close_application)

        self.vbox1 = gtk.EventBox()
        self.vbox1.set_size_request(750,450)
        self.vbox1.connect('leave_notify_event',self.go_multi)
        self.window.add(self.vbox1)
        self.vbox1.show()

        self.tweetview = gtk.TextView()
        self.tweetbuffer = self.tweetview.get_buffer()
        self.tweetbuffer.set_text('Why not working?')
        self.vbox1.add(self.tweetview)
        self.tweetview.show()

        self.window.show()

    def close_application(self, widget):
        gtk.main_quit()

    def go_multi(self, widget, data=None):
        p = Process(target = self.change_textview)
        p.start()
        p.join()

    def change_textview(self):
        print 'changing text'
        startiter = self.tweetbuffer.get_start_iter()
        enditer = self.tweetbuffer.get_end_iter()
        text = self.tweetbuffer.get_text(startiter, enditer)
        print text
        if text:
            self.tweetbuffer.set_text('Changed....')
        else:
            self.tweetbuffer.set_text('')
        return 

def main():
    multi()
    gtk.main()

if __name__ == '__main__':
    main()

Я создаю графический интерфейс для получения твитов. Иногда для получения временной шкалы требуется очень много времени из-за медленного соединения и зависания графического интерфейса. Итак, я хотел сделать так, чтобы он создавал процесс и получал временную шкалу и устанавливал твитбуфер. Но я не могу установить текст в твиттере.

Ответы [ 3 ]

2 голосов
/ 14 февраля 2012

Я не совсем понимаю, почему вы делаете это:

def go_multi(self, widget, data=None):
    p = Process(target = self.change_textview)
    p.start()
    p.join()

, потому что даже при удаленной возможности, в которой он должен работать, вы в основном вызываете функцию change_textview и ждетепроцесс завершен.

Снято, я не думаю, что вам вообще нужна многопроцессорная обработка, вместо этого сделайте многопоточность графического интерфейса.

Создать многопоточность Gtk может быть немного сложно, но этоне сложная задача.
У вас есть два способа сделать это:

  1. Обновите ваш виджет, используя GLib.idle_add (или GObject.idle_add, я никогда не до конца понимаю, почему иногда они не совпадают)
  2. Или следуйте объяснениям [здесь] .На что он в основном говорит:

    • Вызовите следующие методы перед вызовом Gtk.main():

       GObject.threads_init()
       Gdk.threads_init()
      
    • В вашей теме окружитекод, который обновляет виджеты Gtk:

       Gdk.threads_enter()
       # your code here
       Gdk.threads_leave()
      
2 голосов
/ 14 февраля 2012

Вы должны запустить основной цикл для обработки событий рендеринга, прежде чем что-либо станет видимым.

Кроме того, нельзя вызывать функции GTK из второго потока.

Прочтите это, чтобы начать: Многопоточные приложения GTK - Часть 1. Заблуждения

А вот как применить эти знания к PyGTK: Потоки на PyGTK

0 голосов
/ 14 февраля 2012

Если вы все еще хотите продолжать в том же духе после всех ответов: Отказ от ответственности: Понятия не имею, насколько полезен этот ответ. Пояснение: Я пытался использовать вашу логику.Я также импортировал Queue, чтобы разделить некоторые данные между процессами.Я думаю, что это было необходимо, как я видел из документации .Вы можете найти другую информацию в примере кода ниже.

import pygtk
pygtk.require('2.0')
import gtk
from multiprocessing import Process, Queue

class multi:
    def __init__(self):
        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.window.set_size_request(800,400)
        self.window.set_title("Twitter Box")
        self.window.set_border_width(4)
        self.window.connect("destroy", self.close_application)

        self.vbox1 = gtk.EventBox()
        self.vbox1.set_size_request(750,450)
        self.vbox1.connect('leave_notify_event',self.go_multi)
        self.window.add(self.vbox1)
        self.vbox1.show()
        self.tweetview = gtk.TextView()
        self.tweetbuffer = self.tweetview.get_buffer()
        self.tweetbuffer.set_text('Why not working?')
        self.vbox1.add(self.tweetview)
        self.tweetview.show()

        self.window.show()

    def close_application(self, widget):
        gtk.main_quit()

    def go_multi(self, widget, data=None):
        q = Queue()
        p = Process(target = self.change_textview, args=(q,))
        p.start()
        self.tweetbuffer.set_text(q.get())
        p.join()

    def change_textview(self, q):
        print 'changing text'
        startiter = self.tweetbuffer.get_start_iter()
        enditer = self.tweetbuffer.get_end_iter()
        text = self.tweetbuffer.get_text(startiter, enditer)
        print text
        if text:
            q.put(('Changed....'))
        else:
            q.put((''))
def main():
    multi()
    gtk.main()

if __name__ == '__main__':
    main()
...