我正在尝试使用QImage
在窗口上绘制一个点,并尽快更新此点的位置(每次更新少于1毫秒)。我已经编写了下面的代码并运行它,但结果是它太慢了(每次更新大约50ms)。我搜索了瓶颈,发现这种缓慢的原因是调用QWidget.update()
需要太长时间。所以只要使用Widget.update()
我就会发现它不会更快。所以我想我需要另一种方式。有没有更快的方法来做到这一点?所有代码和结果如下。
结果:
qimageBehaviorForStackOverflowQuestion.pro
######################################################################
# Automatically generated by qmake (3.1) Wed Mar 29 15:18:09 2017
######################################################################
TEMPLATE = app
TARGET = qimageBehaviorForStackOverflowQuestion
INCLUDEPATH += .
QT += widgets
# Input
HEADERS += qimageBehaviorForStackOverflowQuestion.h
SOURCES += qimageBehaviorForStackOverflowQuestion.cpp
qimageBehaviorForStackOverflowQuestion.h
#include <iostream>
#include <QApplication>
#include <QWidget>
#include <QTimer>
#include <QPainter>
#include <QPushButton>
#include <QImage>
#include <QTime>
class MyWidget : public QWidget {
Q_OBJECT
private:
QImage *image;
int px, py;
uchar d[100*100*4];
QTimer *timer;
QTime time;
public:
MyWidget();
void paintEvent(QPaintEvent * event);
public slots:
void doPaint();
};
qimageBehaviorForStackOverflowQuestion.cpp
#include "qimageBehaviorForStackOverflowQuestion.h"
int my_counter = 0;
MyWidget::MyWidget() : QWidget(0), px(0), py(0){
image = new QImage(d, 100, 100, QImage::Format_ARGB32);
for(int cnt = 0, a, r, g, b; cnt < 100*100*4;){
a = 255; //alpha
r = 0; //red
g = 0; //green
b = 0; //blue
d[cnt] = b; cnt++;
d[cnt] = g; cnt++;
d[cnt] = r; cnt++;
d[cnt] = a; cnt++;
}
// connect QTimer.timeout to my doPaint method
timer = new QTimer();
connect(timer, SIGNAL(timeout()), this, SLOT(doPaint()));
timer->start(1);
};
void MyWidget::doPaint(){
// manipulate the positions of the points
if(px < 100){
int cnt = 0, b = 255, g = 255, r = 255, a = 255;
d[4 * px + cnt] = b; cnt++;
d[4 * px + cnt] = g; cnt++;
d[4 * px + cnt] = r; cnt++;
d[4 * px + cnt] = a; cnt++;
px++;
}
// update the window
update();
};
void MyWidget::paintEvent(QPaintEvent * event){
QPainter painter(this);
painter.drawImage(0, 0, *image);
}
int main(int argc, char *argv[]){
QApplication app(argc, argv);
MyWidget *widget = new MyWidget();
widget->show();
return app.exec();
}
答案 0 :(得分:1)
经过几个小时的谷歌搜索后,我找到了更快的方法。它变得非常快(一旦20FPS现在大约500FPS)。我现在使用的是QGraphicsView Framework
和QPixmap
以及QGraphicsPixmapItem
。但是我不知道这是正确或有效的方式,如果它不能纠正我。如果您知道有更快的方式请告诉我。我会以任何方式向您展示代码。我希望它可以帮助那些解决同样问题的人。
qgraphicsSceneExample.h
#include <iostream>
#include <QApplication>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsItem>
#include <QTimer>
#include <QPainter>
#include <QPushButton>
#include <QImage>
#include <QTime>
#include <QStyleOptionGraphicsItem>
#include <QWidget>
#include <QPixmap>
#include <QGraphicsPixmapItem>
class MyView : public QGraphicsView {
Q_OBJECT
private:
QGraphicsScene *scene;
QImage *image;
QPixmap *pixmap;
QGraphicsPixmapItem *gpixmapItem;
int px, py;
uchar d[100*100*4];
QTimer *timer;
QTime time;
public:
MyView();
//void paintEvent(QPaintEvent * event);
public slots:
void doPaint();
};
qgraphicsSceneExample.cpp
#include "qgraphicsSceneExample.h"
int my_counter = 0;
MyView::MyView() : px(0), py(0){
image = new QImage(d, 100, 100, QImage::Format_ARGB32);
for(int cnt = 0, a, r, g, b; cnt < 100*100*4;){
a = 255; //alpha
r = 0; //red
g = 0; //green
b = 0; //blue
d[cnt] = b; cnt++;
d[cnt] = g; cnt++;
d[cnt] = r; cnt++;
d[cnt] = a; cnt++;
}
// connect QTimer.timeout to my doPaint method
timer = new QTimer();
connect(timer, SIGNAL(timeout()), this, SLOT(doPaint()));
scene = new QGraphicsScene(0);
pixmap = new QPixmap(QPixmap::fromImage(*image));
gpixmapItem = scene->addPixmap(*pixmap);
this->setScene(scene);
timer->start(1);
};
void MyView::doPaint(){
// manipulate the positions of the points
if(px < 100){
int cnt = 0, b = 255, g = 255, r = 255, a = 255;
d[4 * px + cnt] = b; cnt++;
d[4 * px + cnt] = g; cnt++;
d[4 * px + cnt] = r; cnt++;
d[4 * px + cnt] = a; cnt++;
px++;
}
pixmap = new QPixmap(QPixmap::fromImage(*image));
gpixmapItem->setPixmap(*pixmap);
std::cout << my_counter++ << "\n";
};
int main(int argc, char *argv[]){
QApplication app(argc, argv);
MyView *myView = new MyView();
myView->show();
return app.exec();
}
答案 1 :(得分:0)
例如,考虑将Px的增量更改为大于+1,+ 5。这会将doPaint()函数的调用减少5倍。并将加快绘图速度。因为你的问题是你要经常更新图纸100次。
P.S:你还应该停止计时器在绘图结束时停止调用doPaint()函数。因为它每1ms被调用一次。因为timeout()
每1ms会发出jQuery(".together_description").each(function() {
var myInput = jQuery(this).val();
jQuery(this).trigger("click");
jQuery(this).focus();
jQuery(this).val(myInput + ' courtesy of XXX');
});
个信号。
修改强> 还要考虑更改非常轻的超时(每1ms&lt; =&gt; 1000 FPS更新)。