gpt4 book ai didi

python - 使用线程控制 wxPython 中的 UI 元素

转载 作者:太空宇宙 更新时间:2023-11-04 06:14:48 24 4
gpt4 key购买 nike

我正在使用 Python/wxWidgets 编写一个简单的游戏。

我已经为主窗口编写了一个类,为另一个获取用户输入的框架编写了一个简单的类。

到目前为止,我的架构是应用程序启动并运行第二个线程,该线程运行一个名为“gameLogic”的函数。然后主线程进入主应用程序循环。

gameLogic线程顺序运行,需要控制UI。例如,它需要打开一个以主框架为父框架的新对话框。但是,我发现这样做最终会导致崩溃(严重到足以在 OS X 中弹出报告崩溃窗口)。

我一直在环顾四周,收集到我需要重构才能使用事件,但我不确定如何创建自己的事件。我可以让我的 gameLogic 线程在主窗口中引发一个事件,然后将调出输入对话框并等待输入(模态),然后将该数据返回给 gameLogic 线程。 gameLogic 线程可以在等待时阻塞,因为 UI 线程是独立的。

在我的主框架中的一个函数(事件处理程序)中,我可以创建一个输入对话框的新实例,以模态方式显示它,然后获取输入。

我已经看到了实现这个的各种想法,但一直没能找到一个很好的例子来说明如何在我的 wxFrame 对象中创建自定义事件并从另一个线程调用它,并且还没有逻辑线程阻塞并等待输入返回,然后如何将该输入返回给 gameThread。

非常感谢您的建议!

最佳答案

首先,困难的部分:

I've seen all sorts of ideas for implementing this but haven't been able to find a good example of how to create the custom event in my wxFrame object and call it from the other thread

an example of this right on the wxPyWiki .您可能还想查看指向 Working with wxPython in a separate thread 的链接.

不过,我觉得博文wxPython and Threads从老鼠大战。 Python 最好地解释了困难的部分。它还向您展示了执行此操作的更简单方法(使用 CallAfterPublisher 而不是发布自定义事件),但让我们坚持您询问的方式。

唯一缺少的部分是:

… and also to have the logic thread block and wait till input comes back, and then how to get that input back to gameThread.

但这并没有什么 wx-specific。很难将信息发送到 wx(或任何事件循环)的唯一原因是事件循环不能阻塞。您的逻辑线程可以阻塞,事实上应该。因此,任何正常的线程同步机制都可以。

因此,您有一个线程想要永远阻塞直到值准备好,而另一个线程希望能够在不阻塞的情况下发送该值。您可以使用 ConditionQueue 轻松完成此操作。后者在这里可能有点矫枉过正,但它更灵活,所以让我们这样做,只是为了好玩。

我将使用 Mouse 博客中的示例,并使其每次后台线程发布一个 EVT_RESULT 事件时,它都会阻塞,直到该事件被处理,并取回一个字符串,它可以……记录什么的,我想,它不是很有用,但我想展示它通过一些东西

from queue import Queue
# ...

class TestThread(Thread):
# ...
def run(self):
for i in range(6):
# ...
wx.PostEvent(self.wxObject, ResultEvent(amtOfTime)
result_from_gui = self.wxObject.q.get(True, None)
# ...

class MyForm(wx.Frame):
# ...
def __init__(self):
# ...
self.q = Queue()
# ...
def updateDisplay(self, msg):
# ...
t = msg.data
if isinstance(t, int):
text = "Time since thread started: %s seconds" % t
else:
text = "%s" % t
self.btn.Enable()
self.displayLbl.SetLabel(text)
self.q.put(text)

在此示例中,GUI 线程在updateDisplay 结束时执行self.q.put(text)。没有神奇的理由它必须在那里然后 - 只要它最终发生(并且恰好 1 次),逻辑线程将阻塞直到它发生。例如,updateDisplay 方法可以创建一个新按钮,并在用户单击它时发送 self.q.put(并删除该按钮)。

关于python - 使用线程控制 wxPython 中的 UI 元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16452517/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com