質問編集履歴

1

コード追加

2021/02/11 13:43

投稿

hachimitu
hachimitu

スコア36

test CHANGED
File without changes
test CHANGED
@@ -263,3 +263,263 @@
263
263
  #質問
264
264
 
265
265
  上記問題を解決方法で何か良い方法はありますでしょうか
266
+
267
+
268
+
269
+
270
+
271
+
272
+
273
+ #解決したコード
274
+
275
+
276
+
277
+ ```python
278
+
279
+ import sys
280
+
281
+ import logging
282
+
283
+ import time
284
+
285
+ import signal
286
+
287
+ from PyQt5.QtCore import QThread, QObject, pyqtSignal, pyqtSlot
288
+
289
+ from PyQt5.QtWidgets import (
290
+
291
+ QApplication,
292
+
293
+ QWidget,
294
+
295
+ QLineEdit,
296
+
297
+ QPlainTextEdit,
298
+
299
+ QPushButton,
300
+
301
+ QGridLayout,
302
+
303
+ QShortcut,
304
+
305
+ )
306
+
307
+ from PyQt5.QtGui import QKeySequence
308
+
309
+ from PyQt5 import QtGui
310
+
311
+ FLAG = False
312
+
313
+ class Worker(QObject):
314
+
315
+
316
+
317
+ done = pyqtSignal(str)
318
+
319
+
320
+
321
+ @pyqtSlot(str)
322
+
323
+ def execute(self, text):
324
+
325
+ global FLAG
326
+
327
+ FLAG = False
328
+
329
+ # シグナル経由で呼び出すと別スレッドで実行されますが、
330
+
331
+ # シグナル&スロット機構を使う場合は、イベントループを使う必要があり、
332
+
333
+ # スレッドのイベントループを正常に稼働させるためには、
334
+
335
+ # 個々の関数(スロット)は即時に終了しなければなりません。
336
+
337
+ #
338
+
339
+ # 時間のかかる処理を行いたい場合は、
340
+
341
+ # 毎回新しいスレッドを生成するか、この中で更に別スレッドを使います。
342
+
343
+
344
+
345
+ while not FLAG:
346
+
347
+ print("Waiting for signal...")
348
+
349
+ print("FLAG = {}".format(FLAG))
350
+
351
+ time.sleep(1)
352
+
353
+
354
+
355
+
356
+
357
+
358
+
359
+
360
+
361
+
362
+
363
+ class View(QWidget):
364
+
365
+
366
+
367
+ sendMessage = pyqtSignal(str)
368
+
369
+
370
+
371
+ def __init__(self, parent=None):
372
+
373
+ super().__init__(parent)
374
+
375
+ lineEdit = QLineEdit(self)
376
+
377
+ button = QPushButton("Execute", self)
378
+
379
+ textEdit = QPlainTextEdit(self)
380
+
381
+
382
+
383
+ lineEdit.returnPressed.connect(self._onClicked)
384
+
385
+ button.clicked.connect(self._onClicked)
386
+
387
+
388
+
389
+ layout = QGridLayout(self)
390
+
391
+ layout.addWidget(lineEdit, 0, 0)
392
+
393
+ layout.addWidget(button, 0, 1)
394
+
395
+ layout.addWidget(textEdit, 1, 0, 1, 2)
396
+
397
+
398
+
399
+ self._button = button
400
+
401
+ self._textEdit = textEdit
402
+
403
+ self._lineEdit = lineEdit
404
+
405
+
406
+
407
+ def _onClicked(self):
408
+
409
+ text = self._lineEdit.text()
410
+
411
+ self.sendMessage.emit(text)
412
+
413
+ self._lineEdit.clear()
414
+
415
+
416
+
417
+ @pyqtSlot(str)
418
+
419
+ def addResultText(self, text):
420
+
421
+ global FLAG
422
+
423
+ logging.info("addResultText: %s", text)
424
+
425
+ self._textEdit.appendPlainText(text)
426
+
427
+ FLAG = True
428
+
429
+
430
+
431
+ def onControlC():
432
+
433
+ global FLAG
434
+
435
+ print("Ctrl-C pressed")
436
+
437
+ FLAG = True
438
+
439
+
440
+
441
+ def main():
442
+
443
+
444
+
445
+ app = QApplication(sys.argv)
446
+
447
+ view = View()
448
+
449
+
450
+
451
+ # スレッド開始
452
+
453
+ thread = QThread(app)
454
+
455
+ worker = Worker()
456
+
457
+ worker.moveToThread(thread)
458
+
459
+ thread.start()
460
+
461
+ #シグナル定義
462
+
463
+
464
+
465
+ # view: メインスレッド, worker: 別スレッド
466
+
467
+ view.sendMessage.connect(worker.execute)
468
+
469
+ worker.done.connect(view.addResultText)
470
+
471
+
472
+
473
+
474
+
475
+
476
+
477
+
478
+
479
+ shortcut = QShortcut(QKeySequence('Ctrl+C'), view)
480
+
481
+ shortcut.activated.connect(onControlC)
482
+
483
+
484
+
485
+
486
+
487
+ # プログラム終了時にエラーが出ないように、スレッドの後始末
488
+
489
+ # ※ QThread の使い方によって後始末の方法が異なるので注意
490
+
491
+ # QThread.quit は、スレッドのイベントループを終了します。
492
+
493
+ app.aboutToQuit.connect(thread.quit)
494
+
495
+
496
+
497
+ view.show()
498
+
499
+ sys.exit(app.exec_())
500
+
501
+
502
+
503
+
504
+
505
+ if __name__ == '__main__':
506
+
507
+ logging.basicConfig(
508
+
509
+ level=logging.DEBUG,
510
+
511
+ # ログにスレッド名を表示するための書式設定
512
+
513
+ #
514
+
515
+ # ※ 制限: QThread のスレッド名は Dummy-1 のように表示されますが、
516
+
517
+ # 今回は、メインスレッドかそうでないかを区別できれば充分です。
518
+
519
+ format="[%(threadName)-10s][%(levelname)-8s] %(message)s",
520
+
521
+ )
522
+
523
+ main()
524
+
525
+ ```