반응형
QScrollbar는 QAbstractSlider를 상속받았다.
따라서 QAbstractSlider에 있는 valueChanged(int value) signal을 받을 수 있다.
// 코드 작성 방법
connect( scrollArea->verticalScrollbar, SIGNAL(valueChanged(int)), this, SLOT(onValueChanged(int)) );
그러나 valueChanged(int) 시그널은 사용자의 스크롤 휠의 움직임뿐만 아니라 내부적으로 scrollbar의 위치가 바꼈을 때도 시그널을 준다.
(예를 들어 scrollarea의 range크기가 바껴서 자동으로 scrollbar의 위치가 바껴도, signal을 전달함.)
그러나 내가 그 시그널은 불필요하고, 사용자의 휠 움직임 시그널만 받고싶다면?
QWheelEvent 함수를 재정의해서 사용한다.
// 코드 작성 방법
// header file
protected :
virtual void wheelEvent(QWheelEvent*); //protected virtual 타입
// cpp file
void wheelEvent(QWheelEvent* e)
{
// 원하는 동작
}
그러나 만약 본래의 동작을 유지하고 싶다면 문제가 있다.
본래 wheelEvent 함수를 재정의한 것이기 때문에 scrollbar가 움직이지 않는다.
해결 방법은 2가지가 있다.
(1) wheelEvent가 발생했을 때 scrollbar를 직접 제어.
(2) eventFilter에서 wheelEvent에 대한 시그널 받기
나는 사용자가 마우스 휠을 움직였다는 시그널만 받으면 되는 것이기때문에 두 번째 방법을 택했다.
(또한 스크롤바는 해당 cpp 파일에 있지 않고, 이걸 생성해준 다른 cpp파일에 있어서 시그널을 보내고 한 차례 더 복잡해지기 때문에....)
// 2번째 방법) 코드 작성 방법
// header file
private :
virtual bool eventFilter(QObject* o, QEvent* e);
// cpp file
this->installEventFilter(this); // 이벤트 등록 필수
bool eventFilter(QObject* o, QEvent* e)
{
if( e->type == QEvent::Wheel)
{
QWheelEvent* we = static_cast<QWheelEvent*>(e);
if( we->orientation() == Qt::Vertical )
{
wheelEvent(we); //마우스 휠 움직임에 따른 scrollbar 움직이기.
/*
원하는 동작 작성
*/
return true; // 경고!
}
else
{
return false;
}
}
return true;
}
// 경고! eventFilter 함수 내에서 받은 receiver object를 지운다면, true를 반환시켜야 한다. 그렇지 않을 경우, Qt가 해당 ojbect를 지울 것이고, crash가 발생한다.
동작 잘됌~~ 테스트 완료 !
반응형