PyQt5: Как установить собственный указатель мыши для каждой роли? - PullRequest
5 голосов
/ 15 мая 2019

1.Введение

Я создаю приложение в Python 3.7 с PyQt5 для графического интерфейса.Я хотел бы настроить курсоры мыши в приложении.

Давайте начнем со стандартного курсора, установленного в Qt5 , как показано в таблице здесь: https://doc.qt.io/qt-5/qt.html#CursorShape-enum. Вы заметите, чтоQt5 имеет специальный Enum Qt::CursorShape, описывающий роль соответствующего курсора.Например:

Qt standard cursors


Я хотел бы заменить каждый Стандартный курсор Qt на обычай сделанный:

Custom cursors


2.Первый подход

Сначала я попробовал что-то вроде этого:

pixmap = QPixmap("C:/../my_arrow.png")
cursor = QCursor(pixmap, 32, 32)
QApplication.setOverrideCursor(cursor)

К сожалению, этот подход не подходит для моих целей.Из документации:

Курсоры переопределения приложений предназначены для показа пользователю, что приложение находится в особом состоянии , например, во время операции, которая может занять некоторое время.

Курсор переопределения будет отображаться во всех виджетах приложения до тех пор, пока не будет вызван restoreOverrideCursor() или другой setOverrideCursor().

Другими словами, использование подхода setOverrideCursor() имеет два недостатка:

  1. Мне нужно было бы вручную отследить, на какую роль должен меняться указатель мыши, каждый раз вызывать setOverrideCursor() и выдавать ему правильные QCursor().

  2. Мне нужно было бы отслеживать, где Qt автоматически вызывает restoreOverrideCursor(), потому что это эффективно отменяет мои собственные изменения.Это было бы постоянное сражение против Qt.


3.Второй подход

Мой второй подход состоял в том, чтобы поиграть с функцией setCursor():

pixmap = QPixmap("C:/../Arrow.png")
cursor = QCursor(pixmap, 32, 32)
my_widget.setCursor(cursor)

Я делаю это на виджете верхнего уровня - QMainWindow() - так, чтобы эффект применялся квсе приложение.

Отлично работает, но имеет один недостаток.Эта функция изменяет только «курсор по умолчанию» (указывающая стрелка), но это все.Все специальные курсоры все те же.


На самом деле я хотел бы сделать что-то вроде этого:

# Note: 'mainwin' is the QMainWindow().
mainwin.setCursor( QCursor(QPixmap("C:/../Arrow.png"),     32, 32), Qt.ArrowCursor     )
mainwin.setCursor( QCursor(QPixmap("C:/../UpArrow.png"),   32, 32), Qt.UpArrowCursor   )
mainwin.setCursor( QCursor(QPixmap("C:/../Cross.png"),     32, 32), Qt.CrossCursor     )
mainwin.setCursor( QCursor(QPixmap("C:/../Wait.png"),      32, 32), Qt.WaitCursor      )
mainwin.setCursor( QCursor(QPixmap("C:/../IBeam.png"),     32, 32), Qt.IBeamCursor     )
mainwin.setCursor( QCursor(QPixmap("C:/../SizeVer.png"),   32, 32), Qt.SizeVerCursor   )
mainwin.setCursor( QCursor(QPixmap("C:/../SizeHor.png"),   32, 32), Qt.SizeHorCursor   )
mainwin.setCursor( QCursor(QPixmap("C:/../SizeBDiag.png"), 32, 32), Qt.SizeBDiagCursor )
mainwin.setCursor( QCursor(QPixmap("C:/../SizeFDiag.png"), 32, 32), Qt.SizeFDiagCursor )
...

К сожалению, функция setCursor() работает не так.


У вас есть решение, которое наилучшим образом соответствует моим целям?

4.Ресурсы

Я многому научился из следующих источников:

К сожалению, ни один из них не дал решения моей проблемы.Я просто упоминаю их здесь, потому что они связаны - но не так (!) - с тем, что я пытаюсь сделать.

...