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

2024-04-14

我想制作一个带条形的 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父母并且失败了。我该如何处理这个问题?

我是否应该通过在另一个线程上处理自定义项目来获得更好的性能?


Qt 非常适合原型设计或非性能关键代码。然而,其面向对象的方法与硬件的工作方式不一致,使得编写高性能代码变得困难甚至不可能。

最好的选择是覆盖绘图代码以在一次调用中渲染所有条形。如果需要支持旧硬件,请生成包含所有顶点的 VBO 并将其一次性发送glDrawArrays称呼。如果最近的硬件没问题,那么您可以通过实例化在 GPU 上生成所有网格,并从纹理中获取条形高度。在后一种情况下,每帧只需要发送 10,000 个浮点数,这对于带宽来说根本不算什么。

底线:实时渲染 10,000 个立方体对于现代 GPU 来说是小菜一碟。 Qt 是你的瓶颈。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于 Q3DScatter 的自定义图表,QCustom3DItem 运行缓慢 的相关文章

随机推荐

  • Java获取无线网络的SSID等信息

    我正在尝试用 Java 获取无线网络设备的 SSID 我尝试了官方网络教程http java sun com docs books tutorial networking nifs retriving html http java sun
  • 无需root设备即可卸载系统应用程序

    有没有办法在不root设备的情况下将apk推送到系统 应用程序文件夹 我找到了几种在 root 设备上执行此操作的方法 但我正在寻找一种无需先 root 设备即可执行此操作的方法 如果有任何区别 我想在三星 S4 上执行此操作并使用 twr
  • 如何在远程服务器上使用 gpg 签名密钥?

    有没有办法在Linux上通过gpg程序 命令行工具 在远程服务器中使用gpg密钥进行签名 我正在使用 gpg 使用测试密钥在本地主机上签署二进制文件 现在我想使用服务器访问的相同类型的密钥 我正在通过更改 gpg 工具的参数来寻找实现 你可
  • BIM服务器数据库访问

    我是一名 Java 开发人员 最近我公司正计划使用BIM Server 概念是 BIM 服务器将与我们当前的项目集成 我们将通过一些 API 访问 BIM 服务器数据库 我与本地 BIM 服务器建立连接 创建项目并使用 JsonBimSer
  • 如何找到字符列的MAX()值?

    我们有遗留表 其中复合键的列部分之一手动填充了值 code 001 002 099 etc 现在 我们有一个功能请求 其中我们必须知道 MAX code 才能为用户提供下一个可能的值 在示例情况下 上面的下一个值是 100 我们尝试对此进行
  • 禁用除第一列之外的每一列的排序

    我目前正在将数据表用于自定义系统 我想对除第一列之外的每一列禁用排序 我尝试使用以下代码 当我添加用逗号分隔的值时 它工作正常 aoColumnDefs bSortable false aTargets 1 2 3 4 但我的表列号因每个单
  • SQL Server 中的条件 WHERE 子句

    我正在创建一个 SQL 查询 其中需要条件where条款 它应该是这样的 SELECT DateAppr TimeAppr TAT LaserLTR Permit LtrPrinter JobName JobNumber JobDesc A
  • 如何从 Lambda 表达式的字符串动态创建方法

    我的最终目标是创建一个函数 将方法名称动态传递给 Hangfire 库中的类 例如 以下是有效的非动态代码 RecurringJob AddOrUpdate gt myFunction Cron Hourly AddOrUpdate 第一个
  • 使用 Assembly.LoadFrom 加载泛型类型

    参考 Jon Skeet 的回答 将实例化的 System Type 作为泛型类的类型参数传递 https stackoverflow com q 266115 592111 我需要根据泛型类型的名称以及作为泛型类型参数的类型名称来加载泛型
  • 如何使用 Win2D 计算 FontFamily 的高度(行距)?

    我想知道如何在 Window 通用应用程序中计算给定字体的高度 及其属性 如大小 粗细 样式 使用Win2D 我以前用过一个CanvasTextLayout 但它需要一个text工作 就像这一行 var ctl new CanvasText
  • Angularjs 的 $http.get 在 IE11 中只执行一次

    我正在学习 angularjs 作为一个测试项目 我正在轮询返回活动进程 它们的 pid 列表并显示这些的服务器 客户端代码如下所示
  • CodeIgniter 和 AJAX 表单提交

    我正在尝试将从表单提交的数据保存到我的 mysql 数据库中 然后将最后发布的项目添加到 div 列表中来更新 div 元素 现在我只是想得到回复 我并不担心目前的格式是否正确 我的问题是表单不会提交e preventDefault 到位
  • Keras Concatenate TypeError:__init__() 得到参数“axis”的多个值

    我目前正在尝试重新创建 Unet 在需要合并两层输出的 上卷积 部分 我得到了提到的错误 类型错误 init 获得参数 轴 的多个值 喀拉斯版本 2 0 6 张量流 GPU 1 2 1 代码片段 import gzip import os
  • 在 Hibernate 4 中创建会话工厂

    我在 Hibernate 4 中生成会话工厂时遇到问题 在 Hibernate 3 中我简单地做了 org hibernate cfg Configuration conf HibernateUtil getLimsInitializedC
  • 将函数应用于滚动窗口

    假设我有一个很长的清单A我想要计算的值 例如长度 1000 std100 对 即我想计算std A 1 100 std A 2 101 std A 3 102 std A 901 1000 在 Excel VBA 中 可以通过编写例如以下内
  • 如何对具有重复字符的字符串使用 substring 和 indexOf?

    我有以下内容String myString city Denver AND state Colorado 它有重复的 和 我如何检索州名 即科罗拉多州 我尝试了以下方法 String state myString substring myS
  • 如何从控制器运行 symfony 2 run 命令

    我想知道我怎样才能跑交响乐2来自浏览器查询或控制器的命令 这是因为我没有任何可能托管来运行它 并且每个 cron 作业都是由管理员设置的 我什至没有启用exec 因此 当我想测试它时 我必须将命令中的所有内容复制到某个测试控制器 这不是最佳
  • Hive Full Outer Join为相同的Join Key返回多行

    我正在对同一列上的 4 个表进行完全外连接 我想为连接列中的每个不同值仅生成 1 行 输入是 employee1 employee1 personid employee1 name 111 aaa 222 bbb 333 ccc
  • Android:本机线程与主线程同步

    在我的 android 应用程序中 我有一个从本机线程到 Java 代码的回调 需要与主 UI 线程同步 目的是 UI 线程根据从本机线程返回的信息显示选项列表 在用户选择一个选项之前 本机线程需要阻塞 用户选择一个选项后 本机线程读取该值
  • 基于 Q3DScatter 的自定义图表,QCustom3DItem 运行缓慢

    我想制作一个带条形的 3D 图表 条形颜色取决于其大小 两个都Qt 条形图和散点图类型 https doc qt io qt 5 qtdatavisualization overview html接近我正在寻找的东西 我最终创建了一个基于的