QwtPlot how to select point(s) curve - qt

I have a QwtPlot that contains some curves and I would like to be able to get the selected point(s) (and curve pointer) from these curves : select a point by clicking and select points by dragging a rect.
I use the following code:
// Picker with click point machine to provide point selection
QwtPlotPicker* clickPicker = new QwtPlotPicker(this->canvas());
clickPicker->setStateMachine(new QwtPickerClickPointMachine);
clickPicker->setMousePattern(0,Qt::LeftButton,Qt::SHIFT);
connect(clickPicker, SIGNAL(appended(QPointF)),
this, SLOT(pointSelected(QPointF)));
// Picker with drag rect machine to provide multiple points selection
QwtPlotPicker* rectPicker = new QwtPlotPicker(
this->xBottom, this->yLeft, QwtPicker::RectRubberBand,
QwtPicker::AlwaysOff, this->canvas());
QwtPickerDragRectMachine* test = new QwtPickerDragRectMachine();
test->setState(QwtPickerMachine::RectSelection);
rectPicker->setStateMachine(test);
connect(rectPicker, SIGNAL(selected(QRectF)),
this, SLOT(pointsSelected(QRectF)));
but the pointSelected slot is called every time I click on the QwtPlot and not only on a curve
BTW, I also try to connect a slot to the signal QwtPlotPicker::selected(const QVector &pa) but it is never emitting ...

