Was läuft in paintEvent() falsch?

Alles rund um die Programmierung mit Qt
Antworten
B4chi
Beiträge: 13
Registriert: 14. April 2009 07:58

Was läuft in paintEvent() falsch?

Beitrag von B4chi »

Hallo,

erstmal ein netten Gruß an alle hier. Hoffe ihr könnt mir helfen.

Ich erstelle eine Klasse die von QWidget ableitet.
Mit Klasse = new Klasse(...) kreiere ich Sie und es funktioniert so wie es soll. Erstelle ich aber eine zweite Klasse wird nicht mehr das gemalt was ich erwarte. Woran liegt das und was amche ich falsch?

WaitSymbol.h

Code: Alles auswählen

#include <QWidget>

namespace Test
{
    class WaitSymbol : public QWidget
    {
        Q_OBJECT

        public:
            // Konstruktor
            WaitSymbol(QRect rect,
                       unsigned int lines_base,
                       QColor color_base,
                       unsigned int lines_top,
                       QColor color_top,
                       double opacity
                       );
            ~WaitSymbol();

            // Eigenschaften
            void setPosition(QPoint pos);
            void setSize(QSize size);
            void setOpacity(double opacity);
            void Enabled(bool enabled);
            void Visible(bool visible);

        private:
            QColor        color_base;        // Grundfarbe des Symbols
            QColor        color_top;          // Funktionsfarbe
            QRect          rect;                 // Position und Größe
            QPoint         pos;                  // Position
            QSize          size;                 // Größe
            bool            enabled;            // Aktiv / Inaktiv
            bool            visible;              // Sichtbar / Unsichtbar
            double         opacity;            // Transparenz
            unsigned int lines_base;       // Anzahl der Linien
            unsigned int lines_top;         // Anzahl der aktiven Linien

        protected:
            void paintEvent(QPaintEvent *event);

    };
}
WaitSymbol.cpp

Code: Alles auswählen

void WaitSymbol::paintEvent(QPaintEvent *event)
{
    if(visible)
    {
        static unsigned int state = 0;
        int side = width() / 2;

        QPainter painter(this);
        painter.setRenderHint(QPainter::Antialiasing);
        painter.translate(width() / 2, height() / 2);   // Mittelpunkt festlegen

        QPoint Line[4] =
        {
            QPoint((int) (side*0.08),(int)(side*0.5)),
            QPoint((int)-(side*0.08),(int)(side*0.5)),
            QPoint((int)-(side*0.08),(int)(side*0.9)),
            QPoint((int) (side*0.08),(int)(side*0.9))
        };

        if(enabled)
        {
            if(state == lines_base)
                state = 0;

            painter.rotate((360.0/(qreal)lines_base)*(qreal)state);

            // Basis malen
            painter.save();
            painter.setBrush(color_base);
            painter.setPen(color_base);
            for (unsigned int x = 0; x < lines_base - lines_top; ++x)
            {
                painter.drawConvexPolygon(Line, 4);
                painter.rotate(360.0/lines_base);
            }

            // Top malen
            painter.setBrush(color_top);
            painter.setPen(color_top);
            for (unsigned int x = 0; x < lines_top; ++x)
            {
                painter.setOpacity((qreal)(x+1)/(qreal)(lines_top-1.0)*1.0);
                painter.drawConvexPolygon(Line, 4);
                painter.rotate(360.0/lines_base);
            }
            painter.restore();

            state++;
        }
        else
        {
            // Basis malen
            painter.save();
            painter.setBrush(color_base);
            painter.setPen(color_base);
            for (unsigned int x = 0; x < lines_base; ++x)
            {
                painter.drawConvexPolygon(Line, 4);
                painter.rotate(360.0/lines_base);
            }
            painter.restore();
            state = 0;
        }
    }
}
test.cpp

Code: Alles auswählen

symbol = new WaitSymbol(QRect(10,250,40,40),
                            10,
                            QColor(20, 20, 20),
                            4,
                            QColor(255, 255, 255),
                            1.0);
    symbol->Visible(true);
    symbol->Enabled(true);
    addWidget(symbol);
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Warum implementierst du bitteschön setPos/setSize/etcetc selber, wenn QWidget das von Haus aus auch kann? (->Doku!)

painter.save() brauchst du eigentlich nur, wenn du den gespeicherten state nachher wieder herstellen musst (restore), damit du davon ausgehend weiter malen kannst. Da dein paintEvent nach dem restore Schluss macht, braucht es das echt nicht, ist nur unnötiger Overhead ;)

Und die Redundanz beim Basis malen bitte weg damit! Einfach immer Basis malen, danach abfragen ob enabled und entsprechend zeichnen.

Zu guter Letzt: Ich kann an dem paintEVent nix falsches erkennen. Und in deinem test.cpp legst du auch nur ein Objekt deiner Klasse an, weswegen man nicht sehen kann, was du mit deinem zweiten anstellst.

Bitte deshalb am besten ein vollständiges, kompilierbares Testcase in ein Zip und anhängen, wenn du nicht wirklich weißt, wo der Fehler liegen könnte.

Grüße
Franz
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Re: Was läuft in paintEvent() falsch?

Beitrag von franzf »

Kleiner Nachtrag
B4chi hat geschrieben:Erstelle ich aber eine zweite Klasse wird nicht mehr das gemalt was ich erwarte. Woran liegt das und was amche ich falsch?
Es ist natürlich wichtig zu wissen, was du erwartest. Erleuter das mal noch genauer.
Hat es etwas mit dem static unsigned int state im paintEvent zu tun? Das ist ehrlich gesagt recht - komisch... Du kannst nicht sagen, wie oft während dem Programmlauf das paintEvent aufegrufen wird. Fenster wird über deinem Widget bewegt -> paintEvent(). resize() resultiert meistens auch in einem weiteren paintEvent(). uswusf. Und du willst da in jedem Fall GANZ SICHER immer den state hochzählen? Sei dir bewusst: die static Variable in einer Methode ist für dich von außen nicht zu erreichen! Du kannst so den State nicht resetten!
B4chi
Beiträge: 13
Registriert: 14. April 2009 07:58

Beitrag von B4chi »

Hallo,

habe es grad rausbekommen. Ja, und Du hast auch recht. Das Problem lag an der static Variable. Diese ist nicht Objektweise sondern ist statisch für die ganze Klasse. Somit gibt es Probleme wenn ich mehr als nur ein WaitSymbol-Objekt erzeuge. Sie ist jetzt unter private und im Konstruktor setze ich se auf NULL. So klappt es auch mit dem Nachbarn.

Trotzdem Danke



Weitere Fragen werden sicherlich folgen. Aber zunächst muss ich mich mit Linux und PowerPC beschäftigen :o(
Antworten