代码之家  ›  专栏  ›  技术社区  ›  KcFnMi

基于Q3DScatter的自定义图表,QCustom3DItem运行缓慢

  •  0
  • KcFnMi  · 技术社区  · 5 年前

    我想做一个三维图表与酒吧,酒吧的颜色取决于它的大小。两者 Qt bar and scatter graph types 很接近我要找的。最后我根据 Q3DScatter 和添加 QCustom3DItem 绘制条形图,以便我可以为每个项目设置网格项目和颜色。我在图表的每个位置都有一个项目。假设它是一个100x100的图表,意味着有10000个条(自定义项)。

    我想每秒多次重新绘制整个图表。我所说的重绘是指每件物品都会改变大小和颜色。设置我调用的项目大小 setScalling() . 因为缩放是通过保持项目中心位置来工作的(我想保持条形图的底部位置),所以我必须调用 setPosition setTextureImage() . 因此,每秒调用多次类似以下get的代码:

    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/
    

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

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

    网格.qrc

    <!DOCTYPE RCC><RCC version="1.0">
        <qresource>
            <file>mesh.obj</file>
        </qresource>
    </RCC>
    

    网格.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 家长和家长都失败了。我该怎么处理?

    0 回复  |  直到 5 年前
        1
  •  3
  •   Yakov Galka    5 年前

    Qt适用于原型设计或非性能关键代码。然而,它的面向对象方法与硬件的工作方式不一致,这使得编写高性能代码变得很困难。

    最好的办法是重写绘图代码,以便在一次调用中呈现所有条形图。如果支持旧的硬件是一个要求,去生成一个VBO与所有的顶点,并发送在一个 glDrawArrays 打电话。如果最近的硬件是好的,那么你可以生成所有的网格在GPU上通过实例,并获取酒吧高度从纹理。在后一种情况下,每帧只需要发送10000个浮点,这在带宽方面是没有意义的。