Qt World Summit: Submit your Presentation

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;
    constexpr bool onWindows = false;

    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].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));
    return series;

    RTM::RTM(QWidget *parent) :
    QPixmap logo(":/logo/uff.png");
    m_view.setWindowFlag(Qt::Widget); //since it is not a window anymore
    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);


    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;



    void RTM::plot(QLineSeries *series)
    //m_view.setWindowTitle("Wavelet"); //since it is not a window, doesn´t need title
    m_view.setMinimumSize(800, 600);

    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.

  • Lifetime Qt Champion

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

    It doesn´t work.

  • Lifetime Qt Champion

    in what way dont work? Still becomes a window or not shown or ?
    It is indeed possible as shown here

  • @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:
    Ui::Widget ui;
    QPushButton m_runButton;
    QHBoxLayout m_plotarea;
    QtCharts::QChartView m_view{this};

  • Lifetime Qt Champion

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

  • Lifetime Qt Champion

    If you need something to look at , i tested the code in the link
    demo project

    alt text

  • @mrjj I kind of got it working, it was as simple like that:

    QHBoxLayout *m_plotarea = new QHBoxLayout;

    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

  • Lifetime Qt Champion

    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