QCursor mit Transparenz

Alles rund um die Programmierung mit Qt
Antworten
linuQs
Beiträge: 26
Registriert: 16. August 2009 11:28

QCursor mit Transparenz

Beitrag 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
kater
Beiträge: 306
Registriert: 29. Dezember 2009 01:13
Wohnort: Darmstadt

Beitrag 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.
linuQs
Beiträge: 26
Registriert: 16. August 2009 11:28

Beitrag 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
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Der QCursor-ctor möchte nunmal zwei Bitmaps, nicht ein Pixmap und ein Bitmap...
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
kater
Beiträge: 306
Registriert: 29. Dezember 2009 01:13
Wohnort: Darmstadt

Beitrag von kater »

Ah jetzt hab ich kapiert was er will. Einen farbigen Cursor der an einigen Stellen transparent ist?
linuQs
Beiträge: 26
Registriert: 16. August 2009 11:28

Beitrag 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 :(
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag 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.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
kater
Beiträge: 306
Registriert: 29. Dezember 2009 01:13
Wohnort: Darmstadt

Beitrag 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); 
linuQs
Beiträge: 26
Registriert: 16. August 2009 11:28

Beitrag 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 ) );
Antworten