Langsamer QGraphicsEffect [Gelöst]

Alles rund um die Programmierung mit Qt
Antworten
master_caster<*>()
Beiträge: 5
Registriert: 15. September 2011 13:53
Kontaktdaten:

Langsamer QGraphicsEffect [Gelöst]

Beitrag von master_caster<*>() »

Hallo Leute,

Ich bin neu hier und möchte damit nicht ausschließen das ich die Suchfunktion noch nicht richtig beherrsche :D .
Ich habe ein Problem mit einer Klasse die von QGraphicsEffect erbt. Es geht um folgendes:

Stellt euch eine QGroupBox vor auf der weitere widgets liegen. Hier sei angemerkt das diese nicht mit einem Layout oder sowas ausgerichtet werden.
Die ausrichtung wird anhand eines festgelegten "Rasters" gemacht.

Sagen wir die QGroupBox ist 100x100 pixel groß und ich gebe als "rastergröße" 10x10 pixel ein, habe ich 10 virtuelle "kästchen" horizontal und vertikal,
auf denen die Widgets angeordnet werden können. Wie beim Qt Designer möchte ich jetzt ein widget per Drag and Drop Operation hinzufügen. Das geht soweit auch schon und
die widgets werden auch richtig positioniert. Während des DragMove events möchte ich dem Benutzer anzeigen wo das neue Widget platziert werden würde, wenn er jetzt
den Drop macht (also die maus los lässt). Die Anzeige wo das neue Widget hinkommen würde funktioniert insofern auch schon das das richtige Kästchen errechnet und mit einem
QGraphicsEffect gefüllt wird (ich zeichne einfach eine linie von Startpunkt zum Endpunkt mit entsprechender Linienstärke). Die Zeichenmethode des abgeleiteten QGraphicsEffects sieht wie folgt aus:

Code: Alles auswählen

void HighlightDropPositionEffect::draw(QPainter * painter)
{
    //mRasterSize ist vom Typ QSizeF und wurde vorher gesetzt
    QPoint offset;
    const QPixmap pixmap = sourcePixmap(Qt::DeviceCoordinates, &offset);
    QPen pen(mColor, (qreal)mRasterSize.height(), Qt::SolidLine, Qt::FlatCap, Qt::RoundJoin);
    QTransform restoreTransform = painter->worldTransform();

    painter->save();
    painter->setWorldTransform(QTransform());
    painter->drawPixmap(offset, pixmap);
    painter->setPen(pen);

    //mStartPosition und mEndPosition sind jeweils vom Typ QPoint und enthalten die
    //Koordinaten wo die Linie gezeichnet werden soll.
    mStartPosition.setY(mStartPosition.y() + (mRasterSize.height() / 2));
    mStartPosition.setX(mStartPosition.x() + offset.x());
    mStartPosition.setY(mStartPosition.y() + offset.y());
    mEndPosition.setX(mStartPosition.x() + mRasterSize.width());
    mEndPosition.setY(mStartPosition.y());

    painter->drawLine(mStartPosition, mEndPosition);
    painter->setWorldTransform(restoreTransform);
    painter->restore();
}
Wohl gemerkt grundsätzlich funktioniert alles einwandfrei. Allerdings ist das Zeichnen sehr sehr langsam.
Meine vermutung ist das bei der neu Positionierung des Effekts alle Widgets mit neu gezeichnet werden, da die CPU last stark nach oben geht dabei.

Hat jemand eine Idee wie ich das Zeichnen schneller hinbekomme? Da bei normaler Mausbewegung die Markierung der DropPosition
stark hinterher hängt, ist sie quasi wertlos. Erst wenn man 2 - 3 Sekunden auf einer Position stehen bleibt ist die richtige DropPosition
markiert.

Danke im vorraus

// edit franzf: Code-Tags eingefügt.
Zuletzt geändert von master_caster<*>() am 14. November 2011 12:31, insgesamt 1-mal geändert.
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Re: Langsamer QGraphicsEffect

Beitrag von franzf »

