2011-10-13 5 views
3

크기 조정 이벤트가 끝나면 QWidget이 있고 일부 작업 (위젯에서 사진 새로 고침)을 수행해야합니다. 이 행동을 어떻게 잡을 수 있습니까? 사용자가 마우스 버튼을 놓아 크기 조정 작업을 모두 끝내는 순간을 포착해야합니다. 이미지 크기를 조정할 때마다 이미지를 새로 고치는 것은 좋은 방법은 아닙니다. 마우스를 놓고 크기 조정 작업이 끝난 경우에만 호출해야합니다.Qt 사용자 크기 조정 이벤트가 끝납니다 (중지)

QMouseReleaseEvent를 다시 구현하려고 시도했지만 사용자가 위젯 테두리를 눌러 크기를 조절할 때 작동하지 않습니다. 그것은 우리의 상황에서 작동하지 않는다는 것을 의미합니다.

내 자신의 QSizeGrip을 만들고 내 위젯의 아래쪽에 삽입하려고했지만 이벤트 QMouseReleaseEvent가 다시 구현되지 않았습니다. 이벤트가 사용자가 마우스를 놓은 시간을 생성하지 않았습니다. 나는 이유를 모른다.

누구나 그 문제를 해결할 수 있습니까?

미리 감사드립니다.

답변

1

Windows 장식의 마우스 이벤트는 기본 창 시스템에서 관리하므로 시도한대로 잡을 수 없습니다. 나는 한 번 같은 문제가 발생했다. 내가 선택한 솔루션은 각 resize 이벤트에서 단일 QTimer를 시작하고 타이머 간격이 경과 한 후에 만 ​​업데이트를 처리하는 것이었다. 별로 섹시하지는 않지만 다른 해결 방법을 찾지 못했습니다.

1

또 다른 방법은 응용 프로그램의 이벤트 필터를 설치하고 응용 프로그램의 모든 이벤트를 가져오고 마우스 누름과 마우스를 놓아 버리고 창을 업데이트하지 않는 것입니다 사이 .

"QCoreApplication :: instance()에 이벤트 필터를 설치하십시오. 이러한 이벤트 필터는 모든 위젯에 대한 모든 이벤트를 처리 할 수 ​​있으므로 notify()를 다시 구현하는 것만 큼 강력 할뿐만 아니라 둘 이상을 가질 수도 있습니다. 하나의 응용 프로그램 전역 이벤트 필터 전역 이벤트 필터는 비활성화 된 위젯에 대한 마우스 이벤트를 참조합니다. 응용 프로그램 이벤트 필터는 주 스레드에있는 개체에 대해서만 호출됩니다. "

3

나는이 방법으로 그것을 할 것 :

  1. 이는 QWidget에서 내 클래스를 상속
  2. 개인 int 변수 timerId가 = 0
  3. 과부하는 QWidget :: resizeEvent하고있는 QObject :: TimerEvent를
정의
void MapLoader::resizeEvent(QResizeEvent *){ 
    if (timerId){ 
     killTimer(timerId); 
     timerId = 0; 
    } 
    timerId = startTimer(5000/*delay beetween ends of resize and your action*/); 
} 

void MapLoader::timerEvent(QTimerEvent *te){ 
    /*your actions here*/ 
    killTimer(te->timerId()); 
    timerId = 0; 
} 
3

시간 초과 인 방법은 괜찮은 생각이지만 사용자가 크기를 조정하고 타이머 간격보다 오래 동안 일시 중지하면 실제 "사용자가 창 크기 조정 완료"이벤트를받지 못하게됩니다. 간격을 길게 설정하면 상황이 어려워 지지만 그렇게하면 사용자가 크기 조정을 마친 시간과 함수가 호출 된 시간 사이에 긴 지연이 발생하게됩니다. 솔루션을 찾는 데있어 타이머 메소드를 사용하여 해결하는 사람들이 꽤 많았으므로 일부 유스 케이스에서는 충분히 신뢰할 만하지만 분명히 조금 이상하다고 생각합니다.

나는 mhstnsc의 아이디어가 마음에 든다. 그래서 그것을 구현 한 후에 비슷한 것을하려고하는 누군가에게 쓸모있는 코드를 추가하기로 결정했다. m_bUserIsMoving 플래그를 만들고 "void MainWindow :: moveEvent (QMoveEvent * pEvent)"를 재정 의하여 "사용자가 창 이동 중"이벤트를 쉽게 잡을 수 있습니다.사용자가 크기 조정이나 창 이동을 마칠 때마다 구성 파일을 저장하기 위해이 파일을 사용하므로 앱이 부정한 방법으로 강제 종료 되더라도 마지막 위치가 항상 저장됩니다.

// constructor 
MainWindow::MainWindow(QWidget* pParent, Qt::WindowFlags flags) : QMainWindow(pParent, flags) 
{ 
    m_bUserIsResizing = false; 
    qApp->installEventFilter(this); 
} 

// this will be called when any event in the application occurs 
bool MainWindow::eventFilter(QObject* pObj, QEvent* pEvent) 
{ 
    // We need to check for both types of mouse release, because it can vary on which type happens when resizing. 
    if ((pEvent->type() == QEvent::MouseButtonRelease) || (pEvent->type() == QEvent::NonClientAreaMouseButtonRelease)) { 
     QMouseEvent* pMouseEvent = dynamic_cast<QMouseEvent*>(pEvent); 
     if ((pMouseEvent->button() == Qt::MouseButton::LeftButton) && m_bUserIsResizing) { 
      printf("Gotcha!\n"); 
      m_bUserIsResizing = false; // reset user resizing flag 
     } 
    } 
    return QObject::eventFilter(pObj, pEvent); // pass it on without eating it 
} 

// override from QWidget that triggers whenever the user resizes the window 
void MainWindow::resizeEvent(QResizeEvent* pEvent) { m_bUserIsResizing = true; } 

타이머보다 약간 복잡하지만 강력합니다.

관련 문제