Custom chart based on Q3DScatter with QCustom3DItem going slow

自闭症网瘾萝莉.ら 提交于 2020-01-06 05:36:07

问题


I want to make a 3D chart with bars, the bar color depends on its size. Both Qt bar and scatter graph types are close to what I'm looking for. I ended up creating a chart based on Q3DScatter and adding QCustom3DItem to draw the bars, so I can set a mesh item and color to each item. I have one item in each position of the chart. Let's say it's a 100x100 chart, meaning there are 10 000 bars (custom items).

I want to redraw the entire chart multiple times per second. By redraw I mean every item will change its size and color. To set item size I call setScalling(). Because scalling works by keeping the item center position (and I want to keep the bar base position) then I have to call setPosition just after scalling. And to set color I call setTextureImage(). So, multiple times per second, code like the following get's called:

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);
  }

This works almost as expected. Problem is not fast enough. Any hints on how to make it faster?

I tried to move custom items to another thread.

In order to move processsing (i.e. scalling) of QCustom3DItem out of main (gui) thread I do:

project.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();
}

mainwindow.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

mainwindow.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();
}

graphdata.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

graphdata.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

This looks like to be working, the QCustom3DItem is on another thread, though there is the warning:

QObject::setParent: Cannot set parent, new parent is in a different thread

My understanding is that m_graph->addCustomItem(item) is trying to change item parent and is failing. How should I deal with this?

Should I expect better performance by processing custom items on another thread?

来源:https://stackoverflow.com/questions/59597182/custom-chart-based-on-q3dscatter-with-qcustom3ditem-going-slow

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!