Problem on putting a plot within mainwidget GUI. How to do?
-
Hi everyone, I have a code that works fine when I plot in a external window, it pops up and display the graph, but I´m struggling to add this window to the GUI mainwindow, I looked at the examples, it seems quite easy, but in my case I dont know how to implement it.
I have a few parameters that I need to choose from the spinboxes;
These parameters are passed to a function and a QLineSeries;
in order to add the plot to the mainwindow GUI I added a QHBoxLayout, that I called "plotarea" on my form, i added the BOLD lines on the constructor as below:#include "widget.h"
#include <QtCharts>using namespace QtCharts;
constexpr double pi = 3.14159265358979323846;
#ifdef Q_OS_WIN
constexpr bool onWindows = true;
#else
constexpr bool onWindows = false;
#endifstruct RickerParameters {
double f; // Hz
double dt; // s
double length; // s
int polarity;
};QVector<QPointF> rickerData(const RickerParameters &p)
{
size_t N = (p.length - p.dt/2.0)/p.dt;
const double discrete_length = (N-1) * p.dt;QVector<QPointF> w(N); for (size_t i = 0; i < N; ++i) { const double t = -discrete_length/2.0 + i*p.dt; w[i].setX(t); w[i].setY(p.polarity * ((1.0 - 2*pi*pi*p.f*p.f*t*t) * exp(-pi*pi*p.f*p.f*t*t))); } return w;
}
QLineSeries* rickerSeries(const RickerParameters &p)
{
auto *series = new QLineSeries;
series->setName(QStringLiteral("Ricker Wavelet for f=%1 Hz").arg(p.f, 2));
series->replace(rickerData(p));
return series;
}RTM::RTM(QWidget *parent) :
QWidget(parent)
{
ui.setupUi(this);
setWindowTitle("RTM");
QPixmap logo(":/logo/uff.png");
ui.label_pic->setPixmap(logo);
//m_view.setWindowFlag(Qt::Window);
m_view.setWindowFlag(Qt::Widget); //since it is not a window anymore
m_runButton.setText(tr("Run"));
ui.buttonBox->addButton(&m_runButton, QDialogButtonBox::ApplyRole);
connect(&m_runButton, &QPushButton::clicked, this, &RTM::run);
connect(ui.buttonBox->button(QDialogButtonBox::Close), &QPushButton::clicked, this, &QWidget::close);**//QChartView *view = new QChartView(); QWidget *container = QWidget::createWindowContainer(m_view,ui.plotarea,Qt::Widget); ui.plotarea->addWidget(container);**
}
void RTM::run()
{
RickerParameters p;
p.length = ui.length->value() / 1000.0;
p.polarity = ui.positive->isChecked() ? +1 : -1;
p.f = ui.freq->value();
p.dt = ui.rate->value() / 1000.0;plot(rickerSeries(p));
}
void RTM::plot(QLineSeries *series)
{
m_view.chart()->removeAllSeries();
m_view.chart()->addSeries(series);
m_view.chart()->createDefaultAxes();
//m_view.setWindowTitle("Wavelet"); //since it is not a window, doesn´t need title
m_view.setMinimumSize(800, 600);
m_view.show();
}I´m not sure if I have to add a new QChartView called view, or use the old one m_view. Anyway neither is working.
-
Hi
Just insert m_view into a layout and it should work.
If not a non Qt thing, no need for createWindowContainer
what class type is m_view ? -
@mrjj Hi, m_view is a QtCharts::QChartView m_view{this}.
Insert m_view in a layout u mean like that:QHBoxLayout *m_plotarea = new QHBoxLayout();
ui.plotarea->addWidget(&m_plotarea,0 ,Qt::AlignCenter);
ui.plotarea->m_plotarea(m_view);It doesn´t work.
-
Hi
in what way dont work? Still becomes a window or not shown or ?
It is indeed possible as shown here
https://stackoverflow.com/questions/39128153/how-do-you-display-a-qchartview-in-a-custom-widget -
@mrjj I´m sorry, saying it doesn´t work is way too generic. It doesn´t compile, it says there is no function to call the QHBoxLayout. Like this:
C:\Users\Flavio\Documents\qtTest\RTM\widget.cpp:59: error: no matching function for call to 'QHBoxLayout::addWidget(QHBoxLayout**, int, Qt::AlignmentFlag)'
ui.plotarea->addWidget(&m_plotarea,0 ,Qt::AlignCenter);
^
But I did declare it on the header:
private:
Ui::Widget ui;
QPushButton m_runButton;
QHBoxLayout m_plotarea;
QtCharts::QChartView m_view{this}; -
Hi
yes. "dont work" is hard to work with :)
There is small mistake.
you have a non pointer member
QHBoxLayout m_plotarea;
but you new a new oneQHBoxLayout *m_plotarea = new QHBoxLayout(); // local version. and pointer so when you say ui.plotarea->addWidget(&m_plotarea,0 ,Qt::AlignCenter); and use the & you take address of the pointer and it complains that i cant do that with no matching function for call to addWidget(QHBoxLayout** Notice the 2 ** ( pointer to pointer)
so either use your member and &
or just use the one you NEw without any & -
Ps
If you need something to look at , i tested the code in the link
demo project
https://www.dropbox.com/s/xezk5fpoboaxvsy/mychart.zip?dl=0 -
@mrjj I kind of got it working, it was as simple like that:
QHBoxLayout *m_plotarea = new QHBoxLayout;
m_plotarea->addWidget(&m_view);But now, I have another problem, when i hit RUN, it show on the background, taking the whole window, I want to limit it to a space, I believe I have to set the size, which commands do that?
-
Hi
It seems the other widgets are not into the layout so the Chart can use all space of
the mainwindow as it dont "see" the other widgets.
A quick fix is to use m_view->setMaximumSize( QSize( 400,400 ));
but a better fix was to arrange all widgets in same the layout so it
scales well if windows size changes.