如果最后一个线程完成,则创建新线程[Python 2.7]

如果最后一个线程完成,则创建新线程[Python 2.7],python,multithreading,qt,Python,Multithreading,Qt,我是Python线程的新手。基本上,我有一个用Python设计的基于QT的应用程序。应用程序有一个“跟随轨迹”按钮,每当我按下这个按钮,机器人就会开始移动。我注意到机器人并没有按照精确的轨迹运行 move命令被覆盖,机器人只接收到几个点。以下是按下按钮时执行的功能: def move_robot(self): # points is an array of point for point in points: start_new_thread(self.robo

我是Python线程的新手。基本上,我有一个用Python设计的基于QT的应用程序。应用程序有一个“跟随轨迹”按钮,每当我按下这个按钮,机器人就会开始移动。我注意到机器人并没有按照精确的轨迹运行

move
命令被覆盖,机器人只接收到几个点。以下是按下按钮时执行的功能:

def move_robot(self):
    # points is an array of point
    for point in points:
        start_new_thread(self.robot.move, (point,))
以下是控制器的
移动
功能:

def move(self, point):
    while True:
        self._robot_controller.move(point)
        current_location = self._robot_controller.location()
        if current_location - point < 0.0001:
            break
def移动(自身,点):
尽管如此:
自动机器人控制器移动(点)
当前位置=自。\机器人\控制器。位置()
如果当前位置-点<0.0001:
打破
我的问题是,如何仅在最后一个线程完成时创建新线程?

以下是完整的代码:

class RobotControllerWrapper():
    def __init__(self):
        self._robot_controller = RobotController()

    def move(self, point):
        while True:
            self._robot_controller.move(point)
            current_location = self._robot_controller.location()
            if current_location - point < 0.0001:
                break

from thread import start_new_thread
from qt_gui.plugin import Plugin
from python_qt_binding.QtGui import QWidget, QPushButton

class MyPlugin(Plugin):
    def __init__(self, context):

        super(MyPlugin, self).__init__(context)
        self.setObjectName('MyPlugin')

        self._widget = QWidget()
        self._vertical_layout = QVBoxLayout()
        self._move_robot_button = QPushButton('Follow Trajectory')
        self._move_robot_button.clicked.connect(self.move_robot)
        self._vertical_layout.addWidget(self._move_robot_button)
        self._widget.setLayout(self._vertical_layout)
        self._widget.setObjectName('MyPluginUi')

        if context.serial_number() > 1:
            self._widget.setWindowTitle(self._widget.windowTitle() + (' (%d)' % context.serial_number()))
        context.add_widget(self._widget)

        self.robot = RobotControllerWrapper()

    def move_robot(self):
        # points is an array of point
        for point in points:
            start_new_thread(self.robot.move, (point,))
class RobotControllerRapper():
定义初始化(自):
self.\u robot\u controller=机器人控制器()
def移动(自身,点):
尽管如此:
自动机器人控制器移动(点)
当前位置=自。\机器人\控制器。位置()
如果当前位置-点<0.0001:
打破
从线程导入开始新线程
从qt_gui.plugin导入插件
从python_qt_binding.QtGui导入QWidget,QPushButton
类MyPlugin(插件):
定义初始化(自身,上下文):
超级(MyPlugin,self)。\uuuuu init\uuuuu(上下文)
self.setObjectName('MyPlugin')
self.\u widget=QWidget()
self._vertical_layout=QVBoxLayout()
自身移动机器人按钮=QPushButton(“跟随轨迹”)
self.\u move\u robot\u按钮。单击。连接(self.move\u robot)
self.\u垂直\u布局.addWidget(self.\u移动\u机器人\u按钮)
self.\u widget.setLayout(self.\u垂直布局)
self.\u widget.setObjectName('MyPluginUi')
如果context.serial_number()大于1:
self.\u widget.setWindowTitle(self.\u widget.windowTitle()+(“(%d)”%context.serial\u number())
context.add_小部件(self._小部件)
self.robot=robotcontrollerrapper()
def移动机器人(自身):
#点是点的数组
对于点到点:
启动新线程(self.robot.move,(point,))

为这篇冗长的文章道歉。非常感谢。

根据您的评论,您需要为
move\u robot
创建一个新线程:

def move_robot(self):
    # points is an array of point
    def move_robot_thread(points):
        for point in points:
            thread = start_new_thread(self.robot.move, (point,))
            thread.join()
    start_new_thread(move_robot_thread, (points,))
顺便说一句,我假设
start\u new\u thread
返回
thread
对象

更新
这是给你的。我还没有测试,但它应该可以工作。

在methode move robot的定义中,您应该添加一个“线程控制器”,在启动新线程之前检查上一个运行的线程是否结束。 这可能是一个很好的教程

特别是该方法:

if last_thread.isAlive() ==  False:
    new_thread = start_new_thread(self.robot.move, (point,))

您介意在
移动机器人
中的
循环中阻塞
吗?您可以使用
join
。否则,您需要为此
for
循环创建一个新线程。@Sraw:我认为如果我在主应用程序中阻止
for
循环,GUI将没有响应。非常感谢。我现在不能测试你的代码。但您确定这样做不会影响UI吗?我不想让UI在时间机器人移动时有响应。非常感谢。该线程是根据此
从线程导入开始\u新建\u线程创建的
。如何在上面建议的代码中使用
线程
包?非常感谢<代码>导入错误:无法导入名称开始\新线程
。我认为这应该是
从线程导入开始\u new\u thread
。但是我想知道一起使用
thread
threading
包是否是一种好的做法。
if last_thread.isAlive() ==  False:
    new_thread = start_new_thread(self.robot.move, (point,))