使用 john zelles 图形模块 (Python) 时的多线程

问题描述 投票:0回答:1

我已经使用 John Zelle 图形模块有一段时间了,但这是我第一次尝试使用线程模块。我试图使具有不同起始位置的多个对象(圆圈)同时沿屏幕移动。该代码还将在其最终产品中包含递归和跳转到多个函数。

这是我正在尝试做的一个例子:

from graphics import *
from random import randint
import time
import threading

class Particle:
    
    def __init__(self):
        self.xpos   = randint(0,50)
        self.ypos   = randint(0,50)
        
        self.graphic = Circle(Point(self.xpos,self.ypos),5)    
        self.graphic.draw(window)
        
    def move(self):
        for step in range(5):
            self.xpos += 1
            self.ypos += 1
            self.graphic.move(self.xpos,self.ypos)
            time.sleep(0.5)
            
window = GraphWin("window",500,500)

threading.Thread(target=Particle()).start()
threading.Thread(target=Particle()).start()

尝试使用线程进行不同尝试后,我继续收到两个不同的错误。

这个(来自上面的代码):

Exception in thread Thread-1:
Traceback (most recent call last):
Thread-2  File "/usr/lib/python3.11/threading.py", line 1038, in _bootstrap_inner
:
    Traceback (most recent call last):
  File "/usr/lib/python3.11/threading.py", line 1038, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.11/threading.py", line 975, in run
    self._target(*self._args, **self._kwargs)
TypeError: 'Particle' object is not callable
self.run()
  File "/usr/lib/python3.11/threading.py", line 975, in run
    self._target(*self._args, **self._kwargs)
TypeError: 'Particle' object is not callable

还有:

"RuntimeError: main thread is not in main loop"

我尝试了来自堆栈溢出和其他网站的许多建议,例如:

  • 将我的线程设置为“daemon = True”
  • 使用 'plt.switch_backend('agg')'
  • 制作一个单独的线程类
  • 给我的线程一个句柄,然后在该句柄上使用 .start

注意:如果您确定这些方法应该有效,请告诉我应该如何完成,我是使用线程模块的新手。

感谢您的帮助!

python multithreading oop graphics zelle-graphics
1个回答
0
投票

我尝试了你的代码,它需要一些修复:

  • 在 threading.Thread target 中,您在接受方法时直接传递类实例
  • 您可以将
    Particle.__init__()
    Particle().move()
    作为操作传递
  • 或者您可以使用
    particle1 = Particle()
    类创建对象,然后使用它的方法,例如
    target=particle1.move()
  • 如果您使用 daemon=True ,则意味着新创建的线程将在后台运行,主线程不必等到它完成其进程
  • 如果你像
    thread1.join()
    一样在线程实例上调用join(),主线程将等待,直到该特定线程完成其目标操作(在这种情况下daemon = True或False并不重要)

这里我给你一些正确的代码版本:

# ... same other code

threading.Thread(target=Particle().__init__()).start()
threading.Thread(target=Particle().__init__()).start()

# ... same other code

threading.Thread(target=Particle().move()).start()
threading.Thread(target=Particle().move()).start()

# ... same other code

particle1 = Particle()
particle2 = Particle()

threading.Thread(target=particle1.move()).start()
threading.Thread(target=particle2.move()).start()

# ... same upper code

particle1 = Particle()
particle2 = Particle()

thread1 = threading.Thread(target=particle1.move()).start()
thread2 = threading.Thread(target=particle2.move()).start()

thread1.join()
thread2.join()

在最后一个片段中,您的窗口将打开,直到您的移动函数完成执行或您手动关闭它。

如果您想深入了解 Pytohn 线程,请查看本指南:https://superfastpython.com/threading-in-python/

© www.soinside.com 2019 - 2024. All rights reserved.