gpt4 book ai didi

qt - 在 Qt 中使用像素图或位图快速绘图

转载 作者:行者123 更新时间:2023-12-02 15:30:28 25 4
gpt4 key购买 nike

我需要 Qt 中的快速绘图小部件,但我不想使用任何准备好的东西。我有一些 float 数据,例如 QVector< float >数据,我需要在小部件上绘制它。但我不想使用 paintEventQPainter直接在上面。是否有机会将此数据转换为位图(像素图?)并直接加载它以显示在小部件上?如何从 float 创建位图?

最佳答案

如果绘画是开销大的,你可以把它移到另一个线程,这样它就不会锁定你的应用程序的事件循环,并且在完成时更新结果。

既然你想要任意绘图,那么“将数据转换为位图”确实没有神奇的方法,你必须使用 QPainter 来绘制你的东西。

这是一个如何使用异步绘图仪对象的简单示例:

class Plotter : public QObject {
Q_OBJECT
public:
Plotter(QSize size, QRectF range, QVector<double> data)
: _size(size), _range(range), _data(data) { }

signals:
void done(QImage);
void cleanup();

public slots:
void plot() {
QElapsedTimer t;
t.start();
QImage img(_size, QImage::Format_ARGB32_Premultiplied);
img.fill(Qt::white);
QPainter p(&img);
QPen pen(Qt::darkBlue);
pen.setWidth(1);
p.setPen(pen);
for (int i = 0; i < _data.size(); i += 2) {
p.drawPoint(map(_data[i], _data[i + 1]));
}
qDebug() << "plotted in" << t.elapsed() << "msec";
emit done(img);
emit cleanup();
}

private:
inline QPointF map(double x, double y) {
return QPointF(_size.width() * (x / (_range.width() - _range.x())),
_size.height() * (y / (_range.height() - _range.y())));
}

QSize _size;
QRectF _range;
QVector<double> _data;
};

绘图仪是用它的大小、范围和数据参数创建的,我使用 QRectF 作为范围,基本上使用 x/width 和 y/height 作为水平和垂直范围。绘图仪是一个非常简单的实现,为了示例,它使用 map() 方法将数据点“规范化”到以线性方式绘制到的图像区域。我还添加了一个计时器来查看绘制所有点需要多长时间。

这是用于创建绘图、填充数据并显示结果的示例小部件:

class Widget : public QWidget {
Q_OBJECT
public:
Widget(QWidget * parent = 0) : QWidget(parent) {
// prepping data
QVector<double> data;
data.reserve(200000);
for (int i = 0; i < 200000; ++i) data.append((double)qrand() / RAND_MAX);

// create plotter and thread
Plotter * p = new Plotter(size(), QRectF(0, 0, 1, 1), data);
QThread * thread = new QThread;
p->moveToThread(thread);

// do connections
connect(thread, SIGNAL(started()), p, SLOT(plot()));
connect(p, SIGNAL(done(QImage)), this, SLOT(updatePlot(QImage)));
connect(p, SIGNAL(cleanup()), thread, SLOT(quit()));
connect(thread, SIGNAL(finished()), p, SLOT(deleteLater()));
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));

thread->start();
}

protected:
void paintEvent(QPaintEvent *) {
QPainter p(this);
p.drawImage(QPoint(0, 0), plot);
}

public slots:
void updatePlot(QImage p) {
plot = p;
repaint();
}

private:
QImage plot;
};

在我的示例中,我使用 0-1 范围内的 200 000 个值填充数据。然后使用小部件的大小创建绘图仪,X 和 Y 的范围为 0-1,创建线程并将绘图仪移动到它,进行必要的连接并启动线程。启动后,线程将调用 plot() 插槽,它将绘图结果发送到小部件的 updatePlot() 插槽。当发送结果时,绘图仪将退出线程事件循环,这将删除绘图仪对象和线程,这样它们就不会泄漏。

至于这有多快,我的 i7 桌面在 8 毫秒内绘制了 200,000 个点,所以它无论如何都不慢。

关于qt - 在 Qt 中使用像素图或位图快速绘图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27190411/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com