teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

4

説明補足

2020/05/23 06:09

投稿

teamikl
teamikl

スコア8817

answer CHANGED
@@ -34,12 +34,24 @@
34
34
  - (3) MainWindow で双方を接続する
35
35
   `tools.fileSelected.connect(predict.loadImage)`
36
36
  - (4) シグナル発火
37
-  ToolFrame.on_run メソッド内 で `self.fileSelected.emit(filename)`
37
+  ToolFrame.on_run メソッド内 で `self.fileSelected.emit(filename)` 
38
-  
39
38
 
40
39
  PyQt5 でのシグナル/スロットの使い方は
41
40
  [PyQt5 signals_slots](https://doc.bccnsoft.com/docs/PyQt5/signals_slots.html) 等を参考に、コードの書き方は調べて下さい。
42
41
 
42
+ 追記:
43
+
44
+ 因みに、pyqtではスロットの宣言は省略可能で、引数さえ一致すればよく
45
+ 例えば、Canva.openImage にも connect することができます。
46
+
47
+ `tools.fileSelected.connect(self.canvas.openImage)`
48
+
49
+ ToolFrame.on_runから親にアクセス
50
+ self.parent().predict.loadImage(fileName) みたいなコードは、
51
+ MainWindowに依存したコードになり、クラス・オブジェクトの構造が変わると使えなくなりますが、
52
+ シグナル・スロットを用いることで、利用側が振る舞いを決められるようになり、
53
+ ウィジェットの部品としての再利用性が高まります。
54
+
43
55
  ----
44
56
 
45
57
  ```diff

3

シグナル名・スロット名を本文に合わせて修正

2020/05/23 06:09

投稿

teamikl
teamikl

スコア8817

answer CHANGED
@@ -43,8 +43,8 @@
43
43
  ----
44
44
 
45
45
  ```diff
46
- --- main.orig.py 2020-05-23 14:47:42.155965200 +0900
46
+ --- main.orig.py 2020-05-23 14:52:14.587404600 +0900
47
- +++ main.py 2020-05-23 14:47:21.499922800 +0900
47
+ +++ main.py 2020-05-23 14:55:03.595347700 +0900
48
48
  @@ -5,7 +5,7 @@
49
49
  from PyQt5.QtGui import QPainter, QImage, QPen, qRgb
50
50
  from PyQt5.QtCore import Qt, QPoint, QRect, QSize, QDir
@@ -59,7 +59,7 @@
59
59
  hbox.addWidget(predict)
60
60
  hbox.addWidget(tools)
61
61
  +
62
- + tools.onFileSelected.connect(predict.loadImageFile)
62
+ + tools.fileSelected.connect(predict.loadImage)
63
63
  +
64
64
  return frame
65
65
 
@@ -69,7 +69,7 @@
69
69
 
70
70
  class ToolFrame(QWidget):
71
71
  +
72
- + onFileSelected = pyqtSignal(str)
72
+ + fileSelected = pyqtSignal(str)
73
73
  +
74
74
  def __init__(self, parent=None, *args, **kw):
75
75
  super().__init__(parent, *args, **kw)
@@ -82,11 +82,11 @@
82
82
 
83
83
  if fileName:
84
84
  - self.predict.PredictImage(fileName)
85
- + self.onFileSelected.emit(fileName)
85
+ + self.fileSelected.emit(fileName)
86
86
  #self.canvas.openImage(fileName)
87
87
 
88
88
  class Canvas(QWidget):
89
- @@ -253,7 +258,13 @@
89
+ @@ -253,7 +258,12 @@
90
90
  self.image_predict = QImage()
91
91
  self.image_predict.fill(qRgb(255, 0, 255))
92
92
 
@@ -96,7 +96,7 @@
96
96
  + painter.drawImage(0, 0, self.image_predict)
97
97
  +
98
98
  + @pyqtSlot(str)
99
- + def loadImageFile(self, filename):
99
+ + def loadImage(self, filename):
100
100
  image = QImage()
101
101
  if not image.load(filename):
102
102
  return False

2

動作確認できたので、コード差分を追記

2020/05/23 05:56

投稿

teamikl
teamikl

スコア8817

answer CHANGED
@@ -38,4 +38,67 @@
38
38
   
39
39
 
40
40
  PyQt5 でのシグナル/スロットの使い方は
41
- [PyQt5 signals_slots](https://doc.bccnsoft.com/docs/PyQt5/signals_slots.html) 等を参考に、コードの書き方は調べて下さい。
41
+ [PyQt5 signals_slots](https://doc.bccnsoft.com/docs/PyQt5/signals_slots.html) 等を参考に、コードの書き方は調べて下さい。
42
+
43
+ ----
44
+
45
+ ```diff
46
+ --- main.orig.py 2020-05-23 14:47:42.155965200 +0900
47
+ +++ main.py 2020-05-23 14:47:21.499922800 +0900
48
+ @@ -5,7 +5,7 @@
49
+ from PyQt5.QtGui import QPainter, QImage, QPen, qRgb
50
+ from PyQt5.QtCore import Qt, QPoint, QRect, QSize, QDir
51
+ from collections import deque
52
+ -from PyQt5.QtCore import pyqtSlot
53
+ +from PyQt5.QtCore import pyqtSlot, pyqtSignal
54
+ from PyQt5.QtGui import QIcon
55
+
56
+ class MainWindow(QMainWindow):
57
+ @@ -28,6 +28,9 @@
58
+ hbox.addWidget(self.canvas)
59
+ hbox.addWidget(predict)
60
+ hbox.addWidget(tools)
61
+ +
62
+ + tools.onFileSelected.connect(predict.loadImageFile)
63
+ +
64
+ return frame
65
+
66
+ def setupUI(self):
67
+ @@ -124,9 +127,11 @@
68
+ return False
69
+
70
+ class ToolFrame(QWidget):
71
+ +
72
+ + onFileSelected = pyqtSignal(str)
73
+ +
74
+ def __init__(self, parent=None, *args, **kw):
75
+ super().__init__(parent, *args, **kw)
76
+ - self.predict=PredictCanvas()
77
+ self.initUI()
78
+
79
+ def initUI(self):
80
+ @@ -146,7 +151,7 @@
81
+ fileName, _ = QFileDialog.getOpenFileName(self, "Open File", QDir.currentPath())
82
+
83
+ if fileName:
84
+ - self.predict.PredictImage(fileName)
85
+ + self.onFileSelected.emit(fileName)
86
+ #self.canvas.openImage(fileName)
87
+
88
+ class Canvas(QWidget):
89
+ @@ -253,7 +258,13 @@
90
+ self.image_predict = QImage()
91
+ self.image_predict.fill(qRgb(255, 0, 255))
92
+
93
+ - def PredictImage(self, filename):
94
+ + def paintEvent(self, event):
95
+ + painter = QPainter(self)
96
+ + painter.drawImage(0, 0, self.image_predict)
97
+ +
98
+ + @pyqtSlot(str)
99
+ + def loadImageFile(self, filename):
100
+ image = QImage()
101
+ if not image.load(filename):
102
+ return False
103
+
104
+ ```

1

書式の修正

2020/05/23 05:52

投稿

teamikl
teamikl

スコア8817

answer CHANGED
@@ -28,13 +28,13 @@
28
28
  Qtのシグナル/スロットを使った解消法を提案
29
29
 
30
30
  - (1) ToolFrame でファイル選択時のシグナルを定義します
31
-  fileSelected = pyqtSignal(str)
31
+  `fileSelected = pyqtSignal(str)`
32
32
  - (2) PredictCanvas 側で、ファイルを読み込むスロットを定義します
33
-  @pyqtSlot ... def loadImage(self, filename)
33
+  `@pyqtSlot` ... `def loadImage(self, filename)`
34
34
  - (3) MainWindow で双方を接続する
35
35
   `tools.fileSelected.connect(predict.loadImage)`
36
36
  - (4) シグナル発火
37
-  ToolFrame.on_run メソッド内 で self.fileSelected.emit(filename)
37
+  ToolFrame.on_run メソッド内 で `self.fileSelected.emit(filename)`
38
38
   
39
39
 
40
40
  PyQt5 でのシグナル/スロットの使い方は