错误:
QPainter::begin: Paint device returned engine == 0, type: 3
QPainter::setCompositionMode: Painter not active
QPainter::end: Painter not active, aborted
我做了一个小例子来重现这个错误,但它没有重现错误的确切性质。在原始代码中,我将这些QGraphicsSimpleTextItems(MyCallout)作为QGraphicsItem的附件,它永远不会移动,永远不会改变位置;相反,它有一个我重绘的图像,看起来像一个加载栏。文本项目是根据该栏的百分比来跟随和上移或下移。如果我向下滚动视图以使文本项不再可见,然后向上滚动,我会看到文物。具体来说,我看到我在MyCallout中使用的QGraphicsLineItem有一个略高于/低于原始版本的附加副本,并且MyCallout的文本部分已经消失。当我向左或向右滚动然后回到我看到这些QPainter错误时。这个小例子一旦创建并添加到场景中并且向上或向下滚动时就会出现这些错误,但是人工制品问题不那么明显。
小编译示例的来源:
main.cpp
#include <QApplication>
#include "mainwindowtest.h"
#include <stdio.h>
int main(int argc, char * argv[]){
QApplication app(argc,argv);
MainWindow mainWin;
mainWin.show();
int rc = app.exec();
printf("%d\n",rc);
return 0;
}
mainwindowtest.cpp
#include <QtGui>
#include "mainwindowtest.h"
#include "myviewtest.h"
#include "myscenetest.h"
MainWindow::MainWindow(){
scene = new MyScene(this);
QSize size2=QSize(100000,6000);
view = new MyView(scene,size2);
setCentralWidget(view);
}
mainwindowtest.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTableView>
#include <QListView>
#include <QSlider>
#include <QLineEdit>
#include <QLayout>
class MyView;
class MyScene;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow();
protected:
private slots:
signals:
private:
MyView *view;
QWidget * window;
MyScene * scene;
};
#endif
mycallouttest.cpp
#include <QtGui>
#include "mycallouttest.h"
#include "myscenetest.h"
MyCallout::MyCallout (QGraphicsItem* parent) : QGraphicsSimpleTextItem (parent) {
setZValue(100);
setText(QString("0:"));
setBrush(QColor("violet"));
_shadow = new QGraphicsDropShadowEffect;
_shadow->setOffset(-boundingRect().x()+1.05,-boundingRect().y()+1.05);
_shadow->setBlurRadius(0);
_shadow->setColor("black");
setGraphicsEffect(_shadow);
_line.setParentItem(this);
_line.setLine(4,boundingRect().height()+18,14,boundingRect().height()-3);
_line.setZValue(90);
_line.setPen(QColor("violet"));
hide();
}
void MyCallout::setTextTo(const QString & text){
QString a=this->text();
int i = this->text().indexOf(":");
if(i>0){
a.remove(i+1,a.size());
a.append(text);
setText(a);
}else{
printf("warning: callout text with no ':'\n");
}
}
void MyCallout::position(int col,int value){
printf("position\n");
QString label;
QString a=text();
int i = text().indexOf(":");
if(i>0){
a.remove(0,i);
a.prepend(QString(QString("%1").arg(value)));
}else{
a=QString(QString("%1:").arg(value));
}
setText(a);
setPos((col+1)*7, (MAX_ROW-value-3)*7);
prepareGeometryChange();
show();
update();
}
QRectF MyCallout::boundingRect() const{
return QGraphicsSimpleTextItem::boundingRect();
}
mycallouttest.h
#ifndef MY_CALLOUT_H
#define MY_CALLOUT_H
#include <QGraphicsSimpleTextItem>
class QGraphicsLineItem;
class QGraphicsDropShadowEffect;
class MyCallout :public QGraphicsSimpleTextItem {
//Q_OBJECT
public:
MyCallout(QGraphicsItem * parent =0);
void position(int col,int value);
void setTextTo(const QString & text);
QRectF boundingRect() const;
protected:
QGraphicsLineItem _line;
QGraphicsDropShadowEffect * _shadow;
};
#endif
myscenetest.cpp
#include <QtGui>
#include "myscenetest.h"
#include "mainwindowtest.h"
#include "mycallouttest.cpp"
MyScene::MyScene(QObject *parent) : QGraphicsScene(parent){
setSceneRect(0,0,MAX_COL*11,MAX_ROW*11);
QGraphicsScene::setBackgroundBrush (QColor(173,216,230));
MyCallout *c;
for(int i=1;i<=MAX_COL;++i){
c=new MyCallout;
c->position(i,50);
addItem(c);
}
}
myscenetest.h
#ifndef MY_SCENE_H
#define MY_SCENE_H
#include <QGraphicsScene>
#include <QList>
#include "myviewtest.h"
#define MAX_ROW 90
#define MAX_COL 360
class MyView;
class MyScene : public QGraphicsScene
{
Q_OBJECT
public:
MyScene(QObject * parent =0);
public slots:
signals:
private:
};
#endif
myviewtest.cpp
#include <QtGui>
#include "myviewtest.h"
MyView::MyView(QGraphicsScene * scene,QSize &size,QWidget *parent) : QGraphicsView(scene,parent){
setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
setDragMode(RubberBandDrag);
setMouseTracking(true);
setResizeAnchor(QGraphicsView::AnchorUnderMouse);
_zoom_level=0;
_size=size;
}
const QSize MyView::sizeHint(){
return _size;
}
void MyView::wheelEvent(QWheelEvent * event){
if(event->modifiers() & Qt::ControlModifier){
if(event->delta() > 0){
zoomIn();
centerOn(mapToScene(event->pos()));
_zoom_level--;
emit updateZoom();
} else {
zoomOut();
centerOn(mapToScene(event->pos()));
_zoom_level++;
emit updateZoom();
}
}else{
QGraphicsView::wheelEvent(event);
}
}
myviewtest.h
#ifndef MY_VIEW_H
#define MY_VIEW_H
#include <QGraphicsView>
class MyView : public QGraphicsView {
Q_OBJECT
public:
MyView(QGraphicsScene * scene,QSize &size,QWidget *parent = NULL);
virtual const QSize sizeHint();
public slots:
void zoomIn(){ scale(1.1,1.1);};
void zoomOut(){ scale(1/1.1,1/1.1);};
void wheelEvent(QWheelEvent * event);
signals:
void updateZoom();
protected:
int _zoom_level;
QSize _size;
};
#endif