본문 바로가기
SWE/Qt

QScrollbar가 움직였을 때 signal 전달받는 방법 / valueChanged(int) / QWheelEvent(QWheelEvent)

by S나라라2 2019. 11. 27.
반응형

QScrollbar는 QAbstractSlider를 상속받았다.

따라서 QAbstractSlider에 있는 valueChanged(int value) signal을 받을 수 있다.

QAbstractSlider의 시그널

 

// 코드 작성 방법
connect( scrollArea->verticalScrollbar, SIGNAL(valueChanged(int)), this, SLOT(onValueChanged(int)) );

 

 

그러나 valueChanged(int) 시그널은 사용자의 스크롤 휠의 움직임뿐만 아니라 내부적으로 scrollbar의 위치가 바꼈을 때도 시그널을 준다.

(예를 들어 scrollarea의 range크기가 바껴서 자동으로 scrollbar의 위치가 바껴도, signal을 전달함.)

 

그러나 내가 그 시그널은 불필요하고, 사용자의 휠 움직임 시그널만 받고싶다면?

QWheelEvent 함수를 재정의해서 사용한다.

 

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가 발생한다.

 

동작 잘됌~~ 테스트 완료 !

반응형