0

Is it possible to use a different mouse cursor when dragging a floating QDockWidget? Neither QWidget::setCursor nor QApplication::setOverrideCursor have any effect.

Vojislav Stojkovic
  • 8,043
  • 4
  • 35
  • 48
  • Are you willing to modify Qt itself? You could contribute this QDockWidget feature to Qt 5.1. – peppe Feb 18 '13 at 10:58
  • @peppe It's an interesting idea. I'll look into it at some point and if it's feasible, I might do it, but that won't help me for the project I'm working on now. – Vojislav Stojkovic Feb 18 '13 at 12:54
  • What happens if you setCursor on the main window? It should get the cursor from its parent widget. – paulm Feb 23 '13 at 00:20

1 Answers1

1

A floating QDockWidget is a window, so you need to ask the OS to change the cursor when it's on the non-client area.

A little buggy example for 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);
}

I think the code is self-explanatory, byut don't hesitate to ask if there something you don't understand.

The buggy part, is that I never receive WM_NCLBUTTONUP messages and I don't know why (I get WM_NCMOUSEMOVE instead) neither WM_NCMOUSEHOVER (which is the "enter event" for non-client area).

minirop
  • 326
  • 2
  • 10
  • I was hoping for a platform-agnostic solution, but it seems there's none. The reason why you never get WM_NLCBUTTONUP is something I ran into before and found that it's already documented: https://bugreports.qt-project.org/browse/QTBUG-1358 – Vojislav Stojkovic Feb 21 '13 at 17:46