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;
    #endif

    struct 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.


  • Qt Champions 2017

    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.


  • Qt Champions 2017

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


  • Qt Champions 2017

    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 one

    QHBoxLayout *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 &


  • Qt Champions 2017

    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

    alt text



  • @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?0_1530131125949_wavelet.png


  • Qt Champions 2017

    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.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.