python - 多线程 GUI 编程需求说明

标签 python user-interface

我正在寻找对在图形应用程序中使用多线程的必要性的一个很好的解释。在下面的示例中使用了 Python,但问题不是特定于 Python 的,它可能适用于任何语言的图形编程的一般设计。

举个简单的例子。假设有一个应用程序对一组文件执行某种耗时的操作,并将其进度输出到控制台。假设此操作每个文件需要 2 秒,并且有 10 个文件要处理,分别称为 1.txt、2.txt、3.txt、... 10.txt。那么一个示例实现可能如下所示:

控制台

import time
def process(file):
    print 'processing {0}...'.format(file)
    time.sleep(2.0) #simulate slow operation

files = ['{0}.txt'.format(i) for i in range(1, 11)]
map(process, files)

控制台示例当然是单线程的并且可以很好地完成工作。现在,如果我们想添加图形进度条,单线程实现可能如下所示:

单线程图形用户界面

import time, gtk, gobject

def process(file):
    print 'processing {0}...'.format(file)
    time.sleep(2.0)

class MainWindow(gtk.Window):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.progress = gtk.ProgressBar()
        self.progress.set_fraction(0)
        self.add(self.progress)
        self.connect("destroy", gtk.main_quit)
        self.show_all()
        files = ['{0}.txt'.format(i) for i in range(1, 11)]
        gobject.timeout_add(100, self.submit, files, 0)

    def submit(self, files, i):
        process(files[i])
        self.progress.set_fraction((i + 1.0)/len(files))
        if i + 1 < len(files):
            gobject.idle_add(self.submit, files, i + 1)

win = MainWindow()
gtk.main()

这似乎工作正常,但是当你运行应用程序时,如果你尝试与应用程序交互,比如尝试调整窗口大小,它会卡住,并且只有在它被释放以处理挂起的 gui 时才每两秒响应一次事件。最后一个示例是多线程实现,并在整个执行过程中保持响应。

多线程图形用户界面

import time, gtk, gobject, threading

def process(file):
    print 'processing {0}...'.format(file)
    time.sleep(2.0)

class MainWindow(gtk.Window):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.progress = gtk.ProgressBar()
        self.progress.set_fraction(0)
        self.add(self.progress)
        self.connect("destroy", gtk.main_quit)
        self.show_all()
        files = ['{0}.txt'.format(i) for i in range(1, 11)]
        threading.Thread(target=self.submit, args=(files,)).start()

    def submit(self, files):
        for i, file in enumerate(files):
            process(file)
            gobject.idle_add(self.progress.set_fraction, (i + 1.0)/len(files))
            if not self.get_visible():
                return

gtk.gdk.threads_init()
win = MainWindow()
gtk.main()

在我看来,如果您的代码中有一个长时间运行的阻塞操作并且您想要一个响应式的图形用户界面,那么您必须使用多线程解决方案,这对我来说似乎非常清楚和合乎逻辑。没有其他办法解决它。是这样吗?我曾多次尝试向其他开发人员解释这一点,但许多人不理解或不同意。有人可以提供这个概念的解释,相关文章的链接,或者如果我的理解不正确请纠正我。

最佳答案

你的理解是正确的。如果应用程序不是多线程的,应用程序会等待每个操作完成。当您的应用程序是多线程时,您使用一个线程来处理 GUI 操作,另一个线程来处理文件。

我没有类似的文章或引用。如果您将线程视为人,可能会有所帮助,每个人都有自己的工作,并且每个人一次只能做一件事。

关于python - 多线程 GUI 编程需求说明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13343096/

相关文章:

python - 从源安装后,TensorFlow 无法加载运行时

python - Python 中的 Tkinter 初学者 : Functions with Inputs

python - 如何在 Django 管理中更改 "app name"?

python - Matplotlib-cpp : ImportError: No module named site

python - 如何使用python从文件中打印字典的值

matlab - 如何在 MATLAB 中编写 GUI?

user-interface - 静态 UI 与动态 UI

用于填充 NetBeans 中 JLabels 的应用程序元信息的 Java 静态类

android - 为对话框设置 "dim"颜色

python - Matplotlib basemap 海岸坐标