Изменение курсора мыши при перетаскивании плавающего QDockWidget

Можно ли использовать другой курсор мыши при перетаскивании плавающего QDockWidget? Ни QWidget::setCursor, ни QApplication::setOverrideCursor не действуют.


person Vojislav Stojkovic    schedule 14.02.2013    source источник
comment
Готовы ли вы изменить сам Qt? Вы можете добавить эту функцию QDockWidget в Qt 5.1.   -  person peppe    schedule 18.02.2013
comment
@peppe Это интересная идея. Я рассмотрю это в какой-то момент, и если это осуществимо, я могу это сделать, но это не поможет мне в проекте, над которым я сейчас работаю.   -  person Vojislav Stojkovic    schedule 18.02.2013
comment
Что произойдет, если вы установите курсор в главном окне? Он должен получить курсор от своего родительского виджета.   -  person paulm    schedule 23.02.2013


Ответы (1)


Плавающее QDockWidget — это окно, поэтому вам нужно попросить ОС изменить курсор, когда он находится в неклиентской области.

Небольшой глючный пример для windows:

#define WINVER 0x0500
#include <windows.h>
#include <windowsx.h>
#include <winuser.h>
bool DockWidget::winEvent(MSG * message, long * result)
{
    switch(message->message)
    {
        case WM_NCMOUSEMOVE:
            if(message->wParam == HTCAPTION)
            {
                qDebug() << "WM_NCMOUSEMOVE";
                if(!cursorHasBeenChanged && !cursorHasBeenClosed)
                {
                    cursorHasBeenChanged = true;
                    QApplication::setOverrideCursor(Qt::OpenHandCursor);
                }
            }
            else
                if(cursorHasBeenChanged)
                {
                    cursorHasBeenChanged = false;
                    QApplication::restoreOverrideCursor();
                }
            break;
        case WM_NCMOUSELEAVE:
            qDebug() << "WM_NCMOUSELEAVE";
            if(cursorHasBeenChanged && !cursorHasBeenClosed)
            {
                cursorHasBeenChanged = false;
                QApplication::restoreOverrideCursor();
            }
            break;
        case WM_NCLBUTTONDOWN:
            if(message->wParam == HTCAPTION)
            {
                qDebug() << "WM_NCLBUTTONDOWN";
                cursorHasBeenClosed = true;
                QApplication::setOverrideCursor(Qt::ClosedHandCursor);
            }
            break;
        case WM_NCLBUTTONUP:
            qDebug() << "WM_NCLBUTTONUP";
            if(cursorHasBeenClosed)
            {
                cursorHasBeenClosed = false;
                QApplication::restoreOverrideCursor();
            }
            break;
        default:
            ;
    }

    return QDockWidget::winEvent(message, result);
}

Я думаю, что код не требует пояснений, но не стесняйтесь спрашивать, если вы что-то не понимаете.

Глючная часть заключается в том, что я никогда не получаю сообщения WM_NCLBUTTONUP, и я не знаю почему (вместо этого я получаю WM_NCMOUSEMOVE) ни WM_NCMOUSEHOVER (которое является «событием ввода» для неклиентской области).

person minirop    schedule 21.02.2013
comment
Я надеялся на независимое от платформы решение, но, похоже, его нет. Я уже сталкивался с причиной, по которой вы никогда не получаете WM_NLCBUTTONUP, и обнаружил, что это уже задокументировано: bugreports.qt-project.org/browse/QTBUG-1358 - person Vojislav Stojkovic; 21.02.2013