Venusвозможно но не факт, поскольку ХЗ что делает твой внешний модуль, это для нас тайна за семью печатями, то возможны проблемы изза GIL https://ru.wikipedia.org/wiki/Global_Interpreter_Lock
по приведённым вам примерам по ссылке думаю этот нужен(незнаю как его впихнуть в деф старт)
НО в принципе это решает multiprocessing благо его методы о многом повторяют threading, и смена не соствит труда.
Venusкак откуда это просто пример, создаються два потока “с” и “b”. “b” выполняеться “демоном” тоесть даже после завершения основного скрипта он продолжит работу. А “с” мы ждем когда он закончит свою работу и только тогда продолжаем выполнение основного потока.
и совсем непонятно что это(откуда переменные взялись)
Не обязательно наследовать от класса Thread, процесс\поток можно создать из процедуры\функкции
# import sys import time import threading try: from PyQt4 import QtGui except: from PyQt5 import QtWidgets as QtGui def ext_script(r, t, stop_event): # типа кагбэ внешний скрипт # надеюсь у тебя есь механиз выхода из бконечного цикла, иначе нужно его предусмотреть. # # Параметры: # r, t - просто какието параметры передаваемые в нпоток # stop_event - специальный ивент типа threading.Event для отсановки бесконечного цикла while not stop_event.is_set(): # выполнять бесконечный цикл пока stop_event = False # эмуляция какойто работы print('script run with params r={}, t={}'.format(r, t)) time.sleep(1) class MainWindow(QtGui.QWidget): def __init__(self, parent = None): super().__init__(parent = parent) self.seconary_thread = None # Атрибут класса для второго потока self.thread_stop_event = threading.Event() # сигнал для отсновки второго потока self.layout = QtGui.QGridLayout(self) # r self.r_label = QtGui.QLabel(self, text = 'r:') self.r = QtGui.QSpinBox(self) # Создаем спинбокс self.r.setObjectName('r') # Устанавлваем имя виджета, чтобы понимать кто отправитель события self.r.setRange(1, 10) self.r.setSingleStep(1) self.layout.addWidget(self.r_label, 0, 0) self.layout.addWidget(self.r, 0, 1) # t self.t_label = QtGui.QLabel(self, text = 't:') self.t = QtGui.QSpinBox(self) # Создаем спинбокс self.t.setObjectName('t') # Устанавлваем имя виджета, чтобы понимать кто отправитель события self.t.setRange(1, 10) self.t.setSingleStep(1) self.layout.addWidget(self.t_label, 1, 0) self.layout.addWidget(self.t, 1, 1) self.t.installEventFilter(self) # Кнопка старт self.start_btn = QtGui.QPushButton(self, text = 'START') self.layout.addWidget(self.start_btn, 2, 0) self.start_btn.clicked.connect(self.start_act) # Кнопка стоп self.stop_btn = QtGui.QPushButton(self, text = 'STOP!') self.layout.addWidget(self.stop_btn, 2, 1) self.stop_btn.clicked.connect(self.stop_act) self.show() def start_act(self): if not self.seconary_thread or not self.seconary_thread.is_alive(): # Если поток еще не существует или он не живой r = self.get_r() # получаем r t = self.get_t() # получаем t self.thread_stop_event.clear() # Устанавливаем сигнал в False self.seconary_thread = threading.Thread(target= ext_script, args = (r, t, self.thread_stop_event)) # Создаем поток из функции target= ext_script # м передаем ей аргументы args = (r, t, self.thread_stop_event) self.seconary_thread.start() # запускаем поток else: # если поток уже существует , еще один нам не нужен print('one secondary thread alredy running.') def stop_act(self): if self.seconary_thread and self.seconary_thread.is_alive(): # Если поток "живой" self.thread_stop_event.set() # Устанавливаем флаг в Trye else: print('thread not running.') def get_r(self): # возвращает r return self.r.value() def get_t(self): # возвращает t return self.t.value() if __name__ == '__main__': app = QtGui.QApplication(sys.argv) mw = MainWindow() app.exec_()