我目前正在尝试使用 Qt DataVisualization。
目标是我有一个
QLineEdit
,当我退出它时,我使用 QLineEdit::editingFinished
信号。然后我将输入的值设置为所选的 Bar
。
当我尝试访问
for
时启动第二个 QBarDataItem
循环时,我在第 46 行收到错误。我在那里遇到了读取访问冲突,并且在 Qt 的 qarraydatapointer.h
文件的这一行上收到了错误:
bool needsDetach() const noexcept { return !d || d->needsDetach(); }
这是我的代码:
主文件:
#include <QApplication>
#include <QFile>
#include "Window.h"
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
// creates a window
Window window;
QFile file(app.applicationDirPath() + "/Test.txt");
// Writes the x and y position of the selected Bar
QObject::connect(window.getSeries(), &QBar3DSeries::selectedBarChanged, [&]() {
if (!file.open(QIODevice::ReadWrite)) {
QTextStream stream(&file);
stream << window.getSeries()->selectedBar().x() << ", "
<< window.getSeries()->selectedBar().y() << ", "
<< window.getSeries()->dataProxy()->rowAt(window.getSeries()->selectedBar().x())->data()->value() << "\n";
}
});
QFile file1(app.applicationDirPath() + "/Data.txt");
if (file1.open(QIODevice::ReadOnly | QIODevice::Text)) {
QTextStream in(&file1);
QBarDataRow *data = new QBarDataRow;
while (!in.atEnd()) {
QString line = in.readLine();
*data << line.toFloat();
}
window.getSeries()->dataProxy()->addRow(data);
}
window.show();
file.close();
file1.close();
return app.exec();
}
窗口.h:
#ifndef WINDOW_H
#define WINDOW_H
#include <QMainWindow>
#include <QtDataVisualization>
#define WIDTH 1400
#define HEIGHT 800
struct Data {
Data() {
data1 = new QBarDataRow;
data2 = new QBarDataRow;
data3 = new QBarDataRow;
data4 = new QBarDataRow;
data5 = new QBarDataRow;
}
~Data() {
delete data1;
delete data2;
delete data3;
delete data4;
delete data5;
}
public:
QList<QBarDataRow *> data{ data1, data2, data3, data4, data5 };
QBarDataRow *data1;
QBarDataRow *data2;
QBarDataRow *data3;
QBarDataRow *data4;
QBarDataRow *data5;
};
class Window : public QMainWindow {
Q_OBJECT
public:
Window(QWidget *parent = nullptr);
~Window();
QBar3DSeries *getSeries();
protected:
void resizeEvent(QResizeEvent *event) override;
private:
Q3DBars *m_bars;
QBar3DSeries *m_series;
Data *m_data;
QWidget *m_graph;
};
#endif // WINDOW_H
窗口.cpp:
#include "Window.h"
#include <QLineEdit>
static void setData(Data *data, QBar3DSeries *series) {
*data->data1 << 1.0f << 3.0f << 6.5f << 5.0f << 2.2f;
*data->data2 << 2.0f << 1.5f << 5.0f << 2.0f << 2.4f;
*data->data3 << 3.0f << 2.5f << 4.0f << 1.0f << 3.4f;
*data->data4 << 2.9f << 2.5f << 2.3f << 3.1f << 1.7f;
//*data->data5 << 1.6f << 1.1f << 1.8f << 4.8f << 3.4f;
series->dataProxy()->addRow(data->data1);
series->dataProxy()->addRow(data->data2);
series->dataProxy()->addRow(data->data3);
series->dataProxy()->addRow(data->data4);
//series->dataProxy()->addRow(data->data5);
}
Window::Window(QWidget *parent) : QMainWindow(parent) {
// Initialising variables
m_bars = new Q3DBars;
m_series = new QBar3DSeries;
m_data = new Data;
setWindowTitle("Physik");
resize(WIDTH, HEIGHT);
m_bars->rowAxis()->setRange(0, 4);
m_bars->columnAxis()->setRange(0, 4);
m_bars->scene()->activeCamera()->setCameraPosition(30, 30);
// set values which can then be seen
setData(m_data, m_series);
m_bars->addSeries(m_series);
// Creates a QWidget, which is a child of the QMainWindow (this)
m_graph = QWidget::createWindowContainer(m_bars, this);
m_graph->setGeometry(0, 0, WIDTH * 0.7, HEIGHT);
//--------------------------------------------------------------
QLineEdit *lineEdit = new QLineEdit(this);
lineEdit->setGeometry(WIDTH * 0.75, HEIGHT * 0.1, WIDTH * 0.85, HEIGHT * 0.15);
connect(lineEdit, &QLineEdit::editingFinished, [&]() {
QPoint position = m_series->selectedBar();
for (size_t i{}; i < m_data->data.size(); ++i) {
if (i == position.x()) {
size_t j{};
for (auto &value : *m_data->data[i]) {
if (j == position.y()) {
value.setValue(lineEdit->text().toFloat());
}
++j;
}
break;
}
}
});
}
Window::~Window() {}
QBar3DSeries *Window::getSeries() {
return m_series;
}
void Window::resizeEvent(QResizeEvent *event) {
QMainWindow::resizeEvent(event);
if (m_graph) {
m_graph->resize(event->size().width() * 0.7, event->size().height());
}
}
我尝试编写自己的
QBarDataItem
和QBarDataRow
,它们继承了公共的两个类,并尝试重写函数,但没有成功,我真的尝试了很多不同的东西。但没有任何效果,所以我希望你能帮助我。
我知道这个问题最好不要太具体,这样很多人都可以提供帮助。最后,我只是尝试选择一个
Bar
,当我退出 QLineEdit
时,该值将被设置为所选的 Bar
。enter code here
当构造
m_data
对象时,其构造函数首先将 data1..data5
成员的 copy添加到
data
列表中 before 这些成员尚未初始化。然后在填充 data
列表后初始化这些成员,并且 data
列表内的指针永远不会更新。因此,当您的循环稍后从 m_data->data[i]
检索指针并尝试取消引用它时,您会遇到 未定义的行为,从而导致运行时崩溃。