gpt4 book ai didi

c++ - 如果我将一个 TCanvas vector 传递给另一个类,为什么 ROOT 只允许我将一个 TCanvas vector 的最终元素设置为另一个 TCanvas vector ?

转载 作者:行者123 更新时间:2023-11-28 06:39:16 25 4
gpt4 key购买 nike

问题

我想开始将 TCanvas 从本质上是我程序的“模型”部分动态传递到“ View ”部分。我考虑这样做的方式是在启动时简单地在 View 上创建我的 TCanvas,然后在填充图形后用 View TCanvas 更新此 TCanvas。我创建了一个测试台,看看它是否可行。

我展示了一个工作方法和一个损坏的方法。

我正在使用 QT-ROOT,TQtWidget是一个自定义小部件,本质上是对 TCanvas 的返回。

设置我的 Canvas

void DataTestTab::setupCanvas(int cNCbc) //I pass "2" to this for now to generate the below loop twice
{
for (int i=0; i<cNCbc; i++)
{
m_vectorCanvas.push_back(new TQtWidget(this));

//m_vectorCanvas[i]->GetCanvas()->SetFillColor(i);
QHBoxLayout *loH = new QHBoxLayout(this);

loH->addWidget(m_vectorCanvas[i]);
m_vectorLayout.push_back(loH);

QGroupBox *gbCanvas = new QGroupBox(this);
QString title = QString("CBC %1").arg(i);
gbCanvas->setTitle(title);
gbCanvas->setLayout(m_vectorLayout[i]);
m_vectorGroupBox.push_back(gbCanvas);

ui->loCbcBox->addWidget(m_vectorGroupBox[i]); //adding the panels to the main layout
}
}

这行得通

void DataTestTab::drawTest()
{
static Int_t HistoID = 1;
qDebug() << "in Testing env ";
std::vector<TH1D*> graphs;
std::vector<TCanvas*> vCanvas;

TString name("h1_");
Bool_t build = false;


for (int i = 0; i <m_vectorCanvas.size() ; i++)
{
TCanvas *cCanvas = new TCanvas(build);
name += HistoID++;

vCanvas.push_back(cCanvas);
vCanvas.at(i)->cd();


TH1D *h1 = new TH1D(name.Data(),name.Data(),10,0, 10);
graphs.push_back(h1);
graphs.at(i)->Fill(i);

graphs.at(i)->Draw();
//graphs.at(i)->DrawCopy();

m_vectorCanvas.at(i)->GetCanvas()->SetFillColor(i+5);
m_vectorCanvas.at(i)->cd();

qDebug() << i;

m_vectorCanvas.at(i)->GetCanvas()->SetCanvas(vCanvas.at(i));
m_vectorCanvas.at(i)->Refresh();
}
}

对应输出:

Working Method

尽管图表顺序错误。

这行不通

我将此方法转移到另一个类并通过信号/槽将 TCanvas 传回。

 void DataTestWorker::doWork()
{
static Int_t HistoID = 1;
qDebug() << "in Testing env ";
std::vector<TH1D*> graphs;
std::vector<TCanvas*> vCanvas;

TString name("h1_");
Bool_t build = false;

for (int i = 0; i <2 ; i++)
{
TCanvas *cCanvas = new TCanvas(build);
name += HistoID++;

vCanvas.push_back(cCanvas);
vCanvas.at(i)->cd();

TH1D *h1 = new TH1D(name.Data(),name.Data(),10,0, 10);
graphs.push_back(h1);
graphs.at(i)->Fill(i);

graphs.at(i)->Draw();

}
emit sendGraphData(vCanvas); //void sendGraphData(const std::vector<TCanvas*> &canvas);

然后图形数据被发送到这里:

void DataTestTab::drawGraph(const std::vector<TCanvas*> &canvas)
{
for (int i=0; i<m_vectorCanvas.size(); i++)
{
canvas.at(i)->cd();
m_vectorCanvas.at(i)->cd();
m_vectorCanvas.at(i)->GetCanvas()->SetCanvas(canvas.at(i));
m_vectorCanvas.at(i)->Refresh();
//m_vectorCanvas.at(i)->GetCanvas()->Update();

}
}

这是这个方法的输出:

Attempt 2

目前我能看到的唯一错误是我在 SetupTab 中得到这个错误:

QLayout: Attempting to add QLayout "" to GUI::DataTestTab "DataTestTab", which already has a layout
QLayout: Attempting to add QLayout "" to GUI::DataTestTab "DataTestTab", which already has a layout

最佳答案

我正在尝试一次处理一件事情。你的错误信息QLayout: Attempting to add QLayout "" to GUI::DataTestTab "DataTestTab", which already has a layout源于您正在为 QHBoxLayout 调用此构造函数这一事实:

QHBoxLayout *loH = new QHBoxLayout(this);

如果您查看 QLayout 的文档(例如 http://qt-project.org/doc/qt-4.8/qlayout.html#QLayout )然后您将调用带有父级的构造函数(在您的情况下为 this )并且文档说:

QLayout::QLayout ( QWidget * parent )
Constructs a new top-level QLayout, with parent parent. parent may not be 0.
There can be only one top-level layout for a widget.

因此,即使您没有明确将这些布局设置为您的 DataTestTab 的主要布局,Qt 尝试这样做,因为这是构造函数的编写方式,这会导致您看到的消息。

解决这个问题的明显方法是改变

QHBoxLayout *loH = new QHBoxLayout(this);

QHBoxLayout *loH = new QHBoxLayout;

然后调用这个构造函数:

QLayout::QLayout ()
Constructs a new child QLayout.
This layout has to be inserted into another layout before geometry management will work.

即一个QLayout可以添加到另一个(并且必须这样做才能工作)。

编辑:我认为您可以简化移交对象的方式。没有理由构建 TCanvas对于每个直方图并传递它,特别是因为 TCanvas不会拥有您的直方图,我相信当您发出 TH1::Draw() 时即使有cd() '进入你想要的 Canvas ,这并没有实现你想要做的事情。

我玩过你的代码,我可以通过简单地实现你想要的:

void DataTestWorker::doWork()
{
static Int_t HistoID = 1;
std::vector<TH1D*> graphs;
TString name("h1_");
for (int i = 0; i <2 ; i++)
{
name += HistoID++;
TH1D *h1 = new TH1D(name.Data(),name.Data(),10,0, 10);
graphs.push_back(h1);
graphs.at(i)->Fill(i);
}
emit sendGraphData(graphs); //void sendGraphData(std::vector<TH1D*>);

}

void DataTestTab::drawGraph(std::vector<TH1D*> hists)
{
for (size_t i=0; i<m_vectorCanvas.size(); i++)
{
TH1D *h = hists.at(i);
m_vectorCanvas.at(i)->cd();
h->Draw();
m_vectorCanvas.at(i)->Refresh();
}
}

我显然没有执行任何检查来确保 std::vector<TH1D*>std::vector<TQtWidget*>具有相同的长度等。但使用此代码,我能够在两个 TCanvas 上显示两个直方图。正如你在 This Works 中展示的那样例子。

这有帮助吗?

关于c++ - 如果我将一个 TCanvas vector 传递给另一个类,为什么 ROOT 只允许我将一个 TCanvas vector 的最终元素设置为另一个 TCanvas vector ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26255470/

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