在 PyGTK 中,如何使用线程?

发布于 2024-11-06 18:40:35 字数 283 浏览 2 评论 0原文

我有一个使用 gtk 绘制 GUI 的类。

单击按钮将调用一个方法,该方法将运行一些外部 程序。

但 GUI 可能不会同时重绘。

一种解决方案可能是使用线程。此示例创建一个线程 在 GUI 类之外并在调用 gtk.main() 之前启动它。

如何使 GUI 类外部的线程检测按钮单击事件并调用 合适的方法?

I have a class that draws a GUI, using gtk.

Clicking a button will call a method that will run some external
programs.

But the GUI may not redraw in the meantime.

One solution may be to use threads. This example creates a thread
outside the GUI class and starts it before calling gtk.main().

How do I make a thread outside the GUI class detect a button click event and call the
appropriate method?

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

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

发布评论

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

评论(1

紅太極 2024-11-13 18:40:35

你不需要另一个线程来启动外部程序,你可以使用 Gtk 的空闲循环。这是我为此编写的一些程序。它必须读取程序的标准输出才能在 GUI 上显示它的部分内容,所以我把它留在那里。变量“job_aborted”与“中止”按钮相关联,允许提前终止。

class MyWindow ...

    # here's the button's callback
    def on_simulate(self, button):
      self.job_aborted = False
      args = self.makeargs()  # returns a list of command-line args, first is program
      gobject.idle_add(self.job_monitor(args).next)


    def job_monitor(self, args):
       self.state_running()  # disable some window controls
       yield True  # allow the UI to refresh

       # set non-block stdout from the child process
       p  = subprocess.Popen(args, stdout=subprocess.PIPE)
       fd = p.stdout.fileno()
       fl = fcntl.fcntl(fd, fcntl.F_GETFL)
       fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)

       while True:

         if self.job_aborted:
           os.kill(p.pid, signal.SIGTERM)
           break

         poll = p.poll()
         if poll is not None:
           break

         try:
           line = p.stdout.readline()
           if line:
              line = line.strip()
              # update display

         except IOError:
           pass

         yield True

       self.state_ready()  # re-enable controls
       if self.job_aborted:
         # user aborted
       else:
         # success!

You don't need another thread to launch an external program, you can use Gtk's idle loop. Here's some pieces of program I wrote to do just that. It had to read the stdout of the program to show parts of it on the GUI as well, so I left that in there. The variable "job_aborted" is tied to an "Abort" button, that allows for early termination.

class MyWindow ...

    # here's the button's callback
    def on_simulate(self, button):
      self.job_aborted = False
      args = self.makeargs()  # returns a list of command-line args, first is program
      gobject.idle_add(self.job_monitor(args).next)


    def job_monitor(self, args):
       self.state_running()  # disable some window controls
       yield True  # allow the UI to refresh

       # set non-block stdout from the child process
       p  = subprocess.Popen(args, stdout=subprocess.PIPE)
       fd = p.stdout.fileno()
       fl = fcntl.fcntl(fd, fcntl.F_GETFL)
       fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)

       while True:

         if self.job_aborted:
           os.kill(p.pid, signal.SIGTERM)
           break

         poll = p.poll()
         if poll is not None:
           break

         try:
           line = p.stdout.readline()
           if line:
              line = line.strip()
              # update display

         except IOError:
           pass

         yield True

       self.state_ready()  # re-enable controls
       if self.job_aborted:
         # user aborted
       else:
         # success!
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文