I think it is more convenient to use the CanvasPicker as it comes with the examples and can be extended easily.
Please have a look at the event_filter which comes with Qwt. You should use the class CanvasPicker (it is not part of the Qwt API, but you'll find the code in the examples).
You can instantiate it in your class using
picker = new CanvasPicker(plot); // plot is a pointer to your instance of QwtPlot
You'll see that the event filter is installed in the constructor of CanvasPicker.
Now have a look at CanvasPicker::eventFilter(QObject *object, QEvent *e) which is called when an event occurs in the event loop of QwtPlot. Implement your application logic in the switch construct, f.i. change case QEvent::MouseMove:.

Related

'setAutoTickStep' : is not a member of 'QCPAxis' with QCustomPlot 2.00-beta

I'm using Qt5.6.1 and QCustomPlot 2.00-beta. And I set a new widget called "widget". But when I code
ui->widget->xAxis->setAutoTickStep(false);
it says
error: C2039: 'setAutoTickStep' : is not a member of 'QCPAxis'
how to solve it?
use:
QSharedPointer<QCPAxisTickerFixed> fixedTicker(new QCPAxisTickerFixed);
customPlot->xAxis->setTicker(fixedTicker);
fixedTicker->setTickStep(1.0); // tick step shall be 1.0
fixedTicker->setScaleStrategy(QCPAxisTickerFixed::ssNone); // and no scaling of the tickstep (like multiples or powers) is allowed
from: http://www.qcustomplot.com/documentation/classQCPAxisTickerFixed.html#details
You will need to create an object of type QCustomPlot, do a customPlot->addGraph(), and then access its settings like customPlot->xAxis->QCPAxisTicker(...).
It appears you are trying to access a member of an object of type QWidget, which knows nothing about custom plots, until overridden. Neither the old nor the new method will work on an object of QWidget. You should use a new method of QCPAxis instead; perhaps
ui->customPlot->xAxis->ticker()->setTickCount(0);
If your problem is that you are trying to create a plot in QtCreator, you can create a QWidget in it, and then right-click on it, and do a "Promote to ...". Make sure the QCustomPlot headers are already in your project first, and then specify the one which defines QCustomPlot when promoting. When you say, "rename it as widget and remote it to a QCustomPlot", did you mean "promote it to"?

Qt: make view to update visible data

In my program I use QTableView and QAbstractTableModel that are connected. Model doesn't contain data. When view needs data to show it calls QAbstractTableModel::data and model uses another object to get data and return. At some point data in that object is going changed. Model doesn't know what has changed so dataChanged is not called.
I need that only visible part of data (that is shown in view) goes updated. It should get new data from model. I am trying to achieve that by calling update() or repaint() functions of view but it doesn't help. I am thinking that it should call paintEvent of tableview but it is not called.
How is it possible to make view update visible part of data? I don't want to update whole data that is huge.
Your wishes brokes Qt MVC logic. But if you need workaround - you may do next call to update visible area: emit dataChanged( QModelIndex(), QModelIndex() );

using lambdas or QSignalMapping to pass a custom class value into custom SLOT

I am using Qt5.
I have a loop which generates multiple (number specified by the user) plots by using QCustomPlot (http://www.qcustomplot.com/) each shown in their own dialog. I want the user to be able to save one of the plots, so in each dialog there is a menu bar with an Action "Save as PDF".
I have a List of the plots (QList< QCustomPlot*> >) which each plot is added to when it is created in the loop. My issue is how to select from the list which plot should be saved when the user triggers the action. Here's the main code:
while(currentPlotNum<NumPlots){
//code for generating plots
QAction *saveAsPdfAction = new QAction("Save As PDF",plotDialog);
QFileDialog *saveAsPdfDialog = new QFileDialog(plotDialog);
saveAsPdfDialog->setFileMode(QFileDialog::AnyFile);
saveAsPdfDialog->setNameFilter("PDF Files (*.pdf)");
QObject::connect(saveAsPdfAction,SIGNAL(triggered()),saveAsPdfDialog,SLOT(exec()));
QSignalMapper *signalMapper = new QSignalMapper(saveAsPdfDialog);
QObject::connect(saveAsPdfAction,SIGNAL(triggered()),signalMapper,SLOT(map()));
signalMapper->setMapping(saveAsPdfAction,currentPlotNum);
QObject::connect(signalMapper,SIGNAL(mapped(int)),this,SLOT(setWorkingPlot(int)));
QObject::connect(saveAsPdfDialog,SIGNAL(fileSelected(QString)),this,SLOT(saveToPDF(QString)));
currentPlotNum++;
}
then here are the two SLOTS:
void samplePlots::setWorkingPlot(int value){
workingPlot = value;
}
void samplePlots::saveToPDF(QString PdfFileName){
plotList[workingPlot]->savePdf(PdfFileName,false,600,600);
}
I run the application and generate say 3 plots, when I click the button to save one of the plots, the plot that actually gets saved is seemingly a random choice of one of the 3, rather than the plot in the dialog which i click the button in.
Ideally I would have been able to pass the QCustomPlot* itself through the SignalMaper, but it doesn't seem as though I can do that. I also tried to have the Slot as a lambda (following the syntax here http://www.artandlogic.com/blog/2013/09/qt-5-and-c11-lambdas-are-your-friend/ but I couldn't get it to work.
If anyone has Ideas of how to fix my problem that would be great.
Connect each 'saveToPdf buttons' triggered(bool) signal to a custom signal of your derived displaying QDialog (lets call it saveRequested()).
store in the dialog the index of the displaying plot as well and save your QSignalMapper (not needed).
then connect your main class where your list is stored to that saveRequested() signal, cast the QObject::sender() to your Dialog and access the plot in the list.
cheers

qt malloc(): smallbin double linked list corrupted

In my Qt widget I sometimes get this error:
malloc(): smallbin double linked list corrupted
It does not happen all the time but I think I have narrowed it down to when it starts.
I have a QGraphicsView and QGraphicsScene and there I'm drawing lines whos points are stored in a vector. Reason for this is I need to pass this points to another library. Once I draw the points I have an option if I click on a line I'm prompted to another window where I can change the coordinates of a line.
ResizeDialog *dialog = new ResizeDialog(this);
dialog->exec();
delete dialog;
The above code is the code I use to open a new QDialog. I know if I use this->close() the
qt malloc(): smallbin double linked list corrupted does not appear but then I lose the instance of QGraphicsView. Reason I need to keep the QGraphicsView window open if I need to chose to add further lines.
Any advice on how I can eliminate this issue wold be helpful.
Rather than using delete dialog;, use dialog->deleteLater();. I assume the small code portion is inside a slot of the object referenced by "this", and direct deletion is source of trouble as ResizeDialog *dialog = new ResizeDialog(this); affect the parent object this.

Qt paint on a popup window with data from database

In Qt GUI application, I made a dialog containing a table. When I double click a row in the table, I want:
a popup window to show up;
get points data according to that row from a database;
plot those points on the popup window.
I've done the fetch function of points data in a database.cpp. But according to the rule, the plotting function has to be in dialog.cpp, in a void Dialog::paintEvent(QPaintEvent *event) function. Can I do the plotting function lineTo() in that database.cpp data fetch function?
You can paint in a QPixmap from anywhere, and pass that pixmap to the popup dialog to be displayed inside a QLabel or painted by the paintEvent function.
You can also use QPolygonF which has the advantage of being more cleanly scalable.
Look at the function generatePixmap in that article (Qt Quaterly), then use QLabel::setPixmap to assign the pixmap to the label.

Resources