在QT(大约100,000或更多)中绘制数千$.doTimeout( 100, function(){
if ( $("#description" ).text() != "") {
$("#description" ).text() == "Product A" ? $("#desc-a").css("display","inline") : $("#desc-b").css("display","inline");
return false;
}
return true;
});
的正确方法是什么?
我试过了:
rects
的{{1}}进行简单。paintEvent()
,然后将此图片绘制到QWidget
。QImage
(也许我没有正确使用它,我只是将QWidget
添加到了场景中)每次绘画都很慢,而且我对如何做到这一点没有更多的想法(也许使用opengl / directx,但这听起来并不是一个好主意)。我知道存在应用程序,所以应该有一些方法。
编辑:
我想知道QGraphicsScene
是如何运作的?是否有可能填充一些rects
数组并将其传递给drawRects()
会更好?
答案 0 :(得分:0)
第一个技巧是在单独的线程中绘制到QImage
,然后将其传递到主线程。这不会使它更快,但它会使它不会阻止GUI线程。
// https://github.com/KubaO/stackoverflown/tree/master/questions/threaded-paint-36748972
#include <QtWidgets>
#include <QtConcurrent>
class Widget : public QWidget {
Q_OBJECT
QImage m_image;
bool m_pendingRender { false };
Q_SIGNAL void hasNewRender(const QImage &);
// Must be thread-safe, we can't access the widget directly!
void paint() {
QImage image{2048, 2048, QImage::Format_ARGB32_Premultiplied};
image.fill(Qt::white);
QPainter p(&image);
for (int i = 0; i < 100000; ++i) {
QColor c{rand() % 256, rand() % 256, rand() % 256};
p.setBrush(c);
p.setPen(c);
p.drawRect(rand() % 2048, rand() % 2048, rand() % 100, rand() % 100);
}
emit hasNewRender(image);
}
void paintEvent(QPaintEvent *) {
QPainter p(this);
p.drawImage(0, 0, m_image);
}
public:
Widget(QWidget * parent = 0) : QWidget(parent) {
this->setAttribute(Qt::WA_OpaquePaintEvent);
setMinimumSize(200, 200);
connect(this, &Widget::hasNewRender, this, [this](const QImage & img) {
m_image = img;
m_pendingRender = false;
update();
});
refresh();
}
Q_SLOT void refresh() {
if (!m_pendingRender) {
m_pendingRender = true;
QtConcurrent::run([this] { paint(); });
}
}
};
int main(int argc, char ** argv) {
QApplication app{argc, argv};
Widget w;
QPushButton button{"Refresh", &w};
button.connect(&button, &QPushButton::clicked, &w, [&w]{ w.refresh(); });
w.show();
return app.exec();
}
#include "main.moc"
作为一个单独的问题,您可以将绘图分割为多个并行作业,方法是将每个作业的画家剪切到共享图像的子区域,并注意完全剪切的矩形绘制是无操作,部分剪切的是只会填充他们影响的像素。
答案 1 :(得分:0)
我发现的解决方案:
创建uint32_t
数组,其中可以包含widget
的所有像素,并使用memcpy()
填充它。使用此数组创建QImage
并使用drawImage()
进行显示。
它可以有一些优化,例如(for profiler)合并rects
,它们是继续的(开始时间秒等于第一个结束)。不要画出超出时间范围的rects
。也许跳过太小rects
。
为了绘制文本,工具提示等内容,您仍然可以使用Qt
函数。
对于最简单的alpha混合,你可以只取现有值,将它们循环混合并写入混合值,或者使用SIMD
来实现这一点。
当然对于更复杂的形状,它会更难绘制,但我认为它仍然比使用Qt
函数更快。