MMn. ist hier QGraphicsEffect die falsche Klasse.
Effects alter the appearance of elements by hooking into the rendering pipeline and operating between the source (e.g., a QGraphicsPixmapItem) and the destination device (e.g., QGraphicsView's viewport).
Das hineinhooken wird schon so seine Performance kosten. Wahrscheinlich bist du mit einem Overlay besser dran (Google "QWidget Overlay" als Start), du malst ja nur ne zusätzliche Linie, die absolut unabhängig (außer der Position) deines gedroppten Widgets ist.
master_caster<*>()
Beiträge: 5
Registriert: 15. September 2011 13:53
Kontaktdaten:

Re: Langsamer QGraphicsEffect

Beitrag von master_caster<*>() »

Herzlichen Dank für die schnelle Antwort ich probiers mal sofort aus.
Ich melde mich wenn sich neue Probleme auftun bzw. wenn ichs gelöst habe. xD
master_caster<*>()
Beiträge: 5
Registriert: 15. September 2011 13:53
Kontaktdaten:

Re: Langsamer QGraphicsEffect

Beitrag von master_caster<*>() »

Also ich bin bis jetzt noch nicht wirklich weiter gekommen.
Ich dachte mir zum veranschaulichen des Problems habe ich eine demo Anwendung geschrieben

die ich mal hier anhängen werde. Der Ansatz mit dem Overlay wird aber noch weiter
verfolgt. :D

Ich verwende den compiler der beim visual studio 2005 dabei ist.
Das sind alle sourcen, denke das sollte reichen um einen Eindruck davon zu bekommen.
Da das Programm jetzt sehr klein ist empfiehlt es sich die debug version zu starten damit
man das auch merkt. Im beiliegenden eventfilter wird das paint event abgefangen. Wenn man das auskommentiert
wirds deutlich schneller, näheres ist aber im quelltext erklärt. Einfach durchkompilieren, starten und aus dem listview
ein item dragen und über die groupbox hovern. Viel spaß und nochmals Danke für eure Hilfe.
Dateianhänge
BeispielProgramm.rar
Sourcen zum testen
(8.72 KiB) 122-mal heruntergeladen
master_caster<*>()
Beiträge: 5
Registriert: 15. September 2011 13:53
Kontaktdaten:

Re: Langsamer QGraphicsEffect

Beitrag von master_caster<*>() »

Hallo Leute,

ist nun doch ne weile her aber ich wollte mal wieder was schreiben, damit dieser thread gelesen und später auch als gelöst markiert werden kann.
Also es sieht wie folgt aus. Da die Funktionalität mit dem QGraphicsEffect gegeben war habe ich mich erst um andere sachen gekümmert.
Ich hatte jetzt aber das Drag and Drop handling etwas umstrukturiert bei mir im programm und komme jetzt wieder hierauf zurück.

Also ich hab wie empfohlen mal bei google nach qwidget und overlay gesucht. Viele berufen sich da auf die openGL Abteilung von Qt,
was bei mir aber nicht möglich ist da die widgets mit denen ich Arbeite und den effekt drauf zeichne aus einem Generator kommen, welcher
auch in anderen Projekten verwendet wird und so müsste man alles anpassen.

Stattdessen hab ich nen weiteren link gefunden, in dem einfach nen anderes qwidget verwendet wird.
Hierbei wird der hintergrund bis auf spezielle bereiche transparent gezeichnet und ich mache während der dragmove operation
nur ein widget->move(destinationPoint);

Das mach subjektive nen besseren Eindruck aber hab da jetzt noch nen kleinen bug das sich das dingen nicht soweit bewegt wie es sollte :D
da muss ich nochmal nachgucken.
Bin aber nach wie vor dankbar für neue Ansätze bzw. einfachere Möglichekeiten, falls es die denn gibt.

Die Overlayklasse sieht wie folgt aus:

Code: Alles auswählen

class Overlay : public QFrame
{
    public:
        Overlay(QWidget *parent);
    protected:
        void paintEvent(QPaintEvent *event);
};

Code: Alles auswählen

Overlay::Overlay(QWidget *parent) : QFrame(parent)
{
    setPalette(Qt::transparent);
    setAttribute(Qt::WA_TransparentForMouseEvents);
    setFrameShadow(QFrame::Sunken);
}

void Overlay::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.setPen(QPen(Qt::red));
    painter.drawLine(width()/8, height()/8, 7*width()/8, 7*height()/8);
    painter.drawLine(width()/8, 7*height()/8, 7*width()/8, height()/8);
}
master_caster<*>()
Beiträge: 5
Registriert: 15. September 2011 13:53
Kontaktdaten:

Re: Langsamer QGraphicsEffect

Beitrag von master_caster<*>() »

Dank des Tips von franzf habe ich nun das was ich wollte.
ich zeichne ein transparentes Widget mit einem Rahmen drum um dem Nutzer zu zeigen wo die neuen Objekte erstellt werden würden.
Ich geh mal davon aus das man das noch etwas performanter hinbekommt als bei der Implementierung die ich gemacht habe aber es läuft jetzt sehr flüssig.

Wenn jemand ein ähnliches Problem hat / hatte und aus dem thread nicht genau erkennen kann wie ich das Problem gelöst habe kann mich gerne
anschreiben.

Das Problem kann als gelöst betrachtet werden.

PS.: kann ich den thread irgendwie auf "Gelöst" setzen?
toba
Beiträge: 28
Registriert: 22. September 2011 09:28

Re: Langsamer QGraphicsEffect

Beitrag von toba »

den ersten post editieren und Theradtitel abändern :)
Antworten