Qt: 경계 없는 창 이동

2073 단어 Qt
무테두리 창을 이동하는 코드는 인터넷에 매우 많은데, 그 원리는 모두 같지만, 문제가 있다. 나는 단지 그것을 수정할 뿐이다
인터넷상의 코드는 단지 두 개의 사건을 실현하였다
void EditDialog::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        m_DragPosition = event->globalPos() - this->pos();
        event->accept();
    }
}

void EditDialog::mouseMoveEvent(QMouseEvent *event)
{
    if (event->buttons() && Qt::LeftButton) {
        move(event->globalPos() - m_DragPosition);
        event->accept();
    }
}

그러나 이렇게 하면 문제가 하나 있다. 마우스가mousePressEvent를 실현한 클래스에서 눌렀을 때 (예: QPushButton) 이 클래스가 이 이벤트를 우선적으로 처리한다는 것이다.
창의 mousePressEvent에 이벤트를 전달하지 않습니다.계속, 마우스를 이 단추 밖으로 이동할 때 (QPush Button에 눌렸다고 가정하면) 창의 mouse Move Event를 터치합니다.
이로 인해 좌표를 계산할 때 오류가 발생하면 창이 깜빡이고 위치가 바뀌며 마우스가 앞에서 눌린 버튼 위에 멈추지 않는 것을 볼 수 있다.
해결 방법도 간단하다. 책 변수를 하나 더 성명해서 판단하고, mouse Release Event를 실현하면 된다
void EditDialog::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        m_Drag = true;
        m_DragPosition = event->globalPos() - this->pos();
        event->accept();
    }
}

void EditDialog::mouseMoveEvent(QMouseEvent *event)
{
    if (m_Drag && (event->buttons() && Qt::LeftButton)) {
        move(event->globalPos() - m_DragPosition);
        event->accept();
    }
}

void EditDialog::mouseReleaseEvent(QMouseEvent *)
{
    m_Drag = false;
}

이렇게 하면 테두리 없는 창의 드래그가 완성됩니다.그러나 이렇게 하는 효율은 높지 않다. 왜냐하면 마우스가 매번 move를 할 때마다 이벤트를 촉발하고 위치를 계산하며 창을 이동하고 다시 그리기 때문이다.
창에 QWebView 위젯이 있을 때, 특히 웹 페이지에 그림이 있고, Flash가 있을 때, 위의 방안으로 창을 이동할 때 매우 원활하지 않다는 것을 발견할 수 있다.
 
여러 플랫폼을 고려하지 않고 Windows 플랫폼만을 대상으로 한다면, 나는 Windows에서 표준적인 방법으로 제목 표시줄로 메시지를 이동하는 것을 모의하여 간단하면서도 효율적으로
void MainWindow::mousePressEvent(QMouseEvent *event)
{
    if (ReleaseCapture())
        SendMessage(HWND(this->winId()), WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);
    event->ignore();
}

이렇게 하면 창을 드래그할 때 마우스를 놓을 때만 창을 옮길 수 있어 첫 번째 방법의 저효율 문제를 피할 수 있다

좋은 웹페이지 즐겨찾기