0

我已经看到很多关于在子进程或线程中运行代码的东西,并且使用multiprocessingandthreading模块真的很容易。但是,在 GUI 中执行此操作会增加额外的复杂性。

据我了解,如果您尝试从多个线程(或进程)操作它们,GUI 类不喜欢它。解决方法是将数据从您创建的任何线程发送到负责图形的线程,然后在那里渲染。

不幸的是,对于我想到的场景,这不是一个选项:我创建的 gui 允许用户编写自己的绘图代码,然后执行。这意味着我无法控制它们的精确绘图方式,我也不想拥有它。(更新:这些图显示在单独的窗口中,不需要嵌入到主 GUI 中的任何位置。我希望它们与主 GUI 分开存在,而不共享任何底层图形库堆栈。)

所以我现在想知道的是

是否有一些干净(ish)的方式在一个全新的解释器实例中执行一串python代码,并与窗口系统有自己的联系?


回应评论:

当前应用程序设置如下: 一个简单的 python 脚本加载一个 wxPython gui(一个 wx.App)。使用此 gui 用户可以设置模拟,其中一部分涉及在普通 python 中创建一个脚本,该脚本运行模拟并对结果进行后处理(这通常涉及绘制和显示它们)。目前我通过简单地在脚本代码上调用 exec() 来做到这一点。这工作正常,但在模拟运行时 gui 冻结。我已经尝试在子进程中运行嵌入式脚本,它也可以正常工作,直到您尝试显示创建的图形(通常使用 matplotlib 的 show())。此时,wxPython、wx、gtk 等堆栈深处的某个库开始抱怨,因为您无法从多个线程操作它。我想要的设置to have 大致相同,但不是嵌入式脚本与主应用程序共享 GUI,而是希望它在自己的环境中显示图形。

只是为了澄清:

不是关于“我如何进行多线程/多处理”甚至“我如何在单个 wxpython gui 中进行多线程/多处理”的问题。问题是如何加载全新gui 的 gui 启动脚本。如何让窗口管理器将此脚本视为一个完全独立的应用程序?

最简单的方法是在某个临时文件夹中生成它,然后对 python 解释器进行非阻塞调用,但这会使通信更加困难,并且很难知道何时可以再次删除临时文件。我希望有一种更清洁、更动态的方式来做到这一点。

4

4 回答 4

1

在 Windows 上,您可以使用来自另一个进程的父窗口创建窗口,并绘制到该窗口。请参阅CreateWindowEx的 hWndParent 参数。

如果 wxWindows 支持明确地获取/设置,那么你应该很高兴。根据您的平台,在任何 Windows 系统中都可能出现类似的情况。

因此,只要让您的用户能够找到您的应用程序窗口的句柄,就应该让他们可以选择在您的应用程序中嵌入的视图上进行绘图,同时在他们自己的进程中运行。

于 2012-08-24T08:49:41.657 回答
1

我对 wx 没有太多了解,我使用 jython(用 java 实现的 python,你可以使用 java)和 swing。Swing 有自己的工作线程,如果您进行 gui 更新,您可以将代码包装到可运行文件中并使用swing.invokelater.

你可以看看 wx 是否有类似的东西,但是如果你只被允许从你创建它的线程中操作 gui 尝试类似的东西。为您的 gui 创建一个代理对象,它将您的所有调用转发到您的线程,该线程将它们转发到 gui。

但是像这样的代理会变得一团糟。你让他们用'updateGui'函数定义类怎么样,他们应该通过队列交还给你,你将在你的gui线程中执行。

于 2012-08-24T09:35:01.237 回答
1

你可以简单地使用子进程来运行'python.exe'并将脚本输入管道吗?

或者,如果您想将一些(可腌制的)数据移动到运行脚本的新进程中,那么multiprocessing包就足够了。只需创建一个运行脚本的函数/可调用对象,然后创建一个以可调用对象为目标的Process对象。这样,您应该能够传递一些数据,而不会出现 GUI 问题。

使用任何一种捕获文本都很容易,子进程允许这样做,仅此而已。使用多进程,您可以更轻松地来回传递 python 对象。

于 2012-08-24T09:46:30.430 回答
1

在 wxPython 领域中,当您使用线程时,您必须使用它的线程安全方法与 GUI 进行通信:wx.CallAfter、wx.CallLater 或 wx.PostEvent。在您的情况下,我将在单独的线程/进程中运行任何长时间运行的代码,并在完成处理后将结果发送到 GUI。GUI 可以实例化一个新框架并使用 matplotlib 或 PyPlot 来显示绘图,具体取决于您要走的路。我听说您也可以使用 FloatCanvas 绘制情节。

无论如何,如果您正确实例化新帧,那么您可以实例化 N 帧并显示它们并没问题。请参阅 wxPython wiki,了解一些使用 wx 线程的示例:http ://wiki.wxpython.org/LongRunningTasks

于 2012-08-24T13:45:17.977 回答