【问题标题】:Trouble with QCursor setting the color of cursorQCursor 设置光标颜色的问题
【发布时间】:2020-04-24 03:45:16
【问题描述】:

C++ == 语言。

QT 库。

使用 qt 库时,我无法准确弄清楚如何使用位图或其他方式更改 UI 的光标颜色。任何建议都会很棒!

感谢您的宝贵时间。

【问题讨论】:

    标签: c++ qt user-interface


    【解决方案1】:

    要更改光标形状甚至使用自定义光标,可以使用QCursor

    它提供了多种构造函数来以不同的方式创建游标:

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

    构造一个自定义像素图光标。

    像素图是图像。通常给它一个掩码(使用 QPixmap::setMask() 设置)。 hotX 和 hotY 定义了光标的热点。

    如果 hotX 为负数,则设置为 pixmap().width()/2。如果 hotY 为负数,则设置为 pixmap().height()/2。

    有效的光标大小取决于显示硬件(或底层窗口系统)。我们建议使用 32 x 32 游标,因为所有平台都支持此大小。一些平台还支持 16 x 16、48 x 48 和 64 x 64 光标。

    另见QPixmap::QPixmap()QPixmap::setMask()


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

    构造一个自定义位图光标。

    位图和掩码组成位图。 hotX 和 hotY 定义了光标的热点。

    如果 hotX 为负数,则设置为 bitmap().width()/2。如果 hotY 为负数,则设置为 bitmap().height()/2。

    光标位图(B)和掩码(M)位组合如下:

    • B=1 和 M=1 产生黑色。
    • B=0 和 M=1 产生白色。
    • B=0 和 M=0 表示透明。
    • B=1 和 M=0 在 Windows 下给出 XOR 的结果,在所有其他平台上给出未定义的结果。

    在位图中使用全局 Qt 颜色 Qt::color0 绘制 0 像素,使用 Qt::color1 绘制 1 像素。

    有效的光标大小取决于显示硬件(或底层窗口系统)。我们建议使用 32 x 32 游标,因为所有平台都支持此大小。一些平台还支持 16 x 16、48 x 48 和 64 x 64 光标。

    另见QBitmap::QBitmap()QBitmap::setMask()


    QCursor::QCursor(Qt::CursorShape shape)

    构造一个具有指定形状的光标。

    有关形状列表,请参阅 Qt::CursorShape

    因此,对于彩色自定义光标,必须使用带有像素图的构造函数。

    使用QWidget::setCursor(),可以将自定义光标应用于特定小部件。

    我准备了一个 MCVE 来演示各种游标类型 - 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();
    }
    

    一个CMakeLists.txt准备VS解决方案:

    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)
    

    和使用的图像文件pencil.png 准备了一个alpha通道(用于透明度):

    使用 VS2017 和 Qt 5.13(在 Windows 10 上)编译和测试:

    【讨论】:

      猜你喜欢
      • 2011-11-06
      • 2015-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多