问题是:我想绘制由 USB 设备生成的输入数据(数据大小超过 50MB)计算的许多行。如果我使用 QPainterPath::lineTo 和 QPainterPath::moveTo 函数画线,似乎性能不好,内存不会释放。
我的环境是:具有 8G RAM 和 Qt 4.7.2 的 Windows 7。
例如,如果数据大小为 50MB,则占用的内存为 200MB。当上一次绘制完成,应用程序准备下次绘制时,200MB不会释放。所以如果我画很多次,应用程序就会崩溃。void QRasterPaintEngine::strokePolygonCosmetic(const QPointF *points, 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);
每个数据样本是一个字节,我将每个数据样本绘制为高电压或低电压取决于它的值。