USB 장치에서 생성 된 입력 데이터 (50MB 이상의 데이터 크기)로 계산 된 많은 선을 그려야합니다. QPainterPath :: lineTo 및 QPainterPath :: moveTo 함수를 사용하여 선을 그리면 성능이 좋지 않으며 메모리가 해제되지 않는 것으로 보입니다.Qt : [해결] 그리기가 끝나면 QPainterPath가 차지하는 메모리를 해제하는 방법은 무엇입니까?
내 환경은 다음과 같습니다. Windows 7 (8G RAM 및 Qt 4.7.2).
예를 들어 데이터 크기가 50MB이면 점유 된 메모리는 200MB가됩니다. 이전 도면이 완료되고 응용 프로그램이 다음에 그릴 준비가되면 200MB가 해제되지 않습니다. 따라서 여러 번 그릴 경우 응용 프로그램이 중단됩니다. 무효 QRasterPaintEngine에서 예외 포인트 : strokePolygonCosmetic (const를 QPointF * 점, INT의 pointCount, PolygonDrawMode 모드) : 그런데
// Draw all the line segments.
for (int i=1; i<pointCount; ++i) {
QPointF lp1 = points[i-1] * s->matrix + offs; // error here, the point is NULL
QPointF lp2 = points[i] * s->matrix + offs; // error here, the point is NULL
const QRectF brect(lp1, lp2);
ProcessSpans penBlend = d->getPenFunc(brect, &s->penData);
if (qpen_style(s->lastPen) == Qt::SolidLine) {
drawLine_midpoint_i(qFloor(lp1.x()), qFloor(lp1.y()),
qFloor(lp2.x()), qFloor(lp2.y()),
penBlend, &s->penData,
i == pointCount - 1 ? mode_for_last : LineDrawIncludeLastPixel,
devRect);
} else {
drawLine_midpoint_dashed_i(qFloor(lp1.x()), qFloor(lp1.y()),
qFloor(lp2.x()), qFloor(lp2.y()),
&s->lastPen,
penBlend, &s->penData,
i == pointCount - 1 ? mode_for_last : 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);
다음은 각 데이터 샘플은 1 바이트와 나는 값의 각 하나 개의 높은 전압 또는 낮은 전압 의존립니다.
어떻게 메모리 사용량을 측정하고 있습니까? –
자신 만의 코드를 보여줄 수 있습니까? –
@Arnold Spence : 저는 windonw task manager를 사용하여 메모리 리소스를 모니터링합니다. – Xavier