본문 바로가기
Python/PySide PyQt

[PySide] FigureCanvas.mpl_connect

by ds31x 2024. 5. 19.

FigureCanvas.mpl_connect

 

FigureCanvas 클래스는

  • Matplotlib 이 이용하여 그려진 그래픽 요소와의 interaction(상호작용)을 위한 event handling을 구현하기 위해,
  • mpl_connect method를 제공함.
더보기

Matplotlib는 wypython, tkinter, qt, gtk, macOS 등의 다양한 user interface toolkit들과 함께 동작하여, 
사용자와 interaction이 가능하도록 해주는 "GUI neutral" API를 제공함.

 

이 "GUI neutral" API가 제공하는 event들은

Matplotlib가 최초로 지원했던 user interface toolkit인 gtk의 모델에 기반으로 구현되었음.

 

Matplotlib가 제공하는 event는
Matplotlib의 Figure 및 Axes 등에 대한 정보와
실제 그림의 coordinate정보를 포함하여 제공하는 장점을 가짐.

 

2024.06.02 - [개발환경] - [Etc] GTK: GIMP Toolkit

 

[Etc] GTK: GIMP Toolkit

GTK란GTK는 "GIMP Toolkit"을 의미하는 Open source GUI Toolkit입니다. GTK는 원래 GIMP(GNU Image Manipulation Program)의 개발을 위해 만들어진 Open Source Toolkit임.https://www.gtk.org/ The GTK Project - A free and open-source cross-p

ds31x.tistory.com


이 메소드 mpl_connectmethod를 사용하여

  • 특정 event에 대응하는
  • callback function을 연결할 수 있음.

2023.07.13 - [Python] - [Python] Callback function

 

[Python] Callback function

callback function란 다음 두가지에 해당하는 function을 의미한다. 다른 function의 argument로 전달되어 특정 event가 발생시 호출이 이루어지는 function을 가르킨다 (사용자가 명시적으로 호출하지 않음). Pyt

ds31x.tistory.com


이 문서에서는 PySide6에서 Matplotlib를 사용할 때 이용가능한

  • 기본적인 event 종류
  • 각 event에 대응하는 callback function을 구현하는 간단한 예제 코드를 보여주고 설명함.

mpl_connect 메소드 사용법

mpl_connect연결할 event의 이름과 해당 이벤트가 발생했을 때 호출될(=연결될) callback function을 parameters로 가짐.
사용 가능한 주요 event type은 다음과 같음:

  • button_press_event: 마우스 버튼이 눌릴 때 발생하는 event.
  • button_release_event: 마우스 버튼이 떼어질 때 발생하는 event.
  • motion_notify_event: 마우스 커서가 움직일 때 발생하는 event.
  • key_press_event: 키보드 키가 눌렸을 때 발생하는 event.
  • key_release_event: 키보드 키가 떼어질 때 발생하는 event.

https://matplotlib.org/stable/users/explain/figure/event_handling.html

 

Event handling and picking — Matplotlib 3.9.0 documentation

Event handling and picking Matplotlib works with a number of user interface toolkits (wxpython, tkinter, qt, gtk, and macOS) and in order to support features like interactive panning and zooming of figures, it is helpful to the developers to have an API fo

matplotlib.org

 


예제 코드: 각 event 확인

다음 code snippet은 각 event를 확인할 수 있는 예제임.

import sys
from PySide6.QtCore import Qt
from PySide6.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget
from matplotlib.figure import Figure
from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qtagg import NavigationToolbar2QT as NavigationToolbar

