당신이보고있는 효과는 순전히 psychovisual입니다. 그것은 소프트웨어 결함이 아니라 인간의 결함입니다. 나는 진지해. x
의 값을 고정하여 확인할 수 있습니다. 깜박임이 없으므로 창에서 전체 픽스맵을 다시 칠하고 아무런 깜박임을 표시하지 않습니다.
정신 박동 깜박임은 스크롤 속도가 실시간으로 연결되어 있지 않을 때 발생합니다. 때로는 업데이트 사이의 시간이 CPU로드로 인해 또는 시스템 타이머 부정확으로 인해 달라질 수 있습니다. 우리의 시각 시스템은 두 개의 이미지를 통합하며 전체적인 밝기가 변경된 것처럼 보입니다.
배경을 회색으로 설정하여 이미지의 명암비를 낮추면 감지되는 깜박임이 줄어 듭니다. 이것은 효과가 psychovisual이라는 추가적인 단서이다.
다음은이 효과를 방지하는 방법입니다. 스크롤 거리가 시간과 어떻게 연관되어 있는지주의하십시오 (여기서는 1ms = 1 픽셀).
#include <QElapsedTimer>
#include <QPaintEvent>
#include <QBasicTimer>
#include <QApplication>
#include <QPainter>
#include <QPixmap>
#include <QWidget>
#include <QDebug>
static inline int rand(int range) { return (double(qrand()) * range)/RAND_MAX; }
class Widget : public QWidget
{
float fps;
qint64 lastTime;
QPixmap pixmap;
QBasicTimer timer;
QElapsedTimer elapsed;
void timerEvent(QTimerEvent * ev) {
if (ev->timerId() == timer.timerId()) update();
}
void paintEvent(QPaintEvent * ev) {
qint64 time = elapsed.elapsed();
qint64 delta = time - lastTime;
lastTime = time;
if (delta > 0) {
const float weight(0.05);
fps = (1.0-weight)*fps + weight*(1E3/delta);
if (pixmap.size() != size()) {
pixmap = QPixmap(size());
pixmap.fill(Qt::black);
}
int dy = qMin((int)delta, pixmap.height());
pixmap.scroll(0, dy, pixmap.rect());
QPainter pp(&pixmap);
pp.fillRect(0, 0, pixmap.width(), dy, Qt::black);
for(int i = 0; i < 30; ++i){
int x = rand(pixmap.width());
pp.fillRect(x, 0, 3, dy, Qt::green);
}
}
QPainter p(this);
p.drawPixmap(ev->rect(), pixmap, ev->rect());
p.setPen(Qt::yellow);
p.fillRect(0, 0, 100, 50, Qt::black);
p.drawText(rect(), QString("FPS: %1").arg(fps, 0, 'f', 0));
}
public:
explicit Widget(QWidget *parent = 0) : QWidget(parent), fps(0), lastTime(0), pixmap(size())
{
timer.start(1000/60, this);
elapsed.start();
setAttribute(Qt::WA_OpaquePaintEvent);
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
페인트 이벤트 전반에 걸쳐 픽스맵 페인팅을 위해 QPainter 인스턴스를 유지하는 것은 매우 드문 일입니다. QPainter가 여전히 pixmap에서 열려있는 동안 다른 페인트 장치에 픽스맵을 페인팅하면 동작이 정의되지 않을 수도 있습니다. –
깜박임없는 응답 (메모리 비용)을 얻기 위해 활성화해야하는 이중 버퍼링에 관해 뭔가를 기억합니다. – RedX
@RedX, AFAIK, Qt는 현재 이중 버퍼링을 지원하며 추가 이중 버퍼링 코드를 작성할 필요가 없습니다. – Anony