我想制作一个带条形的 3D 图表,条形颜色取决于其大小。两个都Qt 条形图和散点图类型 https://doc.qt.io/qt-5/qtdatavisualization-overview.html接近我正在寻找的东西。我最终创建了一个基于的图表Q3DScatter
并添加QCustom3DItem
绘制条形,这样我就可以为每个项目设置网格项目和颜色。我在图表的每个位置都有一个项目。假设这是一个 100x100 图表,这意味着有 10 000 个条形图(自定义项目)。
我想每秒多次重绘整个图表。我所说的重绘是指每个项目都会改变其大小和颜色。要设置项目大小,我调用setScalling() https://doc.qt.io/qt-5/qcustom3ditem.html#scaling-prop。因为缩放是通过保持项目中心位置(并且我想保持栏基位置)来工作的,所以我必须调用设置位置 https://doc.qt.io/qt-5/qcustom3ditem.html#position-prop就在缩放之后。为了设置颜色我称之为设置纹理图像() https://doc.qt.io/qt-5/qcustom3ditem.html#setTextureImage。因此,每秒多次调用如下代码:
for (int col = 0; col < 100; col++)
for (int row = 0; row < 100; row++) {
items[row*COLS+col]->setScalling(scale);
items[row*COLS+col]->setPosition(position);
items[row*COLS+col]->setTextureImage(image);
}
这几乎按预期工作。问题是速度不够快。关于如何使其更快的任何提示?
我尝试将自定义项目移动到另一个线程。
为了移动处理(即缩放)QCustom3DItem
在主(gui)线程之外我这样做:
项目.pro
QT += core gui widgets datavisualization
TEMPLATE = app
CONFIG += c++11
SOURCES += main.cpp mainwindow.cpp graphdata.cpp
HEADERS += mainwindow.h graphdata.h
RESOURCES += mesh.qrc
CONFIG(debug, debug|release) {
DESTDIR = debug
} else {
DESTDIR = release
}
OBJECTS_DIR = $$DESTDIR/
MOC_DIR = $$DESTDIR/
RCC_DIR = $$DESTDIR/
UI_DIR = $$DESTDIR/
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
主窗口.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "graphdata.h"
class MainWindow : public QMainWindow {
Q_OBJECT
QThread thread;
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
signals:
void start();
};
#endif // MAINWINDOW_H
主窗口.cpp
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
resize(400,300);
auto graph = new Q3DScatter;
auto container = QWidget::createWindowContainer(graph);
setCentralWidget(container);
auto data = new GraphData(graph);
data->moveToThread(&thread);
connect(this, &MainWindow::start, data, &GraphData::start);
thread.start();
emit start();
}
MainWindow::~MainWindow() {
thread.quit();
thread.wait();
}
图数据.h
class GraphData : public QObject {
Q_OBJECT
Q3DScatter* m_graph;
QCustom3DItem* item;
public:
explicit GraphData(Q3DScatter* m_graph);
public slots:
void start();
void setData(int scale);
};
#endif // GRAPHDATA_H
图形数据.cpp
#include "graphdata.h"
GraphData::GraphData(Q3DScatter* graph) : m_graph(graph){}
void GraphData::start() {
item = new QCustom3DItem;
item->setMeshFile(QStringLiteral(":mesh.obj"));
m_graph->addCustomItem(item);
}
void GraphData::setData(int scale) {
// item->setScaling();
}
mesh.qrc
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>mesh.obj</file>
</qresource>
</RCC>
mesh.obj
# Blender v2.80 (sub 75) OBJ File: ''
# www.blender.org
o Cube
v 1.000000 1.000000 -1.000000
v 1.000000 -1.000000 -1.000000
v 1.000000 1.000000 1.000000
v 1.000000 -1.000000 1.000000
v -1.000000 1.000000 -1.000000
v -1.000000 -1.000000 -1.000000
v -1.000000 1.000000 1.000000
v -1.000000 -1.000000 1.000000
vt 0.625000 0.000000
vt 0.375000 0.250000
vt 0.375000 0.000000
vt 0.625000 0.250000
vt 0.375000 0.500000
vt 0.375000 0.250000
vt 0.625000 0.500000
vt 0.375000 0.750000
vt 0.625000 0.750000
vt 0.375000 1.000000
vt 0.375000 0.500000
vt 0.125000 0.750000
vt 0.125000 0.500000
vt 0.875000 0.500000
vt 0.625000 0.500000
vt 0.625000 0.250000
vt 0.625000 0.750000
vt 0.625000 1.000000
vt 0.375000 0.750000
vt 0.875000 0.750000
vn 0.0000 1.0000 0.0000
vn 0.0000 0.0000 1.0000
vn -1.0000 0.0000 0.0000
vn 0.0000 -1.0000 0.0000
vn 1.0000 0.0000 0.0000
vn 0.0000 0.0000 -1.0000
s off
f 5/1/1 3/2/1 1/3/1
f 3/4/2 8/5/2 4/6/2
f 7/7/3 6/8/3 8/5/3
f 2/9/4 8/10/4 6/8/4
f 1/11/5 4/12/5 2/13/5
f 5/14/6 2/9/6 6/15/6
f 5/1/1 7/16/1 3/2/1
f 3/4/2 7/7/2 8/5/2
f 7/7/3 5/17/3 6/8/3
f 2/9/4 4/18/4 8/10/4
f 1/11/5 3/19/5 4/12/5
f 5/14/6 1/20/6 2/9/6
这看起来正在工作,QCustom3DItem
在另一个线程上,尽管有警告:
QObject::setParent: Cannot set parent, new parent is in a different thread
我的理解是m_graph->addCustomItem(item)
正在努力改变item
父母并且失败了。我该如何处理这个问题?
我是否应该通过在另一个线程上处理自定义项目来获得更好的性能?