PyQt5,如何通过线程重启操作运行
PyQt5, how to restart operations running through threads
所以我一直在尝试创建一个 GUI,它在多个线程上运行以执行每个操作。每个操作实际上都有循环 运行ning,所以我决定使用线程来同时 运行 每个操作。
下面是一段描述工作流程的代码。
下面有一个名为 cvfeed1 的函数,当使用 ( self.pushButton_3.clicked.connect(self.cvfeed1) ) 在 GUI 上按下按钮时,它会启动一个线程。当线程启动时,它会调用一个名为 colour_detect 的函数。我面临的问题是我只能使用该线程一次,即我只能单击一次按钮。当函数中的操作完成后,我再次点击按钮,程序崩溃了。我需要做什么才能再次使线程正常工作?
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_()
你不能多次启动一个线程:它是一个动作,而不是一台可以被另一个代理(重新)使用的机器。您可以使用相同的函数启动另一个线程,但如果不与第一个线程同步,您可能会同时得到两个 运行,这可能是一件坏事。
如果你要同步,你还不如无限期地保留一个线程 运行,只是 post 请求它按某个适当的时间表进行处理。该调度可能允许抢占当前操作,或者可能只允许一个请求在当前操作之后排队,或者其他任何请求。
所以我一直在尝试创建一个 GUI,它在多个线程上运行以执行每个操作。每个操作实际上都有循环 运行ning,所以我决定使用线程来同时 运行 每个操作。
下面是一段描述工作流程的代码。
下面有一个名为 cvfeed1 的函数,当使用 ( self.pushButton_3.clicked.connect(self.cvfeed1) ) 在 GUI 上按下按钮时,它会启动一个线程。当线程启动时,它会调用一个名为 colour_detect 的函数。我面临的问题是我只能使用该线程一次,即我只能单击一次按钮。当函数中的操作完成后,我再次点击按钮,程序崩溃了。我需要做什么才能再次使线程正常工作?
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_()
你不能多次启动一个线程:它是一个动作,而不是一台可以被另一个代理(重新)使用的机器。您可以使用相同的函数启动另一个线程,但如果不与第一个线程同步,您可能会同时得到两个 运行,这可能是一件坏事。
如果你要同步,你还不如无限期地保留一个线程 运行,只是 post 请求它按某个适当的时间表进行处理。该调度可能允许抢占当前操作,或者可能只允许一个请求在当前操作之后排队,或者其他任何请求。