如何从不同的进程修改文本视图?

发布于 2025-01-05 03:02:29 字数 1750 浏览 1 评论 0原文

所以我正在制作一个 GUI 来获取推文。我制作了一个事件框,它将接收信号并更改文本视图。 我正在使用多重处理来更改文本视图,但它只是没有改变。我什至尝试改变窗口的大小。但一切都没有改变。我可以获取文本视图的文本缓冲区,但无法更改它。

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()

我正在制作 GUI 来获取推文。有时,由于连接速度慢并且 GUI 冻结,检索时间线需要很长时间。所以,我想让它创建一个进程,它将获取时间线并设置tweetbuffer。但我无法在 tweetbuffer 中设置文本。

So I am making a GUI to get tweets. I have made an event box which would take the signal and change the textview.
I am using multiprocessing to change the textview, but it just doesn't change. I even tried changing the size of the window. But nothing changes. I can get textbuffer of the textview but can not change it.

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()

I am making GUI to get tweets. Sometimes it takes really long to retrieve timeline due to slow connectivity and the GUI freezes. So, I wanted to make it such that, it would create a process and it will fetch the timeline and set tweetbuffer. But I am unable to set text in tweetbuffer.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

筱果果 2025-01-12 03:02:29

我不完全理解你为什么这样做:

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

因为,即使在它应该工作的远程可能性中,你基本上也是在调用 change_textview 函数并等待该过程完成。

清除了这个,我认为你根本不需要多处理,而是让你的 gui 多线程。

制作一个 Gtk 多线程一开始可能有点棘手,但这并不是一项困难的任务。
您有两种方法可以做到这一点:

  1. 使用 GLib.idle_add 更新您的小部件(或 GObject.idle_add,我从来没有完全理解为什么有时它们不一样)
  2. 或者按照[此处]的说明进行操作。它基本上是说:

    • 在调用Gtk.main()之前调用以下方法:

      <前><代码> GObject.threads_init()
      Gdk.threads_init()

    • 在您的线程中,将更新 Gtk 小部件的代码括起来:

      <前><代码> Gdk.threads_enter()
      # 这里是你的代码
      Gdk.threads_leave()

I don't fully inderstand why you do this:

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

because, even in the remote possibility in which it should work, you're basically calling the change_textview function and waiting for the process to finish.

Cleared this, I don't think you need multiprocessing at all, make your gui multithreading instead.

Make a Gtk multithread may be a little tricky at first, but it's not a difficult task.
You have two ways for doing so:

  1. Update your widget using GLib.idle_add (or GObject.idle_add, I never fully understand why sometimes they're not the same)
  2. Or follow what's explained [here]. Which it basically says to:

    • Call the following methods before you call Gtk.main():

       GObject.threads_init()
       Gdk.threads_init()
      
    • In your thread, surround the code that updates the Gtk widgets with:

       Gdk.threads_enter()
       # your code here
       Gdk.threads_leave()
      
赠意 2025-01-12 03:02:29

在任何内容变得可见之前,您必须运行主循环来处理渲染事件。

另外,您不得从第二个线程调用 GTK 函数。

阅读本文以帮助您入门:多线程 GTK 应用程序 – 第 1 部分:误解

下面是如何将这些知识应用到 PyGTK 中:PyGTK 上的线程

You must run the main loop to process the rendering events before anything becomes visible.

Also, you must not call GTK functions from a second thread.

Read this to get you started: Multi-threaded GTK applications – Part 1: Misconceptions

And here is how to apply this knowledge to PyGTK: Threads on PyGTK

孤单情人 2025-01-12 03:02:29

如果您在获得所有答案后仍想继续这样做:
免责声明:
我不知道这个答案有多大用处。
说明:
我试着用你的逻辑。我还导入了 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()

If you still want to continue on that way after all answers:
Disclaimer:
I have no idea how useful this answer.
Explanation:
I tried to use your logic. I also imported Queue to share some data between processes. I guess it was needed as I saw from documentation. You may find some other info in code sample below.

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()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文