优雅地终止QThread内部的进程

时间:2018-01-29 12:37:24

标签: python-3.x qt robotframework python-multiprocessing qthread

TL; DR: 当从main(从python包导入:多处理)创建进程时,可以终止它并具有正常退出,即允许机器人脚本进行拆解。但是,在QThread中创建进程时,Robot脚本将立即停止而不允许拆解。

长篇故事: 我正在尝试修复硬件测试程序,测试人员使用Python3和QT进行GUI并运行RobotFramework测试脚本。为了运行机器人测试,创建QThread以防止GUI冻结,在QThread内部启动运行Robot Framework测试的进程。在测试有效的设备时,即没有失败的测试,Robot脚本正确运行。但是,当我尝试中止测试时,不允许优雅地关闭它,因为它似乎直接被杀死。清除:机器人测试退出但不运行拆解。如果我改为直接在“main”中创建运行Robot测试的进程,程序将在终止时正常退出。

我的问题是如何让QThread内的进程表现得一样?

我创建了一个最小的示例代码来显示正在发生的事情。有两个文件robotrunner.py和robottemplate.robot。如果我们将测试变量设置为1,我们将直接在main中创建进程,程序将在2秒后正常退出。如果我们将测试变量设置为2,则将在QThread内创建进程,同时终止测试将立即终止(不需要)。

Running the test cases, nr1 is desired and nr2 is undesired behaviour

robotrunner.py:

    import robot
import time
import time
import datetime
from multiprocessing import Process
from PyQt5.QtCore import QThread, pyqtSignal

class RobotExec(QThread):
    def __init__(self):
        QThread.__init__(self)
        self.p = None

    #Run QThread
    def run(self):
        self.p = Process(target=startRobot)
        print("p.start()")
        self.p.start()

    def stop(self):
        print("p.terminate")
        self.p.terminate()
        print("Waiting to join")
        self.p.join()
        print("joined")

def startRobot():
    print("Robot run")
    robot.run('robottemplate.robot', loglevel='INFO')

if __name__ == '__main__':
    test=2  #Choose between 1 and 2
    print(test)

    #nr1
    if test==1:
        p = Process(target=startRobot)
        print("p.start()")
        p.start()
        time.sleep(2)
        print("p.terminate")
        p.terminate()
        print("Waiting to join")
        p.join()
        print("joined")

    #nr2
    if test==2:
        robotExecutionThread = RobotExec()
        robotExecutionThread.start()
        time.sleep(1)
        robotExecutionThread.stop()
        time.sleep(6)

robottemplate.robot:

*** Settings ***
Suite Setup  Setup Sute
Suite Teardown  Teardown Suite

*** Variables ***

*** Keywords ***

wait for server
    [arguments]  ${host}  ${port}  ${timeout}=30
    wait until keyword succeeds  ${timeout} seconds  1 second  TCP server is alive  host=${host}  port=${port}

Setup Sute
    Log To Console    Setup Sute

Teardown Suite
    Log To Console    Teardown Suite
    Sleep    1s
    Log To Console    Tore down the suit

*** Test Cases ***
Test PC
    [Tags]    RevPC
    Log To Console    RevPC
    Sleep    1s

Test PC and PD
    [Tags]    RevPC    RevPD
    Log To Console    PC and PD
    Sleep    1s

Test PD
    [Tags]    RevPD
    Log To Console    RevPD
    Sleep    1s

Test PD and PE
    [Tags]    RevPD    RevPE
    Log To Console    PD and PE
    Sleep    1s

Test PE
    [Tags]    RevPE
    Log To Console    RevPE
    Sleep    1s

Test that should always run
    [Tags]    All
    Log To Console    This test should always run

0 个答案:

没有答案