简体   繁体   中英

Trouble with QCursor setting the color of cursor

C++ == language.

QT library.

Using the qt library I am having trouble figuring out exactly how I can go about changing the color of the cursor for my UI with bitmap, or some other means. Any suggestions would be awesome!

Thank you for your time.

To change the cursor shape or even to use custom cursors, QCursor can be used.

It provides a variety of constructors to create cursors in distinct ways:

QCursor::QCursor(const QPixmap &pixmap, int hotX = -1, int hotY = -1)

Constructs a custom pixmap cursor.

pixmap is the image. It is usual to give it a mask (set using QPixmap::setMask()). hotX and hotY define the cursor's hot spot.

If hotX is negative, it is set to the pixmap().width()/2. If hotY is negative, it is set to the pixmap().height()/2.

Valid cursor sizes depend on the display hardware (or the underlying window system). We recommend using 32 x 32 cursors, because this size is supported on all platforms. Some platforms also support 16 x 16, 48 x 48, and 64 x 64 cursors.

See also QPixmap::QPixmap() and QPixmap::setMask() .


QCursor::QCursor(const QBitmap &bitmap, const QBitmap &mask, int hotX = -1, int hotY = -1)

Constructs a custom bitmap cursor.

bitmap and mask make up the bitmap. hotX and hotY define the cursor's hot spot.

If hotX is negative, it is set to the bitmap().width()/2. If hotY is negative, it is set to the bitmap().height()/2.

The cursor bitmap (B) and mask (M) bits are combined like this:

  • B=1 and M=1 gives black.
  • B=0 and M=1 gives white.
  • B=0 and M=0 gives transparent.
  • B=1 and M=0 gives an XOR'd result under Windows, undefined results on all other platforms.

Use the global Qt color Qt::color0 to draw 0-pixels and Qt::color1 to draw 1-pixels in the bitmaps.

Valid cursor sizes depend on the display hardware (or the underlying window system). We recommend using 32 x 32 cursors, because this size is supported on all platforms. Some platforms also support 16 x 16, 48 x 48, and 64 x 64 cursors.

See also QBitmap::QBitmap() and QBitmap::setMask() .


QCursor::QCursor(Qt::CursorShape shape)

Constructs a cursor with the specified shape.

See Qt::CursorShape for a list of shapes.

So, for a colored custom cursor, the constructor with pixmap has to be used.

With QWidget::setCursor() , a custom cursor can be applied to a specific widget.

I prepared an MCVE to demonstrate the various cursor types - testQCursorShape.cc :

// Qt header:
#include <QtWidgets>

