55049


pyqt5で特定のキーを押したときにアクションを起こすグラフは次のようなコードで書けました。

[code]

    import sys
    from PyQt5 import QtGui,QtCore, QtWidgets,QtMultimedia, QtMultimediaWidgets
    from PyQt5.QtWidgets import QDialog, QApplication, QVBoxLayout
    from PyQt5.QtCore import Qt
    from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
    from matplotlib.backends.backend_qt5 import NavigationToolbar2QT as NavigationToolbar
    from matplotlib.figure import Figure
    import matplotlib.pyplot as plt
    
    import numpy as np
    
    
    class MyCanvas(FigureCanvas):
        def __init__(self, parent=None, width=5, height=4, dpi=100):
    
            fig = Figure(figsize=(width, height), dpi=dpi)
            self.axes = fig.add_subplot(111)
    
            self.plot_figure()
    
            FigureCanvas.__init__(self, fig)
            self.setParent(parent)
    
        def plot_figure(self):
            pass
    
    
        def keyPressEvent(self,event):
            if event.key() == Qt.Key_Right:
                print("g")
            else:
                print("G")
    
    
    class MyStaticMplCanvas(MyCanvas):
        def __init__(self, parent=None):
            super(MyStaticMplCanvas,self).__init__(parent)
            self.setFocusPolicy(Qt.StrongFocus)
    
        def plot_figure(self):
            x=np.arange(0,2*np.pi,0.1)
            y=np.sin(x)
            self.axes.plot(x,y,"-")
            self.axes.set_xlabel("x")
            self.axes.set_ylabel("y")
            self.axes.set_xlim(0,2*np.pi)     
    
    
    
    class Main(QDialog):
        def __init__(self, parent=None):
            super(Main, self).__init__(parent)
    
            canvas = MyStaticMplCanvas(self)
    
            layout = QVBoxLayout()
            layout.addWidget(canvas)
    
            self.setLayout(layout)
    
            self.setWindowTitle('plot')
            self.show()
    
    
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        win = Main()
    
        app.exec_()
    
[/code]

これを実行すると次のようなGUIが作成されます。  
[![画像](https://i.stack.imgur.com/3kf67.png)](https://i.stack.imgur.com/3kf67.png)  
ここで、グラフのプロットをMyStaticMplCanvasで別クラスに分けるのも冗長と思い、次のようにMyCanvasクラスに一つにまとめてみました。

[code]

    import sys
    from PyQt5 import QtGui,QtCore, QtWidgets,QtMultimedia, QtMultimediaWidgets
    from PyQt5.QtWidgets import QDialog, QApplication, QVBoxLayout
    from PyQt5.QtCore import Qt
    from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
    from matplotlib.backends.backend_qt5 import NavigationToolbar2QT as NavigationToolbar
    from matplotlib.figure import Figure
    import matplotlib.pyplot as plt
    
    import numpy as np
    
    
    class MyCanvas(FigureCanvas):
        def __init__(self, parent=None, width=5, height=4, dpi=100):
            super(MyCanvas,self).__init__(parent)
            self.setFocusPolicy(Qt.StrongFocus)
            fig = Figure(figsize=(width, height), dpi=dpi)
            self.axes = fig.add_subplot(111)
    
            self.plot_figure()
    
            FigureCanvas.__init__(self, fig)
            self.setParent(parent)
    
        def plot_figure(self):
            x=np.arange(0,2*np.pi,0.1)
            y=np.sin(x)
            self.axes.plot(x,y,"-")
            self.axes.set_xlabel("x")
            self.axes.set_ylabel("y")
            self.axes.set_xlim(0,2*np.pi)     
    
    
        def keyPressEvent(self,event):
            if event.key() == Qt.Key_Right:
                print("g")
            else:
                print("G")
    
    
    class Main(QDialog):
        def __init__(self, parent=None):
            super(Main, self).__init__(parent)
    
            canvas = MyCanvas(self)
    
            layout = QVBoxLayout()
            layout.addWidget(canvas)
    
            self.setLayout(layout)
    
            self.setWindowTitle('plot')
            self.show()
    
    
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        win = Main()
    
        app.exec_()
    
[/code]

すると、次のようなエラーが出ました。

[code]

      File "C:\Users\toma\Anaconda3\lib\site-packages\matplotlib\backends\backend_qt5.py", line 236, in __init__
        figure._original_dpi = figure.dpi
    
    AttributeError: 'Main' object has no attribute 'dpi'
    
[/code]

何が悪かったのでしょうか。


CC BY-SA 4.0
2019-05-17T07:41:09.043
55046
2019-05-17T09:01:16.393
26529
question
python3 pyqt5
pyqt5でコードを少し変えたらkeyPressEventが動作しなくなった


おそらく、`super(MyCanvas,self).__init__(parent)`
が不要なのと、`self.setFocusPolicy(Qt.StrongFocus)` を `FigureCanvas.__init__(self,
fig)` の後に呼び出す必要があるのだと思われます。

`class MyCanvas(FigureCanvas):` の `def __init__(...):` は以下のようになるでしょう。

[code]

        def __init__(self, parent=None, width=5, height=4, dpi=100):
    
            fig = Figure(figsize=(width, height), dpi=dpi)
            self.axes = fig.add_subplot(111)
    
            self.plot_figure()
    
            FigureCanvas.__init__(self, fig)
            self.setParent(parent)
            self.setFocusPolicy(Qt.StrongFocus)
    
[/code]


CC BY-SA 4.0
2019-05-17T09:01:16.393
55049
2019-05-17T09:01:16.393
26370
55046
answer