# MainWindow 클래스는 PySide6의 QMainWindow를 상속받아 사용자 정의 윈도우를 생성.
class MainWindow(QMainWindow):
    def __init__(self):
        # 부모 클래스의 생성자 호출
        super().__init__()  
        # 윈도우 제목 설정
        self.setWindowTitle("Event Handling with Matplotlib and PySide6")  

        # Matplotlib Figure 객체 생성. 이 객체는 플롯의 컨테이너 역할을 수행.
        self.figure = Figure()
        self.canvas = FigureCanvas(self.figure)  # Figure 객체를 화면에 표시할 Canvas 생성
        self.ax = self.figure.add_subplot(111)  # 1x1 그리드에 첫 번째 서브플롯 추가
        self.ax.plot([1, 2, 3, 4], [1, 4, 9, 16])  # 예제 데이터로 간단한 선 그래프plotting 

        # NavigationToolbar2QT는 Matplotlib의 도구 모음을 PySide6 애플리케이션에 통합
        self.toolbar = NavigationToolbar(self.canvas, self)  # Canvas와 MainWindow를 툴바에 연결

        # QVBoxLayout을 사용하여 위젯을 수직으로 정렬.
        layout = QVBoxLayout()
        widget = QWidget()  # 중앙 위젯으로 사용할 QWidget 인스턴스 생성
        self.setCentralWidget(widget)  # 생성한 위젯을 메인 윈도우의 중앙 위젯으로 설정
        widget.setLayout(layout)  # QVBoxLayout을 QWidget에 설정
        layout.addWidget(self.toolbar)  # 툴바를 레이아웃에 추가
        layout.addWidget(self.canvas)   # 캔버스를 레이아웃에 추가

        self.canvas.setFocusPolicy(Qt.StrongFocus)
        self.canvas.setFocus()

        # 각종 이벤트에 대한 리스너(콜백 함수) 연결
        self.canvas.mpl_connect("button_press_event", self.on_press)
        self.canvas.mpl_connect("button_release_event", self.on_release)
        self.canvas.mpl_connect("motion_notify_event", self.on_motion)
        self.canvas.mpl_connect("key_press_event", self.on_key_press)
        self.canvas.mpl_connect("key_release_event", self.on_key_release)

    # 마우스 버튼이 눌렸을 때 호출되는 메소드
    def on_press(self, event):
        print(f"Mouse button pressed at ({event.xdata:.2f}, {event.ydata:.2f})")
        print(f"Mouse button is ({event.button}, it is clicked with the pressed key {event.key})")
        print(f"Mouse button is double clicked: {event.dblclick}")
        print('------------------------\n')

    # 마우스 버튼이 떼어졌을 때 호출되는 메소드
    def on_release(self, event):
        print("Mouse button released")
        print('------------------------\n')

    # 마우스가 움직였을 때 호출되는 메소드
    def on_motion(self, event):
        if event.xdata is not None and event.ydata is not None:  # 마우스 위치가 유효한 경우
            print(f"Mouse moved to ({event.xdata:.2f}, {event.ydata:.2f})")
            print('------------------------')

    # 키보드 키가 눌렸을 때 호출되는 메소드
    def on_key_press(self, event):
        print(f"Key pressed: {event.key}")
        print('------------------------\n')

    # 키보드 키가 떼어졌을 때 호출되는 메소드
    def on_key_release(self, event):
        print("Key released")
        print('------------------------\n')

# 애플리케이션 실행 부분
if __name__ == "__main__":
    app = QApplication(sys.argv)  # 애플리케이션 인스턴스 생성
    main_window = MainWindow()    # MainWindow 인스턴스 생성
    main_window.show()            # 메인 윈도우 표시
    sys.exit(app.exec())          # 애플리케이션 이벤트 루프 시작

위의 코드는 PySide6를 사용하여 Matplotlib의 FigureCanvas와 함께 이벤트 리스너를 설정하는 예제임.

이 예제에서는 마우스 및 키보드 이벤트를 감지하고 처리하는 방법을 보여줌.

  • PySide6 설정:
    • QMainWindowQVBoxLayout를 사용하여 GUI 구성요소를 설정.
    • 이를 통해 Matplotlib 캔버스가 메인 윈도우에 표시됩니다.
  • Callback Function (event listener):
    • mpl_connect 메소드를 사용하여 다양한 이벤트(마우스 클릭, 릴리즈, 움직임 및 키보드 이벤트)에 대응하는 함수를 연결함.
    • 이 함수들은 이벤트가 발생할 때 실행되어 관련 정보를 콘솔에 정보를 출력.
  • 실행과 테스트:
    • 이 스크립트를 실행하면,
    • 사용자의 마우스 및 키보드 동작에 따라 적절한 메시지가 출력되어 이벤트 처리를 확인할 수 있음.

참고로, 키보드 이벤트를 받기 위해서는 FigureCanvas가 키보드 입력에 대한 포커스를 가지고 있어야 함.

  • FigureCanvas에 포커스를 명시적으로 설정하기 위해서 setFocusPolicy를 사용하여 위젯이 키보드 입력에 대해 어떻게 반응할지 정의함.
  • Qt.StrongFocus는 키보드 및 마우스 클릭으로 포커스를 받을 수 있음을 의미하며 setFocus 메서드를 통해 FigureCanvas가 포커스를 즉시 받도록 처리함.

같이 읽어보면 좋은 자료들

2024.04.29 - [Python/PySide PyQt] - [PySide6] matplotlib 이용하기

 

[PySide6] matplotlib 이용하기

matplotlib 이용하기PyQt, PySide에서는 PyQtGraph를 통해서도 graph등을 그릴 수 있으나,대중적으로 사용되는 matplotlib를 이용할 수도 있다.PyQtGraph는 Qt vector 기반의 QGraphicsScene를 통해 상호작용이 가능한

ds31x.tistory.com

2023.07.20 - [Python/matplotlib] - [Python] matplotlib : backend란

 

[Python] matplotlib : backend란

matplotlib: backend란 matplotlib의 backend 관련자료를 정리한 문서임.Matplotlib ArchitectureMatplotlib 아키텍트는 다음과 같이 크게 3가지 레이어로 구성된다.Backend Layer :상위 layer에서 graph를 생성하는데 초점

ds31x.tistory.com