MEP27: 백엔드에서 pyplot 분리 #
상태 번호
진전
브랜치 및 풀 리퀘스트 #
주요 PR(GTK3 포함):
백엔드 특정 분기 차이점:
초록 #
이 MEP는 백엔드를 리팩터링하여 보다 구조화되고 일관된 API를 제공하여 일반 코드를 제거하고 기존 코드를 통합합니다. 이를 위해 분할을 제안합니다.
FigureManagerBase
파생 클래스를 핵심 기능 클래스FigureManager
와 백엔드 특정 클래스WindowBase
로ShowBase
및 그 파생 클래스는Gcf.show_all
및MainLoopBase
.
자세한 설명 #
이 MEP는 백엔드 API를 하나의 단일 API로 통합하여 백엔드에서 일반 코드(
_pylab_helpers
및 포함 Gcf
)를 제거하고 코드를 matplotlib에서 보다 적절한 수준으로 푸시하는 것을 목표로 합니다. 이를 통해 때때로 캔버스를 설정하고 다른 경우에는 백엔드에 따라 전체 창을 지정된 크기로 설정하는 것과 같이 백엔드에 나타나는 불일치를 자동으로 제거합니다
.FigureManagerBase.resize(w, h)
FigureManagerBase
일반 코드의 두 가지 주요 위치는 및 에서 파생된 클래스에 나타납니다
ShowBase
.
FigureManagerBase
현재 세 가지 직업이 있습니다.문서는 그것을 pyplot 모드의 도우미 클래스로 설명하고 모든 것을 깔끔한 번들로 묶습니다.
그러나 캔버스와 도구 모음을 래핑할 뿐만 아니라 창 작업 자체도 모두 수행합니다. 이 두 작업의 결합은 다음 줄에서 가장 잘 보입니다. 이것은 백엔드 특정 코드 를 matplotlib 일반 코드와 결합합니다 .
self.set_window_title("Figure %d" % num)
self.set_window_title(title)
title = "Figure %d" % num
현재 백엔드 특정 하위 클래스는
FigureManager
메인 루프를 종료할 시기를 결정합니다. 그림이 다른 그림을 제어할 수 없어야 하므로 이것은 또한 매우 잘못된 것 같습니다.
ShowBase
두 가지 직업이 있습니다.그것은 등록된 모든 피규어 매니저를 훑어
_pylab_helpers.Gcf
보고 그들에게 자신을 보여달라고 말하는 일을 합니다.mainloop
두 번째로 메인 프로그램을 차단하여 수치가 죽지 않도록 하는 특정 백엔드를 수행하는 작업이 있습니다.
구현 #
이 MEP에 대한 설명은 대부분의 솔루션을 제공합니다.
FigureManagerBase
다른 백엔드 클래스와 함께 이 새 클래스를 간단히 래핑하도록 허용하지 않고 윈도우 측면을 제거합니다 .WindowBase
에 대한 통과 메서드(:arrow_right:)를 사용하여 이 기능을 처리할 수 있는 새 클래스를 만듭니다WindowBase
.WindowBase
서브클래싱하는 클래스 는 이전 버전과의 호환성을 보장하기 위해 GUI 특정 창 클래스도 서브 클래싱 해야 합니다( ).manager.window == manager.window
루프의 끝도 캡슐화하는
ShowBase
into 의 메인 루프를 리팩터링합니다 .MainLoopBase
우리는 exit 메서드를 잠금 해제하는 키로 인스턴스를 제공합니다MainLoop
(FigureManager
루프가 종료되기 전에 모든 키가 반환되어야 함). 이렇게 하면 여러 백엔드가 동시에 실행될 가능성이 열립니다.이제
FigureManagerBase
백엔드 세부 사항이 없으므로 이름을 로 바꾸고 다음FigureManager
을 나타내는 새 파일로 이동backend_managers.py
합니다.FigureManagerBase
이를 통해 기존 클래스와 해당 종속성을 그대로 유지할 수 있으므로 백엔드를 별도의 PR로 변환할 수 있습니다.그리고 이것은 또한 새로운
NavigationBase
것이 백엔드 독립으로 변형된 MEP22를 예상ToolManager
합니다.
FigureManagerBase(캔버스, 숫자) |
FigureManager(그림, 숫자) |
|
메모 |
---|---|---|---|
보여 주다 |
보여 주다 |
||
파괴하다 |
모든 구성 요소에 대해 destroy를 호출합니다. |
파괴하다 |
|
full_screen_toggle |
로직 처리 |
set_fullscreen |
|
크기 조정 |
크기 조정 |
||
키 누름 |
키 누름 |
||
get_window_title |
get_window_title |
||
set_window_title |
set_window_title |
||
_get_toolbar |
FigureManagerBase의 모든 하위 클래스에 대한 공통 메서드 |
||
set_default_size |
|||
add_element_to_window |
쇼베이스 |
MainLoopBase |
메모 |
---|---|---|
메인루프 |
시작하다 |
|
끝 |
하위 클래스의 인스턴스가 더 이상 존재하지 않으면 자동으로 호출됩니다. |
|
__전화__ |
메서드가 Gcf.show_all로 이동됨 |
향후 호환성 #
MEP 22에 대해 논의할 때 위에서 언급하지 않은 것처럼 이 리팩터를 통해 새로운 일반 기능을 쉽게 추가할 수 있습니다. 현재 MEP 22는 FigureManagerBase
. 이 코드를 사용하면 단일 FigureManager
클래스에서만 작성하면 됩니다. 이것은 또한 이후의 지원 중단을
매우 간단하게 만들고 단일 클래스 NavigationToolbar2
만 건드리면 됩니다.FigureManager
MEP 23은 이 리팩터링된 코드가 매우 유용한 또 다른 사용 사례를 만듭니다.
이전 버전과의 호환성 #
모든 백엔드 코드를 그대로 두고 기존 클래스에 누락된 메서드만 추가하므로 모든 사용 사례에서 원활하게 작동해야 합니다. FigureManager.resize
유일한 차이점은 API의 표준화로 인해 창이 아닌 캔버스 크기를 조정 하는 데 사용되는 백엔드에
있습니다.
나는 이 리팩터링에 의해 더 이상 사용되지 않는 클래스가 더 이상 사용되지 않고 같은 시간표에서 제거될 것이라고 생각합니다.
또한 생성자 NavigationToolbar2
에 대한 호출 서명의 변경 사항에 유의하십시오. FigureCanvasWx
다른 모든 것과 동일한 방식으로 제거됩니다.
백엔드 |
매니저.리사이즈(w,h) |
추가의 |
---|---|---|
gtk3 |
창문 |
|
Tk |
캔버스 |
|
Qt |
창문 |
|
Wx |
캔버스 |
FigureManagerWx는
|
대안 #
동일한 문제를 해결하기 위한 대체 솔루션이 있는 경우 선택한 접근 방식에 대한 정당성과 함께 여기에서 논의해야 합니다.
질문 #
Mdehoon: 여러 백엔드를 동시에 실행하는 방법에 대해 자세히 설명해 주시겠습니까?
OceanWolf: @mdehoon, 내가 말했듯이 이 MEP를 위한 것은 아니지만 이 MEP가 미래의 가능성으로 열어준다고 봅니다. 기본적으로 MainLoopBase
클래스는 백엔드 Gcf당 역할을 하며, 이 MEP에서는 백엔드당 열린 그림 수를 추적하고 해당 백엔드에 대한 메인 루프를 관리합니다. 해당 백엔드에 대해 열려 있는 수치가 없음을 감지하면 백엔드 특정 메인 루프를 닫습니다. 이 때문에 약간의 조정만으로 전체 다중 백엔드 matplotlib를 수행할 수 있다고 생각합니다. 왜 그렇게 하고 싶은지는 아직 모르지만 MainLoopBase에 가능성을 남겨둡니다. 모든 백엔드 코드 세부 사항이 리팩터링 FigureManager
되어 이를 지원하므로 한 명의 관리자가 모든 백엔드를 관리합니다.
Mdehoon: @OceanWolf, 알겠습니다. 설명 감사합니다. 백엔드에 대한 균일한 API를 갖는 것은 matplotlib의 유지 관리에 매우 중요합니다. 저는 이 MEP가 올바른 방향으로 나아가는 단계라고 생각합니다.