def test_seach_manga(self): def search_callback(loop, result: List[Manga]): self.assertIsInstance(result, list) self.assertEqual(len(result), 2) foundFlag = False for manga in result: if manga.name == '火影忍者': foundFlag = True break self.assertTrue(foundFlag) self.assertEqual(manga.url, 'https://www.manhuagui.com/comic/4681/') loop.quit() timeout = 5000 if QtWidgets.QApplication.instance() is None: QtWidgets.QApplication([]) loop = QtCore.QEventLoop() mhg = get_mhg() mhg.search_result.connect(partial(search_callback, loop)) mhg.search_manga('naruto') if timeout is not None: QtCore.QTimer.singleShot(timeout, partial(call_timeout, loop)) loop.exec_()
def initial_message(self, input): text = input["utt"] print(text) sessionId = input["sessionId"] self.el = QtCore.QEventLoop() # SCXMLファイルの読み込み sm = QtScxml.QScxmlStateMachine.fromFile('states.scxml') # セッションIDとセッションに関連する情報を格納した辞書 # 複数人がアクセスしてもいいようにする self.sessiondic[sessionId] = { "statemachine": sm, "purpose": "", "isbn": "", "author": "", "title": "" } # 初期状態に遷移 sm.start() self.el.processEvents() # 初期状態の取得 current_state = sm.activeStateNames()[0] print("current_state=", current_state) # 初期状態に紐づいたシステム発話の取得と出力 sysutt = self.uttdic[current_state] return {"utt": "知りたい本に関するキーワードから目的の情報を推測します。\n" + sysutt, "end": False}
def execute(self, context): #logger.debug('execute operator') self.app = QtWidgets.QApplication.instance() # instance() gives the possibility to have multiple windows # and close it one by one if not self.app: # create the first instance self.app = QtWidgets.QApplication(sys.argv) if 'stylesheet' in self._kwargs: stylesheet = self._kwargs['stylesheet'] self.set_stylesheet(self.app, stylesheet) self.app.setStyle("fusion") self.event_loop = QtCore.QEventLoop() self.widget = self._widget(*self._args, **self._kwargs) #logger.debug(self.app) #logger.debug(self.widget) # run modal wm = context.window_manager self._timer = wm.event_timer_add(1.0 / 30.0, window=context.window) context.window_manager.modal_handler_add(self) return {'RUNNING_MODAL'}
def __init__(self, live=True, reload=True, standalone=False, sim_queue=None): QtCore.QObject.__init__(self) self.loop = QtCore.QEventLoop(self) reg['sim/gearbox'] = self # self.queue = sim_queue # if self.queue is None: # self.queue = queue.Queue() self.breakpoints = set() self.live = live self.done = False self.reload = reload self.standalone = standalone self.running = False self.thrd = QtCore.QThread() self.moveToThread(self.thrd) self.thrd.started.connect(self.run) self.thrd.start()
def service(self): if self._service is None: reply = self._update_credentials() loop = QtCore.QEventLoop() reply.finished.connect(loop.quit) loop.exec_() if not reply.has_error(): self._service = reply.results else: logging.debug(reply.error_str) return self._service
def for_loop_files(paths, interval=100, parent=None, objectName=""): timer = QtCore.QTimer(parent=parent, singleShot=True, interval=interval) if objectName: timer.setObjectName(objectName) loop = QtCore.QEventLoop(timer) timer.timeout.connect(loop.quit) timer.destroyed.connect(loop.quit) for path in paths: if shiboken2.isValid(timer): timer.start() loop.exec_() yield path
def execute(self, context): # create a QApplication if already does not exists self._app = QtWidgets.QApplication.instance( ) or QtWidgets.QApplication(sys.argv) self._event_loop = QtCore.QEventLoop() # run modal wm = context.window_manager # self._timer = wm.event_timer_add(1 / 120, window=context.window) self._timer = wm.event_timer_add(0.001, window=context.window) context.window_manager.modal_handler_add(self) return {"RUNNING_MODAL"}
def __upload_version(self, version): # create a new event loop to upload files eventLoop = QtCore.QEventLoop() # open new thread and wait for thread to finish thread = UploaderThread(self.app, version, self.file) thread.finished.connect(eventLoop.quit) thread.start() eventLoop.exec_() if thread.get_errors(): for e in thread.get_errors(): self.app.logger.error(e)
def execute(self, context): self.app = QtWidgets.QApplication.instance() if not self.app: self.app = QtWidgets.QApplication(sys.argv) self.widget = Ui_Form() self.event_loop = QtCore.QEventLoop() self.widget.hide() wm = context.window_manager self._timer = wm.event_timer_add(1 / 120, window=context.window) context.window_manager.modal_handler_add(self) print('running modal') return {'RUNNING_MODAL'}
def initial_message(self, input): text = input['utt'] sessionId = input['sessionId'] self.el = QtCore.QEventLoop() sm = QtScxml.QScxmlStateMachine.fromFile('states.scxml') self.sessiondic[sessionId] = sm sm.start() self.el.processEvents() current_state = sm.activeStateNames()[0] print('current_state=', current_state) sysutt = self.uttdict[current_state] return {'utt': "天気案内システム。" + sysutt, 'end': False}
def test_get_meta2(self): def index_callback(loop, manga: Manga): self.assertEqual(manga.last_udpate, '2020-02-05 13:47') self.assertTrue(not manga.finished) loop.quit() timeout = 5000 if QtWidgets.QApplication.instance() is None: QtWidgets.QApplication([]) mhd = get_mhd() mhd.get_index_page('https://www.manhuadui.com/manhua/jinjidejuren/') loop = QtCore.QEventLoop() mhd.index_page.connect(partial(index_callback, loop)) if timeout is not None: QtCore.QTimer.singleShot(timeout, partial(call_timeout, loop)) loop.exec_()
def Send_cgtwNote(self, m_database, m_id): ''' :param m_database: 获取项目的数据库 如: proj_csj :param m_id: 获取对应 条目的id 号: projectDb = self.getProjectDatabase() t_info = self.t_tw.info_module(projectDb, 'shot') filters = [ ["shot.eps_name", '=', 'ACT2'], ["shot.shot", '=', 'S031'] ] t_info.init_with_filter(filters) # 过滤器 fields = [] # 查询的内容 # 作者 模块 任务名称 阶段 data = t_info.get(fields) 如 [{'id': u'0DC0AEAB-575B-6548-7287-6B0646070A79'}] :return: ''' # app = QtGui.QApplication.instance() webview = QWebEngineView() m_token = self._t_tw.sys().get_token() m_ip = str(self._t_tw.sys().get_server_ip() ) #如果是内网 则不要加入端口号,如果是外网需要加入+':10003' m_module = self._t_tw.info_module(m_database, 'shot').get_module() web_data = "http://" + str( m_ip ) + "/index.php?controller=v_thirdpath_soft&method=show_page&db=" + str( m_database) + "&module=" + str( m_module ) + "&module_type=info&theme=maya&lang=zh&task_id=" + str( m_id) + "&widget=note_widget&token=" + str( m_token) + "&is_qt=y" if web_data: if web_data.find('://') == -1: web_data = 'http://' + web_data url = QtCore.QUrl(web_data) webview.load(url) webview.show() q = QtCore.QEventLoop() q.exec_()
def test_get_meta1(self): def index_callback(loop, manga: Manga): self.assertEqual(manga.last_udpate, '2019-06-13 17:17') self.assertTrue(manga.finished) loop.quit() timeout = 5000 if QtWidgets.QApplication.instance() is None: QtWidgets.QApplication([]) mhd = get_mhd() mhd.get_index_page( 'https://www.manhuadui.com/manhua/huoyingrenzhediyihuafuzhiyuangaoBOX/' ) loop = QtCore.QEventLoop() mhd.index_page.connect(partial(index_callback, loop)) if timeout is not None: QtCore.QTimer.singleShot(timeout, partial(call_timeout, loop)) loop.exec_()
def for_loop_files(path, interval=100, extensions=(), parent=None, objectName=""): timer = QtCore.QTimer(parent=parent, singleShot=True, interval=interval) if objectName: timer.setObjectName(objectName) loop = QtCore.QEventLoop(timer) timer.timeout.connect(loop.quit) timer.destroyed.connect(loop.quit) for root, dirs, files in os.walk(path): # print(files) for name in files: base, ext = os.path.splitext(name) # print(ext) if extensions: if ext in extensions: print(extensions) if shiboken2.isValid(timer): timer.start() loop.exec_() yield os.path.join(root, name) else: yield os.path.join(root, name)
def test_get_index_page(self): def index_callback(loop, manga: Manga): chapters = manga.chapters self.assertIsInstance(chapters, dict) self.assertEqual(len(chapters), 3) self.assertEqual(len(chapters[MangaIndexTypeEnum.CHAPTER]), 75) chapter = chapters[MangaIndexTypeEnum.CHAPTER][39] self.assertEqual(chapter.title, '40话') loop.quit() timeout = 5000 if QtWidgets.QApplication.instance() is None: QtWidgets.QApplication([]) mhd = get_mhd() mhd.get_index_page('https://www.manhuadui.com/manhua/pengyouyouxi/') loop = QtCore.QEventLoop() mhd.index_page.connect(partial(index_callback, loop)) if timeout is not None: QtCore.QTimer.singleShot(timeout, partial(call_timeout, loop)) loop.exec_()
def test_get_page_urls(self): def page_urls_callback(loop, page_urls, manga: Manga, m_type: MangaIndexTypeEnum, idx: int): self.assertEqual(len(page_urls), 40) self.assertEqual( page_urls[0], 'https://mhimg.eshanyao.com/ManHuaKu/p/pengyouyouxi/75/145829.jpg' ) self.assertEqual( page_urls[1], 'https://mhimg.eshanyao.com/ManHuaKu/p/pengyouyouxi/75/145830.jpg' ) self.assertEqual( page_urls[-3], 'https://mhimg.eshanyao.com/ManHuaKu/p/pengyouyouxi/75/145866.jpg' ) loop.quit() timeout = 10000 if QtWidgets.QApplication.instance() is None: QtWidgets.QApplication([]) mhd = get_mhd() manga = Manga(name='朋友游戏', url='https://www.manhuadui.com/manhua/pengyouyouxi/', site=mhd) manga.add_chapter( MangaIndexTypeEnum.CHAPTER, title='75话「还是老样子呢」', page_url='https://www.manhuadui.com/manhua/pengyouyouxi/461357.html' ) mhd.get_page_urls(manga, MangaIndexTypeEnum.CHAPTER, 0) loop = QtCore.QEventLoop() mhd.get_pages_completed.connect(partial(page_urls_callback, loop)) if timeout is not None: QtCore.QTimer.singleShot(timeout, partial(call_timeout, loop)) loop.exec_()
def test_get_page_urls(self): def page_urls_callback(loop, page_urls, manga: Manga, m_type: MangaIndexTypeEnum, idx: int): self.assertEqual(len(page_urls), 208) self.assertEqual( page_urls[0], 'https://i.hamreus.com/ps1/h/naruto/69/NARUTO69_000.jpg.webp?cid=194193&md5=9rdIwhvMsyOQN8DK0alICQ' ) self.assertEqual( page_urls[1], 'https://i.hamreus.com/ps1/h/naruto/69/NARUTO69_001b.png.webp?cid=194193&md5=9rdIwhvMsyOQN8DK0alICQ' ) self.assertEqual( page_urls[-2], 'https://i.hamreus.com/ps1/h/naruto/69/NARUTO69_104.png.webp?cid=194193&md5=9rdIwhvMsyOQN8DK0alICQ' ) loop.quit() timeout = 10000 if QtWidgets.QApplication.instance() is None: QtWidgets.QApplication([]) mhg = get_mhg() manga = Manga(name='火影忍者', url='https://www.manhuagui.com/comic/4681/', site=mhg) manga.add_chapter( MangaIndexTypeEnum.CHAPTER, title='第69卷', page_url='https://www.manhuagui.com/comic/4681/194193.html') mhg.get_page_urls(manga, MangaIndexTypeEnum.CHAPTER, 0) loop = QtCore.QEventLoop() mhg.get_pages_completed.connect(partial(page_urls_callback, loop)) if timeout is not None: QtCore.QTimer.singleShot(timeout, partial(call_timeout, loop)) loop.exec_()
def test_get_index_page2(self): def index_callback(loop, manga: Manga): chapters = manga.chapters self.assertIsInstance(chapters, dict) self.assertEqual(len(chapters), 3) self.assertEqual(len(chapters[MangaIndexTypeEnum.CHAPTER]), 195) chapter = chapters[MangaIndexTypeEnum.CHAPTER][156] self.assertEqual(chapter.title, '第157话 归还之魂') loop.quit() timeout = 5000 if QtWidgets.QApplication.instance() is None: QtWidgets.QApplication([]) mhg = get_mhg() mhg.get_index_page('https://www.manhuagui.com/comic/19430/') loop = QtCore.QEventLoop() mhg.index_page.connect(partial(index_callback, loop)) if timeout is not None: QtCore.QTimer.singleShot(timeout, partial(call_timeout, loop)) loop.exec_()
def initial_message(self, input): # 最初にユーザーからのメッセージとsessionIdを受け取る text = input["utt"] sessionId = input["sessionId"] self.el = QtCore.QEventLoop() # SCXMLファイルの読み込み sm = QtScxml.QScxmlStateMachine.fromFile('./scxml/states.scxml') # smオブジェクトを持っておく self.sessiondic[sessionId] = sm sm.start() self.el.processEvents() # 初期状態の取得(ask_place) current_state = sm.activeStateNames()[0] print("current state", current_state) # 初期情報に紐づいたシステム発話の取得と出力 sysutt = self.uttdic[current_state] return {"utt": f"こちらは天気情報案内システムです。{sysutt}", "end": False}
def get_A(D, Q): # 必要な情報の辞書とリスト info = D # 辞書の作成 info_list_name = [] # 名前のみのlistの作成 info_list_val = [] # valueのみlistの作成 info_list_val_name = [] # valueの値段を除いた名前のみのlistの作成 for v in info.keys(): # 辞書をリストに変換(key) info_list_name.append(v) for v in info.values(): # 辞書をリストに変換(value) info_list_val.extend(v) for v in range(len(info_list_val)): # valueの名前だけのlist info_list_val_name.append(info_list_val[v][0]) for v in range(len(info_list_val_name)): info_list_name.append(info_list_val_name[v]) # 識別するための情報の追加 plus_info = [ '他', '情報', '認識結果', '一番安い', '検出結果', '種類', '商品リスト', 'カテゴリリスト', 'カテゴリーリスト' ] for v in range(len(plus_info)): info_list_val_name.append(plus_info[v]) # テキストから取得した情報数を返す関数.見つからない場合は0を返す. def get_info_num(text): flag = 0 for information_num in info.keys(): if information_num in text: flag += 1 for information_num in info_list_val_name: if information_num in text: flag += 1 if information_num == '他': flag += 100 if information_num == '一番安い': flag += 1000 return flag # テキストから必要なを抽出する関数.見つからない場合は空文字を返す. def get_info(text): info_key = 0 # 得られる情報がkeyかどうかを識別する変数 info_value = 0 # 得られる情報がvalueかどうかを識別する変数 case = 0 # 質問の種類を識別する変数 key_name = "" # 得られる情報(key)の名前を取得 value_name = "" # 得られる情報(value)の名前を取得 Q_case = 0 # 質問か読み上げ繰り返しなのかを識別する変数 for information in info.keys(): if information in text: if information != '他': key_name = information # ユーザーに聞かれた情報(key)の名前を取得 info_key = 1 for information in info_list_val_name: if information in text: if information != '他': value_name = information # ユーザーに聞かれた情報(value)の名前を取得 info_value = 1 if (value_name == "情報") or (value_name == "認識結果") or ( value_name == "検出結果") or (value_name == "種類") or ( value_name == "商品リスト") or (value_name == "カテゴリリスト") or (value_name == "カテゴリーリスト"): Q_case = 1 if info_key == 1 and info_value == 1: if value_name == '一番安い': pass else: info_key = 0 # keyとvalueの一部がかぶっていた場合,valueを優先する処理 return information, info_key, info_value, key_name, value_name, Q_case else: return information, info_key, info_value, key_name, value_name, Q_case return "", info_key, info_value, key_name, value_name, Q_case # Qtに関するおまじない if not QtCore.QCoreApplication.instance(): app = QtCore.QCoreApplication() else: app = QtCore.QCoreApplication.instance() el = QtCore.QEventLoop() # SCXMLファイルの読み込み sm = QtScxml.QScxmlStateMachine.fromFile('states_1.scxml') # 初期状態に遷移 sm.start() el.processEvents() # 状態とシステム発話を紐づけた辞書 uttdic = {"ask_info": ""} # 初期状態の取得 current_state = sm.activeStateNames()[0] # 初期状態に紐づいたシステム発話の取得と出力 sysutt = uttdic[current_state] # ユーザ入力の処理 while True: text = Q # 質問を読み込む info_num = 0 # 情報数が1or2の識別するための変数 response_list = [] # 返す答えの要素を保存するlist response_ans = [] # 返す答えを保存するlist # ユーザ入力を用いて状態遷移と取得情報数 if current_state == "ask_info": info_num = get_info_num(text) ans, info_key, info_value, key_name, value_name, case = get_info( text) if ans != "" and info_num == 1: # 情報数が1の場合の状態遷移を実行 info_case = 1 sm.submitEvent("ans") el.processEvents() if ans != "" and info_num == 2: # 情報数が1の場合の状態遷移を実行(keyとvalueの名前のかぶりあり) info_case = 1 sm.submitEvent("ans") el.processEvents() if ans != "" and info_num > 2 and info_num < 1000: # 情報数が2の場合(カテゴリ+他 or 商品名+他)の状態遷移を実行 info_case = 2 sm.submitEvent("ans") el.processEvents() if ans != "" and info_num > 1000: # 情報数が2の場合(カテゴリ+一番安い)の状態遷移を実行 info_case = 3 sm.submitEvent("ans") el.processEvents() # 遷移先の状態を取得 current_state = sm.activeStateNames()[0] # 遷移先がtell_infoの場合は情報を伝えて終了 if current_state == "tell_info": # 伝える情報(info_caseにより伝える情報を区別) # 得られた情報が1つの場合 if info_case == 1 and info_key == 1 and info_value == 0 and case == 0: # keyに関して聞かれた場合 for information in info.keys(): if information == key_name: # 得られた情報(key)をkeyとして持つvalueを検索,表示 response_list = info[information] for i in range(len(response_list)): response_ans.append(response_list[i][0]) response_ans.append('があります') if info_case == 1 and info_key == 0 and info_value == 1 and case == 0: # valueに関して聞かれた場合(値段に関する質問) for information in range(len(info_list_val)): if value_name == info_list_val[information][0]: response_ans.append( str(info_list_val[information][1]) + '円です') if info_case == 1 and info_key == 0 and info_value == 1 and case == 1 and ( value_name == '認識結果' or value_name == '検出結果' or value_name == '情報' or value_name == '商品リスト'): # 認識結果を返す処理 for v in info_list_val_name: response_ans.append(v) for i in range(len(plus_info)): del response_ans[-1] if info_case == 1 and info_key == 0 and info_value == 1 and case == 1 and ( value_name == '種類' or value_name == 'カテゴリリスト' or value_name == 'カテゴリーリスト'): # 商品の種類を返す処理 for v in info.keys(): response_ans.append(v) # 得られた情報が2つの場合 if info_case == 2 and info_key == 1 and info_value == 0 and case == 0: # あるkeyに関して他に何があるか聞かれた場合の検索,表示(key+他を想定) for information in info.keys(): if information == key_name: # 得られた情報(key)をkeyとして持つvalueを検索,表示 response_list = info[information] for i in range(len(response_list)): response_ans.append(response_list[i][0]) del response_ans[0] if response_ans == []: response_ans.append('他にはありません') else: response_ans.append('があります') if info_case == 2 and info_key == 0 and info_value == 1 and case == 0: # あるkeyに関して他に何があるか聞かれた場合の検索,表示(value+他を想定) del_number = 0 # かぶっている商品を調べて削除するための変数 for information in info.keys(): if type(info[information]) == list: for i in range(len(info[information])): if value_name in info[information][i][0]: response_list = info[information] for i in range(len(response_list)): response_ans.append(response_list[i][0]) for number in range(len(response_ans)): # かぶっている商品を削除 if value_name == response_ans[number]: del_number = number del response_ans[del_number] if response_ans == []: response_ans.append('他にはありません') else: response_ans.append('があります') if info_case == 3: # あるkeyに関して一番安い商品を聞かれた場合の検索,表示(key+一番安いを想定) if info_key == 0 and info_value == 1: pass else: L = [] for k, v in info.items(): if k == key_name: L = deepcopy(v) L = sorted(L, key=lambda x: x[1]) response_ans.append( str(L[0][1]) + '円の' + str(L[0][0]) + 'です') break
"{}?lat={}&lon={}&lang=ja&units=metric&APPID={}".format( forecast_url, lat, lon, appid)) dic = response.json() # 3時間おきの天気情報についてループ for i in range(len(dic["list"])): # i番目の天気情報(UNIX時間) dt = float(dic["list"][i]["dt"]) # 明日の正午以降のデータになった時点でその天気情報を返す if dt >= timestamp: return dic["list"][i] return "" # Qtに関するおまじない app = QtCore.QCoreApplication() el = QtCore.QEventLoop() # SCXMLファイルの読み込み sm = QtScxml.QScxmlStateMachine.fromFile('states.scxml') # 初期状態に遷移 sm.start() el.processEvents() # システムプロンプト print("SYS> こちらは天気情報案内システムです") # 状態とシステム発話を紐づけた辞書 uttdic = { "ask_place": "地名を言ってください", "ask_date": "日付を言ってください",
def game_loop(self): print('starting game loop') while self.state == 'playing': if self.playing_color == 'white': if self.white_is_human: print('white human is playing') allowed_moves = self.chessengine.get_all_allowed_moves( self.playing_color) self.handler.get_human_move(self.playing_color, allowed_moves) loop = QtCore.QEventLoop() self.wait_no_more.connect(loop.quit) loop.exec_() self.chessengine.register_move(self.received_human_move) if not self.black_is_human: self.black_chessengine.register_move( self.received_human_move) else: print('white computer is playing') computer_move = self.white_chessengine.get_next_move( self.playing_color) self.chessengine.register_move(computer_move) #self.handler.execute_computer_move_on_screen.emit(computer_move) if not self.black_is_human: self.black_chessengine.register_move(computer_move) elif self.playing_color == 'black': if self.black_is_human: print('black human is playing') allowed_moves = self.chessengine.get_all_allowed_moves( self.playing_color) self.handler.get_human_move(self.playing_color, allowed_moves) loop = QtCore.QEventLoop() self.wait_no_more.connect(loop.quit) loop.exec_() self.chessengine.register_move(self.received_human_move) if not self.white_is_human: self.white_chessengine.register_move( self.received_human_move) else: print('black computer is playing') computer_move = self.black_chessengine.get_next_move( self.playing_color) self.chessengine.register_move(computer_move) if not self.white_is_human: self.white_chessengine.register_move(computer_move) self.handler.update_chessboard_view.emit( self.chessengine.current_board_representation()) # Check if game is over here I guess. self.flip_playing_color() if len(self.chessengine.get_all_allowed_moves( self.playing_color)) == 0: if self.chessengine.king_is_under_attack(self.playing_color): print('VICTORY!') else: print('DRAW.') self.state = 'idle'
def thread_wait( finished_signal: QtCore.Signal, timeout: int = 600000, finish_func: Callable = None, failed_signal: QtCore.Signal = None, failed_func: Callable = None, update_signal: QtCore.Signal = None, ): """Prevent the primary event loop from progressing without blocking GUI events. This progresses until the given signal is emitted or the timeout reached.""" # https://www.jdreaver.com/posts/2014-07-03-waiting-for-signals-pyside-pyqt.html # create a new event loop loop = QtCore.QEventLoop() # create a finished quit function def finished_quit() -> None: loop.quit() # stop timer if timer: timer.stop() # connect the finished signal to loop quit finished_signal.connect(finished_quit) # type: ignore # if an optional finish function is provided, also connect that signal to it if finish_func: finished_signal.connect(finish_func) # type: ignore timer = None # create a timeout quit function def timeout_quit() -> None: loop.exit(1) logger.error("Timeout reached") if timeout is not None: # setup a timeout quit timer = QtCore.QTimer() timer.timeout.connect(timeout_quit) # type: ignore timer.setSingleShot(True) timer.start(timeout) if update_signal: update_signal.connect(lambda: timer.start(timeout)) # type: ignore # create a failed quit function def failed_quit(err) -> None: # exit loop and loop.exit(1) # stop timer if timer: timer.stop() # call provided failure function failed_func(err) # if an optional failure function is provided, also connect that signal to it if failed_signal and failed_func: failed_signal.connect(failed_quit) # type: ignore # do yield # execute the new event loop loop.exec_()
def start(self): self.error.emit(f"start method in thread: {threading.get_ident()}") self.setup_timer() self.timer.start(self.time_to_sleep) loop = QtCore.QEventLoop() loop.exec_()
def delay(self): loop = QtCore.QEventLoop() QtCore.QTimer.singleShot(1, loop.quit) loop.exec_()