Seite 1 von 1

QCursor mit Transparenz

Verfasst: 20. Februar 2010 20:11
von linuQs
Hallo zusammen,
wie der Titel schon sagt wollte ich einen QCursor mit Transparenz bzw. einem transparenten Bild erzeugen. Dazu habe ich eine QPixmap geladen und mit mask() die Maske erzeugt. Dabei kam aber folgende Fehlermeldung

Code: Alles auswählen

QCursor: Cannot create bitmap cursor; invalid bitmap(s)
Selbst folgender Code funktioniert bei mir nicht, da der selbe Fehler auftritt:

Code: Alles auswählen

QPixmap pix( 20, 20 );
pix.fill( Qt::blue );
setCursor( QCursor( QBitmap(pix), pix.mask() ) );
Weiß jemand, wie man den Fehler verhindern / umgehen kann, damit man als Cursor ein transparentes png benutzen kann

Verfasst: 21. Februar 2010 01:38
von kater
Aus der Qt Hilfe:

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.

Darauf folgere ich, dass ein Bitmap wirklich nur ein Bit enthält. 0 und 1. Nicht Blau.

Du solltest QCursor eine Pixmap geben, keine Bitmap.

Verfasst: 21. Februar 2010 16:41
von linuQs
Danke für die Antowrt, aber das löst leider nicht mein anfangsproblem.
Folgdendes ist der Code aus meinem Programm:

Code: Alles auswählen

QPixmap pix( 20, 20 );
QPainter painter(&pix);
mySvgRenderer -> render(&painter,"cursor1");
setCursor( QCursor( pix ) );
Dadurch wird zwar das Bild (Svg-Element) dargestellt, die transparenten Stellen im Cursor sind aber nicht definiert (immer unterschiedlich).
Dann habe ich gelesen, dass man dazu eine Maske brauch:

Code: Alles auswählen

QPixmap pix( 20, 20 );
QPainter painter(&pix);
mySvgRenderer -> render(&painter,"cursor1");
setCursor( QCursor( pix, pix.mask() ) );
Durch diese Änderung wurde der Cursor nachher im Programm gar nicht geändert, sondern blieb beim Standard Cursor. Es kam aber die Meldung

Code: Alles auswählen

QCursor: Cannot create bitmap cursor; invalid bitmap(s)
Leider weiß ich nicht genau, was die Meldung bedeutet bzw. wie ich den Fehler beheben kann

Verfasst: 21. Februar 2010 17:34
von Christian81
Der QCursor-ctor möchte nunmal zwei Bitmaps, nicht ein Pixmap und ein Bitmap...

Verfasst: 21. Februar 2010 18:31
von kater
Ah jetzt hab ich kapiert was er will. Einen farbigen Cursor der an einigen Stellen transparent ist?

Verfasst: 21. Februar 2010 18:51
von linuQs
@kater: ja, genau das, irgendeine Idee, wie das geht?

@Christian81: Folgendes funktioniert mit dem selben Fehler auch nicht:

Code: Alles auswählen

setCursor( QCursor( QBitmap(pix), pix.mask() ) );

Code: Alles auswählen

pix.setMask(pix.mask())
setCursor( QCursor( pix ) );
Habe leider keine Ahnung wie es sonst noch funktionieren könnte :(

Verfasst: 21. Februar 2010 20:25
von Christian81
'Funktioniert nicht' - gute Fehlerbeschreibung...
Des weiteren: http://doc.trolltech.com/4.6/qpixmap.html#QPixmap-3:
Warning: This will create a QPixmap with uninitialized data. Call fill() to fill the pixmap with an appropriate color before drawing onto it with QPainter.

Verfasst: 22. Februar 2010 03:23
von kater
Versuchs mal damit. Sry. wegen den schrecklichen Code aber zumindest funktioniert es so bei mir. color0 und color1 muss man ggf. tauschen.

Code: Alles auswählen

    // Es soll ein neuer Cursor erstellt werden der blau ist
    // und seine Mitte transparent
    // Umstaendlicher geht es nicht mehr, aber QImage ist das
    // einzige Bild, welches sowas wie setPixel hat.

    // Der Cursor ist 32x32 Pixel gross und wird mit Blau gefüllt
    QImage image(32,32, QImage::Format_RGB16);
    image.fill(Qt::blue);
    
    // Die Maske ist so gross wie der Cursor und gibt an, wo er
    // transparent sein soll
    QImage imageMask(32,32, QImage::Format_Mono);
    // Laut Doku wird der Cursor transparent, wenn die Maske 0 ist
    // bei mir ist es andersrum, sie muss 1 sein
    imageMask.fill(Qt::color0);
    
    // Das innere transparente Quadrat wird erstellt
    for(int i = 10; i < 20; i++)
        for(int j = 10; j < 20; j++)
        {
            // Wie gesagt, transparent ist der Cursor dann, wenn Maske
            // und Bild 0 ist. Bei mir ist es eben genau andersrum
            imageMask.setPixel(i,j, Qt::color1);
            image.setPixel(i, j, Qt::color1);
        }
    
    // Neue Bitmap aus der Maske erstellen
    QBitmap mask(QPixmap::fromImage(imageMask));
        
    // Pixmap erstellen und Maske hinzufuegen
    QPixmap pixmap = QPixmap::fromImage(image);
    pixmap.setMask(mask);
    
    // Neuen Cursor erstellen
    QCursor cursor(pixmap);
    // Cursor zuweisen
    setCursor(cursor); 

Verfasst: 22. Februar 2010 16:18
von linuQs
Danke für den Beispielcode!
Bei mir hat auch folgendes funktioniert:

Code: Alles auswählen

QPixmap pix( 20, 20 );
pix.fill( QColor(255,255,255,0) ); //Neu
QPainter painter(&pix);
mySvgRenderer -> render(&painter,"cursor1");
setCursor( QCursor( pix ) );