PDA

View Full Version : QGraphicsDropShadowEffect causing a QPainter error



Berryblue031
18th March 2011, 14:38
Has anybody come across

QGraphicsDropShadowEffect throwing the following error?

QPainter::begin: A paint device can only be painted by one painter at a time.
QPainter::translate: Painter not active

I am adding a bit of flourish in my app and when I try to put a dropshadow on widgets that are in a QStackedWidget (I am not sure if this is what is causing the crash) I am getting a crash in

void QGraphicsDropShadowEffect::draw(QPainter *painter)

JohannesMunk
20th March 2011, 01:32
Could you create and post a minimal example application that shows the error?

Joh

Berryblue031
23rd March 2011, 11:35
Unfortunately when I try to reproduce it in a minimal example it doesn't happen, but in my main app it is still there. Can you think of any general scenarios that could trigger something like this?

Added after 1 4 minutes:

Also it only happens when I am mousing over the shadowed widget if I just switch between them in the stack panel everything is fine, but something that happens when mousing over triggers the paint errors.

Sparhawk
27th March 2011, 19:43
I have the same problem with QGraphicsOpacityEffect on a QStackedWidget. I try to extend QStackedWidget to get fade effects or transitions when you change the page (using currentIndex) on QStackedWidget. But I can't reproduce on a small application.

This is the code of the extenden QStackedWidget. Are there something wrong?



#ifndef GRAPHICSSTACKEDWIDGET_H
#define GRAPHICSSTACKEDWIDGET_H

#include <QStackedWidget>

class GraphicsStackedWidgetPrivate;

class GraphicsStackedWidget : public QStackedWidget
{
Q_OBJECT
Q_PROPERTY (int currentIndex READ currentIndex WRITE setCurrentIndex)
Q_PROPERTY (double windowOpacity READ windowOpacity WRITE setWindowOpacity DESIGNABLE isWindow)

private:
GraphicsStackedWidgetPrivate *d;
Q_DECLARE_PRIVATE(GraphicsStackedWidget)

public:
GraphicsStackedWidget(QWidget *parent = 0);
~GraphicsStackedWidget();

int currentIndex() const;
Q_INVOKABLE int addWidget(QWidget *w);

public slots:

private slots:
void setCurrentIndex ( int index );
bool hidePage();
void showPage();
};

#endif // GRAPHICSSTACKEDWIDGET_H

-----------------------------------------------------------

#include "graphicsstackedwidget.h"
#include <QtGui>
#include <QGraphicsLinearLayout>

#define TRANSITION_TIME_MS 500

class GraphicsStackedWidgetPrivate
{
public:
int m_index;
GraphicsStackedWidgetPrivate() {
}
};


GraphicsStackedWidget::GraphicsStackedWidget(QWidg et *parent):
QStackedWidget(parent),
d(new GraphicsStackedWidgetPrivate)
{
d->m_index = 0;
}

GraphicsStackedWidget::~GraphicsStackedWidget()
{
delete d;
}

int GraphicsStackedWidget::currentIndex() const
{
return QStackedWidget::currentIndex();
}

void GraphicsStackedWidget::setCurrentIndex ( int index )
{
d->m_index = index;
if ( hidePage() ) {
QTimer::singleShot(TRANSITION_TIME_MS/2, this, SLOT(showPage()));
} else {
showPage();
}
}

int GraphicsStackedWidget::addWidget(QWidget *w)
{
return QStackedWidget::addWidget(w);
}

bool GraphicsStackedWidget::hidePage()
{
bool result = false;
QWidget *oldWidget = QStackedWidget::widget(QStackedWidget::currentInde x());
if ( oldWidget != NULL ) {
QGraphicsOpacityEffect *effect = new QGraphicsOpacityEffect(oldWidget);
oldWidget->setGraphicsEffect(effect);
QPropertyAnimation *animation = new QPropertyAnimation(effect, "opacity", this);
animation->setDuration(TRANSITION_TIME_MS/2);
animation->setStartValue(1);
animation->setEndValue(0);
animation->start();
QTimer::singleShot(TRANSITION_TIME_MS/2, oldWidget, SLOT(repaint()));
result = true;
}
return result;
}

void GraphicsStackedWidget::showPage()
{
QWidget *widget = QStackedWidget::widget(d->m_index);
if ( widget != NULL ) {
QGraphicsOpacityEffect *effect = new QGraphicsOpacityEffect(widget);
widget->setGraphicsEffect(effect);
QPropertyAnimation *animation = new QPropertyAnimation(effect, "opacity", this);
animation->setDuration(TRANSITION_TIME_MS/2);
animation->setStartValue(0);
animation->setEndValue(1);
animation->start();
QTimer::singleShot(TRANSITION_TIME_MS/2, widget, SLOT(repaint()));
}
QStackedWidget::setCurrentIndex(d->m_index);
if ( widget != NULL ) {
widget->update();
}
}




Thanks a lot