QWidget의 계층 구조를 시각화하는 디버그 지원 도구

5759 단어 Qt
Qt Advent Calendar 2016 14일째의 기사입니다.

QWidget의 계층 구조를 시각화하는 디버그 지원 툴 WidgetBrowser 을 만들었습니다.

소개



대규모 응용 프로그램 개발에서는 화면에 보이는 위젯이 어디에서 구현되는지 모르는 경우가 많습니다. 표시되어 있는 문자열로 검색할 수도 있습니다만, 클래스명을 알면 보다 효율적으로 해당 소스 코드를 찾을 수 있습니다.

Qt에서는, 선언중에 Q_OBJECT 매크로를 포함한 클래스이면 클래스명을 알 수 있으므로, 예를 들어 커서아래에 있는 위젯의 클래스명을 조사하는 것이 가능합니다.

그래서 위젯의 계층 구조를 따라 클래스 이름을 조사 할 수있는 WidgetBrowser 도구를 개발했습니다.



설치



기본적으로 응용 프로그램에 내장되어 사용합니다.

WidgetBrowsergit clone 하고 src/wb 디렉토리를 애플리케이션에 복사하여 빌드 대상에 포함시킵니다.

시작하려면 wb::WbDialog::exec()를 호출하면 괜찮습니다. WbDialog 클래스가 자동으로 QApplication 객체로부터 정보를 모아 표시합니다.

example
#include <wb/dialog.h>

wb::WbDialog dialog;
dialog.exec();

또한 이벤트 필터 WbOpenListenerQApplication에 설치하여 바로 가기 키로 시작할 수 있습니다.

example
#include <QApplication>
#include <QKeySequence>
#include <wb/listener.h>

WbOpenListener listener;
listener.setKeySequenceToOpen(QKeySequence("Meta+F2"));
qApp->installEventfilter(&listener);

응용 프로그램 소스 코드를 변경할 수없는 경우 WidgetBrowser가 포함 된 Qt DLL
빌드하고 교체하는 방법을 사용할 수 있습니다 (대상이 LGPL 버전 Qt를 사용하고 있다면).

사용법



시작되면 해당 시점의 위젯 계층 구조가 캡처되어 왼쪽 트리에 표시됩니다.

최상위 요소는 다음 5가지입니다.
  • Active Modal 위젯
    활성 모달 위젯 (QApplication::activeModalWidget() 값)
  • Active Popup Widget
    활성 팝업 위젯 (QApplication::activePopupWidget() 값)
  • Focus Widget
    포커스가있는 위젯 (QApplication::focusWidget() 값)
  • Widget at Cursor
    커서 아래 위젯 (QApplication::widgetAt(QCursor::pos()) 값)
  • Top Level Widgets
    최상위 위젯 (QApplication::topLevelWidgets() 값)

  • 이들은 시작된 순간의 값이며 업데이트되지 않습니다.



    트리에서 위젯을 선택하면 오른쪽에 위젯 스크린샷이 표시됩니다.

    트리에서 컨텍스트 메뉴에서 위젯의 클래스 이름을 복사할 수 있습니다.
    스크린샷에서 이미지를 저장할 수 있습니다.

    대화 상자를 닫으면 응용 프로그램에 처리를 반환합니다.

    만드는 법



    트리 뷰는 위젯의 계층 구조를 나타내는 항목 모델을 만들고 사용합니다.
  • QAbstractItemModel을 구현하여 트리 뷰 만들기 (Read Only)

  • 스크린샷은 QWidget::render 를 호출하여 이미지를 가져오기 때문에 부작용이 있습니다. 또한 한 번도 show() 되지 않은 위젯은 잘못된 이미지가 될 수 있습니다.
    QWidget* widget;
    QLabel* label;
    
    const QRect rectangle(QPoint(), widget->size());
    QPixmap pixmap(rectangle.size());
    widget->render(&pixmap, QPoint(), QRegion(rectangle));
    
    label->setPixmap(pixmap);
    

    클래스명을 카피하는 기능은 이하와 같이 구현하고 있습니다.cpp
    void copyClassName(QWidget* widget) {
    QApplication::clipboard()->setText(widget->metaObject()->className());
    }

    원하는 기능



    주말에 Hackason으로 만든 도구이므로 현시점에서의 기능은 적습니다.

    QtDesigner의 속성 편집기 기능을 추가하고 싶습니다.



    요약



    큰 프로젝트에서는 검색의 키워드로서 클래스명을 알고 싶은 것이 있으므로 툴을 만들었습니다(덤으로 스크린샷도 붙여 보았습니다).

    좋은 웹페이지 즐겨찾기