Following an old example about drag and drop legend (https://www.qcustomplot.com/index.php/support/forum/481), to allow user set legend to predefined location and drag/drop legend, I move setInsetPlacement(0, QCPLayoutInset::ipFree);
into mouse press slot as shown below. However there is a problem that when user set legend to predefined location by calling setInsetAlignment(0, Qt::AlignLeft|Qt::AlignTop);
and etc, the legend location changed but plot->axisRect()->insetLayout()->insetRect(0);
does not update to the new location. This causes offset when trying to move the legend.
Is it true that setInsetAlignment does not actually change the insetRect? How can I work around the problem? Thanks.
#include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); plot = new QCustomPlot(this); plot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); setCentralWidget(plot); plot->addGraph(); plot->addGraph(); plot->legend->setVisible(true); // set the placement of the legend (index 0 in the axis rect's inset layout) to not be // border-aligned (default), but freely, so we can reposition it anywhere: //plot->axisRect()->insetLayout()->setInsetPlacement(0, QCPLayoutInset::ipFree); [b]plot->axisRect()->insetLayout()->setInsetPlacement(0, QCPLayoutInset::ipBorderAligned);[/b] [b]plot->axisRect()->insetLayout()->setInsetAlignment(0, Qt::AlignLeft|Qt::AlignTop);[/b] draggingLegend = false; connect(plot, SIGNAL(mouseMove(QMouseEvent*)), this, SLOT(mouseMoveSignal(QMouseEvent*))); connect(plot, SIGNAL(mousePress(QMouseEvent*)), this, SLOT(mousePressSignal(QMouseEvent*))); connect(plot, SIGNAL(mouseRelease(QMouseEvent*)), this, SLOT(mouseReleaseSignal(QMouseEvent*))); connect(plot, SIGNAL(beforeReplot()), this, SLOT(beforeReplot())); } MainWindow::~MainWindow() { delete ui; } void MainWindow::mouseMoveSignal(QMouseEvent *event) { if (draggingLegend) { QRectF rect = [b]plot->axisRect()->insetLayout()->insetRect(0);[/b] // since insetRect is in axisRect coordinates (0..1), we transform the mouse position: QPointF mousePoint((event->pos().x()-plot->axisRect()->left())/(double)plot->axisRect()->width(), (event->pos().y()-plot->axisRect()->top())/(double)plot->axisRect()->height()); rect.moveTopLeft(mousePoint-dragLegendOrigin); plot->axisRect()->insetLayout()->setInsetRect(0, rect); plot->replot(); } } void MainWindow::mousePressSignal(QMouseEvent *event) { if (plot->legend->selectTest(event->pos(), false) > 0) { draggingLegend = true; [b]plot->axisRect()->insetLayout()->setInsetPlacement(0, QCPLayoutInset::ipFree);[/b] // since insetRect is in axisRect coordinates (0..1), we transform the mouse position: QPointF mousePoint((event->pos().x()-plot->axisRect()->left())/(double)plot->axisRect()->width(), (event->pos().y()-plot->axisRect()->top())/(double)plot->axisRect()->height()); dragLegendOrigin = mousePoint-plot->axisRect()->insetLayout()->insetRect(0).topLeft(); } } void MainWindow::mouseReleaseSignal(QMouseEvent *event) { Q_UNUSED(event) [b] if(draggingLegend){ plot->axisRect()->insetLayout()->setInsetPlacement(0, QCPLayoutInset::ipBorderAligned); draggingLegend = false; }[/b] } void MainWindow::beforeReplot() { // this is to prevent the legend from stretching if the plot is stretched. // Since we've set the inset placement to be ipFree, the width/height of the legend // is also defined in axisRect coordinates (0..1) and thus would stretch. // This is due to change in a future release (probably QCP 2.0) since it's basically a design mistake. plot->legend->setMaximumSize(plot->legend->minimumSizeHint()); }