// main application
int main(int argc, char **argv)
{
  qDebug() << "Qt Version:" << QT_VERSION_STR;
  QApplication app(argc, argv);
  // setup data
#if 0 // bitmap bits
  const quint32 bitmap[32] = {
    //|0  |4  |8  |12 |16 |20 |24 |28 |32
    0b00000000000000000000000000000000,//- 0
    0b00000000000000000001000000000100,//
    0b00000000000000000011100000001110,//
    0b00000000000000000001110000011100,//
    0b00000000000000000000111000111000,//- 4
    0b00000000000000000000011101110000,//
    0b00000000000000000000001111100000,//
    0b00000000000000000000000111000000,//
    0b00000000000000000000001111100000,//- 8
    0b00000000000000000000011101110000,//
    0b00000000000000000000111000111000,//
    0b00000000000000000001110000011100,//
    0b00000000000000000011100000001110,//- 12
    0b00000000000000000001000000000100,//
    0b00000000000000000000000000000000,//
    0b00000000000000000000000000000000,//
    0b00000000000000000000000000000000,//- 16
    0b00000000000000000000000000000000,//
    0b00000000000000000000000000000000,//
    0b00000000000000000000000000000000,//
    0b00000000000000000000000000000000,//- 20
    0b00000000000000000000000000000000,//
    0b00000000000000000000000000000000,//
    0b00000000000000000000000000000000,//
    0b00000000000000000000000000000000,//- 24
    0b00000000000000000000000000000000,//
    0b00000000000000000000000000000000,//
    0b00000000000000000000000000000000,//
    0b00000000000000000000000000000000,//- 28
    0b00000000000000000000000000000000,//
    0b00000000000000000000000000000000,//
    0b00000000000000000000000000000000,//
  };
  const quint32 mask[32] = {
    //|0  |4  |8  |12 |16 |20 |24 |28 |32
    0b00000000000000000001000000000100,//- 0
    0b00000000000000000011100000001110,//
    0b00000000000000000111110000011111,//
    0b00000000000000000011111000111110,//
    0b00000000000000000001111101111100,//- 4
    0b00000000000000000000111111111000,//
    0b00000000000000000000011111110000,//
    0b00000000000000000000001111100000,//
    0b00000000000000000000011111110000,//- 8
    0b00000000000000000000111111111000,//
    0b00000000000000000001111101111100,//
    0b00000000000000000011111000111110,//
    0b00000000000000000111110000011111,//- 12
    0b00000000000000000011100000001110,//
    0b00000000000000000001000000000100,//
    0b00000000000000000000000000000000,//
    0b00000000000000000000000000000000,//- 16
    0b00000000000000000000000000000000,//
    0b00000000000000000000000000000000,//
    0b00000000000000000000000000000000,//
    0b00000000000000000000000000000000,//- 20
    0b00000000000000000000000000000000,//
    0b00000000000000000000000000000000,//
    0b00000000000000000000000000000000,//
    0b00000000000000000000000000000000,//- 24
    0b00000000000000000000000000000000,//
    0b00000000000000000000000000000000,//
    0b00000000000000000000000000000000,//
    0b00000000000000000000000000000000,//- 28
    0b00000000000000000000000000000000,//
    0b00000000000000000000000000000000,//
    0b00000000000000000000000000000000,//
  };
#endif // 0
  const quint32 bitmap[32] = {
    0x00000000,
    0x00001004,
    0x0000380e,
    0x00001c1c,
    0x00000e38,
    0x00000770,
    0x000003e0,
    0x000001c0,
    0x000003e0,
    0x00000770,
    0x00000e38,
    0x00001c1c,
    0x0000380e,
    0x00001004,
    0x00000000,
    0x00000000,
    0x00000000,
    0x00000000,
    0x00000000,
    0x00000000,
    0x00000000,
    0x00000000,
    0x00000000,
    0x00000000,
    0x00000000,
    0x00000000,
    0x00000000,
    0x00000000,
    0x00000000,
    0x00000000,
    0x00000000,
    0x00000000,
  };
  const quint32 mask[32] = {
    0x00001004,
    0x0000380e,
    0x00007c1f,
    0x00003e3e,
    0x00001f7c,
    0x00000ff8,
    0x000007f0,
    0x000003e0,
    0x000007f0,
    0x00000ff8,
    0x00001f7c,
    0x00003e3e,
    0x00007c1f,
    0x0000380e,
    0x00001004,
    0x00000000,
    0x00000000,
    0x00000000,
    0x00000000,
    0x00000000,
    0x00000000,
    0x00000000,
    0x00000000,
    0x00000000,
    0x00000000,
    0x00000000,
    0x00000000,
    0x00000000,
    0x00000000,
    0x00000000,
    0x00000000,
    0x00000000,
  };
  // setup GUI
  // bit map cursor
  const QBitmap qBitmap
    = QBitmap::fromData(QSize(32, 32), (const uchar*)bitmap);
  const QBitmap qBitmapMask
    = QBitmap::fromData(QSize(32, 32), (const uchar*)mask);
  const QCursor qCursorBitmap(qBitmap, qBitmapMask, 7, 7);
  // pixmap cursor
  const QPixmap qPixmap("pencil.png");
  const QCursor qCursorPixmap(qPixmap, 2, 30);
  enum {
    TypeDefault, TypeShape, TypeBitmap, TypePixmap
  };
  // main window
  QWidget qWinMain;
  qWinMain.setWindowTitle(QString::fromUtf8("Test Custom Cursor Shape"));
  QGridLayout qGrid;
  QButtonGroup qTglGrp;
  QRadioButton qTglCursorDefault("Default");
  qTglCursorDefault.setChecked(true);
  qTglGrp.addButton(&qTglCursorDefault, TypeDefault);
  qGrid.addWidget(&qTglCursorDefault, 0, 0);
  QRadioButton qTglCursorShape("Cursor with QCursorShape");
  qTglGrp.addButton(&qTglCursorShape, TypeShape);
  qGrid.addWidget(&qTglCursorShape, 1, 0);
  QRadioButton qTglCursorBitmap("Bitmap Cursor");
  qTglGrp.addButton(&qTglCursorBitmap, TypeBitmap);
  qGrid.addWidget(&qTglCursorBitmap, 2, 0);
  QRadioButton qTglCursorPixmap("Pixmap Cursor");
  qTglGrp.addButton(&qTglCursorPixmap, TypePixmap);
  qGrid.addWidget(&qTglCursorPixmap, 3, 0);
  QFrame qFrmTest;
  qFrmTest.setFrameStyle(QFrame::Panel | QFrame::Sunken);
  qFrmTest.setFixedSize(256, 256);
  qGrid.addWidget(&qFrmTest, 0, 1, 5, 1);
  qWinMain.setLayout(&qGrid);
  // install signal handlers
  QObject::connect(&qTglGrp, QOverload<int>::of(&QButtonGroup::buttonClicked),
    [&](int choice) {
      switch (choice) {
        default:
        case TypeDefault: qFrmTest.unsetCursor(); break;
        case TypeShape: qFrmTest.setCursor(Qt::PointingHandCursor); break;
        case TypeBitmap: qFrmTest.setCursor(qCursorBitmap); break;
        case TypePixmap: qFrmTest.setCursor(qCursorPixmap); break;
      }
    });
  qWinMain.show();
  // runtime loop
  return app.exec();
}

A CMakeLists.txt to prepare VS solution:

project(QCursorShape)

cmake_minimum_required(VERSION 3.10.0)

set_property(GLOBAL PROPERTY USE_FOLDERS ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

find_package(Qt5Widgets CONFIG REQUIRED)

include_directories("${CMAKE_SOURCE_DIR}")

add_executable(testQCursorShape testQCursorShape.cc)

target_link_libraries(testQCursorShape Qt5::Widgets)

and the used image file pencil.png which is prepared with an alpha channel (for transparency):

铅笔.png

Compiled and tested with VS2017 and Qt 5.13 (on Windows 10):

testQCursorShape 的动画快照

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM