Qt:绘制完成后,如何释放QPainterPath占用的内存?

Qt:绘制完成后,如何释放QPainterPath占用的内存?,qt,drawing,qpainter,Qt,Drawing,Qpainter,问题是:我想通过USB设备生成的输入数据(数据大小大于50MB)来绘制许多行。如果我使用QPainterPath::lineTo和QPainterPath::moveTo函数来绘制线条,似乎性能不好,内存不会被释放 我的环境是:带有8G RAM和Qt4.7.2的Windows7 例如,如果数据大小为50MB,则占用的内存将为200MB。当上一次绘图完成并且应用程序准备好下次绘图时,200MB将不会被释放。因此,如果我多次绘制,应用程序将崩溃。 void QRasterPaintEngine::S

问题是:我想通过USB设备生成的输入数据(数据大小大于50MB)来绘制许多行。如果我使用QPainterPath::lineTo和QPainterPath::moveTo函数来绘制线条,似乎性能不好,内存不会被释放

我的环境是:带有8G RAM和Qt4.7.2的Windows7

例如,如果数据大小为50MB,则占用的内存将为200MB。当上一次绘图完成并且应用程序准备好下次绘图时,200MB将不会被释放。因此,如果我多次绘制,应用程序将崩溃。 void QRasterPaintEngine::StrokePolygOnScometic中的异常点(常量QPointF*点、int点计数、PolygonDrawMode模式):

//绘制所有线段。
对于(int i=1;imatrix+offs;//此处出错,该点为NULL
QPointF lp2=点[i]*s->矩阵+offs;//此处错误,点为空
常数QRectF brect(lp1,lp2);
进程span penBlend=d->getPenFunc(brect,&s->penData);
如果(qpen_样式->lastPen)=Qt::SolidLine){
抽绳_中点_i(qFloor(lp1.x)),qFloor(lp1.y),,
qFloor(lp2.x()),qFloor(lp2.y()),
penBlend,&s->penData,
i==pointCount-1?最后的模式:LineDrawIncludeLastPixel,
德夫雷特);
}否则{
绘制线\中点\虚线\ i(qFloor(lp1.x()),qFloor(lp1.y()),
qFloor(lp2.x()),qFloor(lp2.y()),
&s->lastPen,
penBlend,&s->penData,
i==pointCount-1?最后的模式:LineDrawIncludeLastPixel,
devRect和dashOffset);
}
}
顺便说一下,在绘图之前,我对QPainterPath执行了删除操作,但这里似乎不起作用。有人对此有什么想法吗?谢谢

以下是我的绘图代码:

    int scaleFactor;
    double old_x, current_x;
    int current_y, oldval, newval, x_change_visible, tmp_x, tmp_y;
    int low = m_ui->renderAreaWidget->height() - 2, high = 20;
    int ch = getChannelNumber();
    uint64_t ss, se;

    if (sample_buffer == NULL)
        return;

    scaleFactor = getScaleFactor();

    if (painterPath != NULL)
        delete painterPath;
    if (dottedPath != NULL)
        delete dottedPath;
    if (textPath != NULL)
        delete textPath;

    dottedPath = new QPainterPath();
    painterPath = new QPainterPath();
    textPath = new QPainterPath();

    old_x = (getScrollBarValue() % stepSize);
    current_x = (getScrollBarValue() % stepSize);

    ss = (getScrollBarValue() + current_x) * scaleFactor / stepSize;
    se = ss + (getScaleFactor() * width()) * stepSize;
    if (se > getNumSamples()) // Do this _after_ calculating 'step'!
        se = getNumSamples();

    oldval = getbit(sample_buffer, ss, ch);
    current_y = (oldval) ? high : low;
    painterPath->moveTo(current_x, current_y);
    // add dummy line to indicate something
    if (ss < 100 && (isSetTriggerCondition || pretriggerPercent < 100)) {
        QPen pen;
        pen.setStyle(Qt::DotLine);
        bool textDrawed = false;

        bool isTextDrawed = false;
        for (int i = ss; i < 100; i += scaleFactor) {
            if (i >= 50 && i <= 60 && !isTextDrawed && pretriggerPercent != 100) {
                QFont font;
                //font.setFamily("Times");
                //font.setItalic(true);
                font.setPixelSize(18);
                textPath->addText(current_x, low + 1, font, QString("Pre-trigger %1%").arg(pretriggerPercent));

                isTextDrawed = true;
            }

            for (int j = 0; (j < scaleFactor) && (i + j < 100); j++) {
                dottedPath->lineTo(current_x, low);
                current_x += (double)stepSize / (double)scaleFactor;
            }
        }
        zeroX = current_x;
    }

    //current_x = (-getScrollBarValue() % stepSize);
    bool isTriggered = false;
    int oldy = current_y;
    painterPath->moveTo(current_x - ((double)stepSize / (double)scaleFactor), low);
    painterPath->lineTo(current_x, low);
    painterPath->lineTo(current_x, current_y);
    for (uint64_t i = ss; i < se; i += scaleFactor) {
        //Process the samples shown in this step.
        for (uint64_t j = 0; (j < scaleFactor) && (i + j < se); j++) {
           newval = (i + j < numSamples ? getbit(sample_buffer, i + j, ch): newval); // sample buffer is the data buffer, size is about 50M. getbit function is about to determine the specific byte in target channel is high or low.
            x_change_visible = current_x > old_x;
            if (oldval != newval && x_change_visible) {
                painterPath->lineTo(current_x, current_y);
                current_y = (newval) ? high : low;
                if (current_y != oldy && !isTriggered) {
                    isTriggered = true;
                    emit(triggerValue(getChannelNumber(), i));
                }
                painterPath->lineTo(current_x, current_y);
                old_x = current_x;
                oldval = newval;
            }
            current_x += (double)stepSize / (double)scaleFactor;
            oldy = current_y;
        }
    }
    current_x += stepSize;
    painterPath->lineTo(current_x, current_y);
int scaleFactor;
双倍旧_x,当前_x;
int current_y、oldval、newval、x_change_visible、tmp_x、tmp_y;
int low=m_ui->rendereawidget->height()-2,high=20;
int ch=getChannelNumber();
uint64_t ss,东南部;
if(sample_buffer==NULL)
返回;
scaleFactor=getScaleFactor();
if(painterPath!=NULL)
删除painterPath;
if(dottedPath!=NULL)
删除点路径;
if(textPath!=NULL)
删除文本路径;
dottedPath=新的QPainterPath();
painterPath=新的QPainterPath();
textPath=新的QPainterPath();
old_x=(getScrollBarValue()%stepSize);
当前_x=(getScrollBarValue()%stepSize);
ss=(getScrollBarValue()+当前x)*缩放因子/步长;
se=ss+(getScaleFactor()*宽度())*步长;
if(se>getNumSamples())//在计算“步骤”之后执行此操作!
se=getNumSamples();
oldval=getbit(采样缓冲区,ss,ch);
当前值y=(旧值)?高:低;
画师路径->移动到(当前x,当前y);
//添加虚线来表示某事
如果(ss<100&(isSetTriggerCondition | | pretriggerPercent<100)){
QPen笔;
pen.setStyle(Qt::DotLine);
bool textprauded=false;
bool istextdrauded=false;
对于(int i=ss;i<100;i+=scaleFactor){
如果(i>=50&&i addText(当前x,低+1,字体,QString(“预触发%1%”)arg(预触发百分比));
isTextDrawed=真;
}
对于(int j=0;(jlineTo(当前x,低);
当前_x+=(双)步长/(双)缩放因子;
}
}
zeroX=当前_x;
}
//当前_x=(-getScrollBarValue()%stepSize);
bool-isTriggered=false;
int oldy=当前值;
painterPath->moveTo(当前_x-((双)步长/(双)缩放因子),低);
painterPath->lineTo(当前x,低);
画师路径->行到(当前x,当前y);
对于(uint64_t i=ss;i旧_x;
如果(oldval!=newval&&x\u更改\u可见){
画师路径->行到(当前x,当前y);
当前_y=(新值)?高:低;
如果(当前的_y!=旧的&&!已触发){
isTriggered=真;
emit(triggerValue(getChannelNumber(),i));
}
画师路径->行到(当前x,当前y);
旧_x=当前_x;
oldval=newval;
}
当前_x+=(双)步长/(双)缩放因子;
oldy=当前_y;
}
}
当前_x+=步长;
画师路径->行到(当前x,当前y);

