简体   繁体   English

PyQt5,如何重新启动通过线程运行的操作

[英]PyQt5, how to restart operations running through threads

So I have been trying to create a GUI which works on multiple threads to perform each operation. 因此,我一直试图创建一个可在多个线程上执行每个操作的GUI。 Each operation actually has loops running on it and so I decided to use threads to run each operation simultaneously. 每个操作实际上都有运行的循环,因此我决定使用线程来同时运行每个操作。

Here's some piece of code which describes the work flow. 这是一些描述工作流程的代码。

Below there's a function called cvfeed1 which starts a thread when a button is pressed on the GUI using ( self.pushButton_3.clicked.connect(self.cvfeed1) ). 下面是一个名为cvfeed1的函数,该函数使用(self.pushButton_3.clicked.connect(self.cvfeed1))在GUI上按下按钮时启动线程。 When the threads starts it calls a function called colour_detect. 线程启动时,它将调用一个名为colour_detect的函数。 The problem that I am facing is that I can only use this thread once, ie I can only click the button once. 我面临的问题是我只能使用一次该线程,即只能单击一次按钮。 When the operation in the functions is finished and I click the button again, the program crashes. 功能中的操作完成后,再次单击该按钮,程序将崩溃。 What do I need to do to again make the thread work? 我需要怎么做才能再次使线程正常工作?

class MyWindowClass(QMainWindow, form_class):
    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)
        self.setupUi(self)

        self.startButton.clicked.connect(self.start_clicked)
        self.pushButton.clicked.connect(self.printer)

        # Here is the command when the button is clicked.

        self.pushButton_3.clicked.connect(self.cvfeed1)

        self.window_width = self.ImgWidget.frameSize().width()
        self.window_height = self.ImgWidget.frameSize().height()
        self.ImgWidget = OwnImageWidget(self.ImgWidget)       

        self.timer = QtCore.QTimer(self)
        self.timer.timeout.connect(self.update_frame)
        self.timer.start(1)

    # This function starts the detect_1_thread

    def cvfeed1(self):

        detect_1_thread.start()
        #self.pushButton_3.setEnabled(False)

    def printer(self):
        global running1
        running1=True
        printer_thread.start()

    def start_clicked(self):
        global running
        running = True
        capture_thread.start()
        self.startButton.setEnabled(False)
        self.startButton.setText('Starting...')


    def update_frame(self):
        if not q.empty():
            self.startButton.setText('Camera is live')
            frame = q.get()
            img = frame["img"]

            img_height, img_width, img_colors = img.shape
            scale_w = float(self.window_width) / float(img_width)
            scale_h = float(self.window_height) / float(img_height)
            scale = min([scale_w, scale_h])

            if scale == 0:
                scale = 1

            img = cv2.resize(img, None, fx=scale, fy=scale, interpolation = cv2.INTER_CUBIC)
            img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
            height, width, bpc = img.shape
            bpl = bpc * width
            image = QtGui.QImage(img.data, width, height, bpl, QtGui.QImage.Format_RGB888)
            self.ImgWidget.setImage(image)

    def closeEvent(self, event):
        global running
        running = False



capture_thread = threading.Thread(target=grab, args = (0, q, 1920, 1080, 30))
printer_thread = threading.Thread(target=printx)
detect_1_thread=threading.Thread(target=colour_detect)

app = QApplication(sys.argv)
w = MyWindowClass(None)
w.setWindowTitle('GUI')
w.show()
app.exec_()

You can't start a thread more than once: it's an action, not a machine that can be (re)used by another agent. 您最多只能启动一个线程:这是一个动作,而不是可以由另一个代理(重新)使用的机器。 You could start another thread using the same function, but without synchronization with the first thread you could end up with two running at once, which is probably a bad thing. 您可以使用相同的功能启动另一个线程,但是如果不与第一个线程同步,则可能导致两个线程同时运行,这可能是一件坏事。

If you're going to synchronize, you might as well keep the one thread running indefinitely and just post requests for it to process on some appropriate schedule. 如果要进行同步,则最好使一个线程无限期地运行,然后只发布请求以使其按适当的时间表进行处理。 That schedule might allow preempting the current operation, or might allow only one request queued behind the current one, or whatever else. 该计划可能会抢占当前操作,或者可能只允许一个请求排在当前请求之后,或者其他任何原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM