PDA

View Full Version : QRubberband and QcustomPlot



OzQTNoob
15th October 2012, 06:30
Hi all,

i was wondering if anyone had used a QRubberBand in conjunction with the QCustomPlot (http://http://www.workslikeclockwork.com/other/qcustomplot-doc/classQCustomPlot.html) class. I really like the class since I don't have to install anything to get it working but it doesn't have a picker that comes with it like Qwt.

I have tried to get a QRubberband to work but due my serious lack of programming knowledge I have not been successful. My thinking is that it is hopefully a trivial exercise for most Qt programmers (I am still really new to C++) and I was hoping someone may have already been down this path and be able to give me some tips/tricks or help. My main problem seems to be when I try and set the geometry of the QRubberBand (it just seg faults on me), which in turn makes me think that I am not setting things correctly (I did go off of the examples given in the documentation where it uses mouse events to draw the rubberband).

Cheers
Oz

OzQTNoob
16th October 2012, 03:19
Hi everyone,

Okay so I managed to solve this one.

firstly, a real cut down version of my code. I am not saying this compiles (as is since it is not the complete app) I am only showing the combination of code I needed to get a QRubberband happening on the QCustomPlot.
The *.h file


#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "qcustomplot.h"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();

public slots:

private slots:

void mousePress(QMouseEvent* mevent);

void mouseMove(QMouseEvent *mevent);

void mouseRelease(QMouseEvent *mevent);

private:
Ui::MainWindow *ui;

QRubberBand *rubberBand;
QPoint origin;

};

#endif // MAINWINDOW_H


Okay so the big thing was I hunted around the QtSDK examples for any usage of QRubberband and found that they inserted a
rubberBand = 0; in the mainwindow constructor. So I did the same and YEAH BABY its ON!
It would have been nice to see this in the QRubberband example since newbies like myself tend to copy and paste which may not be the best thing to do but its how we learn sometimes (or at least how I do : at 43 years of age I need to get results).

Obviously I haven't shown the ui here, but suffice to say i added a widget and promoted it to a QCustomPlot and renamed it to customPlot. Being the newb that I am I was hoping someone could tell me what the
rubberBand = 0; does. I assume it initializes the pointer. I thought the
if(!rubberBand) in the mousePress slot was saying if it doesn't exist then lets create it but obviously not. I should also say that you will see that I check to see if the right mouse has been clicked and dragged since I want all the other cool zoom and axis drag functionality to remain in the customPlot (left mouse click/clickdrag). Lastly, I assume that until I destroy the widget (e.g. close the app) the actual rubberBand object will stay in memory and no new rubberBand will be created since if(!rubberBand) will always be false once the initial one was created. Anyhow, I hope this helps others who may use QCustomPlot as well.

The *.cpp file.


#include "mainwindow.h"
#include "ui_mainwindow.h"

void MainWindow::mousePress(QMouseEvent* mevent)
{
// if an axis is selected, only allow the direction of that axis to be dragged
// if no axis is selected, both directions may be dragged

if(mevent->button() == Qt::RightButton){
origin = mevent->pos();
if (!rubberBand){
rubberBand = new QRubberBand(QRubberBand::Rectangle, ui->customPlot);
}
rubberBand->setGeometry(QRect(origin, QSize()));
rubberBand->show();
}else{
/*This below is striaght from the QCustomPlot example and can be ignored in the context of the QRubberBand solution*/
if (ui->customPlot->xAxis->selected().testFlag(QCPAxis::spAxis))
ui->customPlot->setRangeDrag(ui->customPlot->xAxis->orientation());
else if (ui->customPlot->yAxis->selected().testFlag(QCPAxis::spAxis))
ui->customPlot->setRangeDrag(ui->customPlot->yAxis->orientation());
else
ui->customPlot->setRangeDrag(Qt::Horizontal|Qt::Vertical);
}
}

void MainWindow::mouseMove(QMouseEvent *mevent)
{
if(rubberBand)
rubberBand->setGeometry(QRect(origin, mevent->pos()).normalized());
}

void MainWindow::mouseRelease(QMouseEvent *mevent)
{
if(rubberBand)
rubberBand->hide();
}

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{

ui->setupUi(this);
rubberBand = 0;/*<-THIS WAS THE KEY! Without it the setGeometry call in the mousePress slot always stuffed up*/

/*set up a custom plot: This is pulled straight from one of the QCustomPlot examples*/
ui->customPlot->setInteractions(QCustomPlot::iRangeDrag | QCustomPlot::iRangeZoom | QCustomPlot::iSelectAxes |
QCustomPlot::iSelectLegend | QCustomPlot::iSelectPlottables | QCustomPlot::iSelectTitle);
ui->customPlot->setRangeDrag(Qt::Horizontal|Qt::Vertical);
ui->customPlot->setRangeZoom(Qt::Horizontal|Qt::Vertical);
ui->customPlot->xAxis->setRange(-20, 20);
ui->customPlot->yAxis->setRange(-20, 20);
ui->customPlot->setupFullAxesBox();
ui->customPlot->setTitle("Interaction Example");
ui->customPlot->xAxis->setLabel("x Axis");
ui->customPlot->yAxis->setLabel("y Axis");
ui->customPlot->legend->setVisible(true);
QFont legendFont = font();
legendFont.setPointSize(10);
ui->customPlot->legend->setFont(legendFont);
ui->customPlot->legend->setSelectedFont(legendFont);
ui->customPlot->legend->setSelectable(QCPLegend::spItems); // legend box shall not be selectable, only legend items

// connect slots that takes care that when an axis is selected, only that direction can be dragged and zoomed:
connect(ui->customPlot, SIGNAL(mousePress(QMouseEvent*)), this, SLOT(mousePress(QMouseEvent*)));
connect(ui->customPlot, SIGNAL(mouseMove(QMouseEvent*)), this, SLOT(mouseMove(QMouseEvent*)));
connect(ui->customPlot, SIGNAL(mouseRelease(QMouseEvent*)), this, SLOT(mouseRelease(QMouseEvent*)));
}