Qt에서 hitButton를 이용한 클릭영역 지정

컴글 2010. 9. 5. 23:07 posted by 배제군
http://korone.net/bbs/board.php?bo_table=qt_qna&wr_id=17786

Qt 커뮤니티에서 버튼의 hit영역 지정글 질문에 대해 테스트했다.

Qt API 에 QAbstractButton 클래스 메소드 중 hitButton 를 확인하면 아래와 같다.

bool QAbstractButton::hitButton ( const QPoint & pos ) const   [virtual protected]

Returns true if pos is inside the clickable button rectangle; otherwise returns false.

By default, the clickable area is the entire widget. Subclasses may reimplement this function to provide support for clickable areas of different shapes and sizes.


pos 가 클릭 가능한 버튼 사각형에 포함되면 true 아니면 false 를 리턴한다.
기본적으로 클릭가능한 영역은 완전한 widget이다. 하위클래스에서 클릭가능한 영역을 도형이나 크기로 지원가능하게 제공하면 재구현이 가능하다.

위의 내용를 참조로 간단하게 구현해봤다.

이미지는 위 질문링크에 포함된 이미지를 사용했고 포토샵에서 클릭영역을 확인 지정했다.



GUI 프로젝트를 생성하고 QPushButton 과 클릭여부를 확인할 QLineEdit 위젯을 알맞게 배치한다.
QPushButton 에 아이콘을 넣을 수 도 있지만 배경으로 넣는게 정렬이나 위치지정에 유용하기때문에 나같은 경우 자주이용한다.

그리고 기본적인 배치 및 클릭여부를 확인하고 QPushButton 을 재구현한 QPolygonPushButton 을 만들자.

project -> add New -> c++ -> c++ class 선택
Class name : QPolygonPushButton
Base class : QPushButton
Type info : inherits QWidget

생성 후 hitButton 가상함수를 구현하자.

qpolygonpushbutton.h 에서

private:
    virtual bool hitButton ( const QPoint & pos ) const;

를 선언한다.
 
그리고 qpolygonpushbutton.cpp 에서 hitButton 을 구현한다.

bool QPolygonPushButton::hitButton( const QPoint & pos ) const {
    QPolygon *f = new QPolygon(4);
    f->setPoint(0, 22, 0);
    f->setPoint(1, 100, 0);
    f->setPoint(2, 110, 26);
    f->setPoint(3, 15, 26);
    bool ok = f->containsPoint(pos, Qt::OddEvenFill);
    return ok;
}

질문에 나온 사다리꼴 좌표를 저장하기 위해 QPolygon 을 이용했다.
각 좌표를 박스 그리듯 순서대로 지정하고 containsPoint 함수를 이용해 pos 와 비교한다.
비교 결과를 ok 로 리턴하게 만들면 함수는 완성이되고 기본 프로그램을 구성했던 QPushButton 을 지금 구현한 QPolygonPushButton 클래스로 바꾸어 다시 실행해본다.



완성된QPolygonPushButton 테스트 프로그램

사다리꼴 영역은 eventCnt 가 올라가지만 이외의 영역은 클릭판정을 받지 못한다.




음표 영역을 선택해서 올바르게 작동하는지 시험해본다.


테스트한 프로젝트 압축본

짧은작성후기.
Qt가 워낙 API가 잘 나와서 그런지 충돌영역검사도 엄청 쉽게 되어 있다.
옛날이면 충돌영역을 bit 이미지로 저장해서 검사하게 했을꺼 같은데.. ㄷㄷ.. ;;
응용하면 QPolygon 을 입력받게 하거나 이미지를 계산하게도 가능하겠다.