每个数据样本是一个字节,我将每个样本绘制为高压或低压,具体取决于它的值。

我找到了解决方案并与您共享。正如我上面发布的示例代码一样,我在绘制之前删除了paintEvent函数中的QPainterPath,但它不起作用。因此,我在跳到paintEvent之前移动了删除操作,这可以释放QPainterPath占用的内存。感谢您的所有建议。:)

你是如何衡量内存使用率的?@Arnold Spence:我使用windonw任务管理器来监控内存资源。@Stephen Chu:我发布了我的绘图代码。使用后删除画师路径,或者更好,在堆栈上创建它们,而不是使用指针和新的。@FrankOsterfeld:谢谢重播,但这是一个操作
    int scaleFactor;
    double old_x, current_x;
    int current_y, oldval, newval, x_change_visible, tmp_x, tmp_y;
    int low = m_ui->renderAreaWidget->height() - 2, high = 20;
    int ch = getChannelNumber();
    uint64_t ss, se;

    if (sample_buffer == NULL)
        return;

    scaleFactor = getScaleFactor();

    if (painterPath != NULL)
        delete painterPath;
    if (dottedPath != NULL)
        delete dottedPath;
    if (textPath != NULL)
        delete textPath;

    dottedPath = new QPainterPath();
    painterPath = new QPainterPath();
    textPath = new QPainterPath();

    old_x = (getScrollBarValue() % stepSize);
    current_x = (getScrollBarValue() % stepSize);

    ss = (getScrollBarValue() + current_x) * scaleFactor / stepSize;
    se = ss + (getScaleFactor() * width()) * stepSize;
    if (se > getNumSamples()) // Do this _after_ calculating 'step'!
        se = getNumSamples();

    oldval = getbit(sample_buffer, ss, ch);
    current_y = (oldval) ? high : low;
    painterPath->moveTo(current_x, current_y);
    // add dummy line to indicate something
    if (ss < 100 && (isSetTriggerCondition || pretriggerPercent < 100)) {
        QPen pen;
        pen.setStyle(Qt::DotLine);
        bool textDrawed = false;

        bool isTextDrawed = false;
        for (int i = ss; i < 100; i += scaleFactor) {
            if (i >= 50 && i <= 60 && !isTextDrawed && pretriggerPercent != 100) {
                QFont font;
                //font.setFamily("Times");
                //font.setItalic(true);
                font.setPixelSize(18);
                textPath->addText(current_x, low + 1, font, QString("Pre-trigger %1%").arg(pretriggerPercent));

                isTextDrawed = true;
            }

            for (int j = 0; (j < scaleFactor) && (i + j < 100); j++) {
                dottedPath->lineTo(current_x, low);
                current_x += (double)stepSize / (double)scaleFactor;
            }
        }
        zeroX = current_x;
    }

    //current_x = (-getScrollBarValue() % stepSize);
    bool isTriggered = false;
    int oldy = current_y;
    painterPath->moveTo(current_x - ((double)stepSize / (double)scaleFactor), low);
    painterPath->lineTo(current_x, low);
    painterPath->lineTo(current_x, current_y);
    for (uint64_t i = ss; i < se; i += scaleFactor) {
        //Process the samples shown in this step.
        for (uint64_t j = 0; (j < scaleFactor) && (i + j < se); j++) {
           newval = (i + j < numSamples ? getbit(sample_buffer, i + j, ch): newval); // sample buffer is the data buffer, size is about 50M. getbit function is about to determine the specific byte in target channel is high or low.
            x_change_visible = current_x > old_x;
            if (oldval != newval && x_change_visible) {
                painterPath->lineTo(current_x, current_y);
                current_y = (newval) ? high : low;
                if (current_y != oldy && !isTriggered) {
                    isTriggered = true;
                    emit(triggerValue(getChannelNumber(), i));
                }
                painterPath->lineTo(current_x, current_y);
                old_x = current_x;
                oldval = newval;
            }
            current_x += (double)stepSize / (double)scaleFactor;
            oldy = current_y;
        }
    }
    current_x += stepSize;
    painterPath->lineTo(current_x, current_y);