Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

qwt plot in QWidget is badly scaled



  • Hi, i have a problem related to badly scaling of a qwt plot. It is automatically located in upper-left corner of a area dedicated to present it. Additionally its size is reduced as well. I want to have it adjusted to whole area.
    Here some more information:
    Plotting function is a separate class, which inherits QwtPlot class and also is a Q_OBJECT. It uses following variables:

    double max_Y_val, min_Y_val;
    QwtSymbol* symbol;
    QwtPlotGrid* grid;
    QwtPlotCurve curve1;
    QwtPointSeriesData* myData;
    QVector<QPointF> samples;
    QwtPlotCanvas* canvas;
    QwtPlotPanner* panner;
    bool if_update_plot;
    

    Here is the constructor and remaining methods and definitions located in the cpp file:

    Plot::Plot(std::string type)
    {
    	if_update_plot = false;
    	setObjectName("plot");
    	setAxisTitle(xBottom, "Title");
    	setAxisScale(yLeft, 1.0, 15.0);
    	QwtPlotCanvas *canvas = new QwtPlotCanvas();
    	canvas->setPalette(Qt::white);
    	canvas->setBorderRadius(10);
    
    	setCanvas(canvas);
    
    	// grid
    	grid = new QwtPlotGrid();
    	grid->attach(this);
    
    	zoomer = new QwtPlotZoomer(canvas);
    	zoomer->setRubberBandPen(QColor(Qt::black));
    	zoomer->setTrackerPen(QColor(Qt::black));
    	zoomer->setMousePattern(QwtEventPattern::MouseSelect2,
    		Qt::RightButton, Qt::ControlModifier);
    	zoomer->setMousePattern(QwtEventPattern::MouseSelect3,
    		Qt::RightButton);
    
    	panner = new QwtPlotPanner(canvas);
    	panner->setMouseButton(Qt::MidButton);
    	this->setAutoReplot(true);
    	replot();
    }
    
    void Plot::Update_plot(const QString& title, const double X_val[1601 * 16], const double Y_val[1601 * 16], int number)
    {
    	if_update_plot = true;
    	max_Y_val = -200;
    	min_Y_val = 0;
    	double min = 0, max = 0;
    	myData = new QwtPointSeriesData;
    
    	// clear samples
    	for (int i = 0; i < samples.length(); i++) {
    		samples.pop_back();
    	}
    	while (samples.length() > 0) {
    		samples.pop_back();
    	}
    	for (int i = 5; i < number; i++) {
    		if (Y_val[i] != 0) {
    			samples.push_back(QPointF(X_val[i], Y_val[i]));
    			if (max_Y_val < Y_val[i]) {
    				max_Y_val = Y_val[i];
    			}
    			if (min_Y_val > Y_val[i]) {
    				min_Y_val = Y_val[i];
    			}
    			max = std::ceil(X_val[i]);
    			if (min == 0) {
    				min= std::floor(X_val[i]);
    			}
    		}
    	}
    
    	curve1.detach();
    	grid = new QwtPlotGrid();
    	grid->attach(this);
    
    	myData->setSamples(samples);
    	curve1.setStyle(QwtPlotCurve::Lines);
    	curve1.setPen(Qt::blue, (2.0), Qt::SolidLine);
    
    	setAxisScale(yLeft, std::floor(min_Y_val), std::ceil(max_Y_val));
    	setAxisScale(xBottom, min, max);
    	setAxisTitle(yLeft, title);
    
    	curve1.setData(myData);
    	curve1.attach(this);
    	this->replot();
    }
    
    void Plot::detach_curve()
    {
    	curve1.detach();
    }
    
    

    And in a class (inherits QDialog and also is a Q_OBJECT), which prompts Plot class to generate plot there is a QWidget area, where i want plot to be placed. I placed there in .h file:

    Plot* plot = new Plot("title");
    bool just_plotted = false;
    

    I also define a slot which is used when data is ready to be plotted. It helps me to decide when to plot. Then in .cpp file there is:

    void PlotWindow::plot_results()
    {
                    // getting data from device
    		double x_data[1601], y_data[1601];
    		for (int i = 0; i < 1601; i++) {
    			x_data[i] = device->x_data[i];
    			y_data[i] = device->y_data[i];
    		}
    		int points_no = device->plot_points_no;
    
    		QHBoxLayout* myLayoutTrans = new QHBoxLayout(ui.widget);
    		myLayoutTrans->addWidget(plot);
    		ui.widget->setLayout(myLayoutTrans);
    
                    // plot the latest data
    		plot->Update_plot("title", x_data, y_data, points_no, false);
    
    		delete myLayoutTrans;
    }
    

    I would be grateful if somebody can tell me where is the problem. everything works correctly, except this one thing... After refreshing the problem still occurs.


  • Lifetime Qt Champion

    Hi,

    @JohnCu said in qwt plot in QWidget is badly scaled:

    delete myLayoutTrans;
    }

    Why are you deleting the layout ?


  • Lifetime Qt Champion

    Hi,

    @JohnCu said in qwt plot in QWidget is badly scaled:

    delete myLayoutTrans;
    }

    Why are you deleting the layout ?



  • @SGaist Ok, i moved myLayoutTrans to private variables and in constructor i allocate memory once prior to updating plot. I delete pointer and associated memory in destructor then. Now, plot is presented properly. Thanks for the hint!


  • Lifetime Qt Champion

    If you set it up correctly, it will be managed by Qt's parent/child hierarchy and you won't need to delete it in the destructor.


Log in to reply