mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-02 09:30:25 +08:00
Parameters: added Mem/StereoFromMotion (default false) and RGBD/ProximityOdomGuess (default false). Visual proximity detection is done before computing the loop closure transform (the later is ignored if visual proximity succeeded with a node close to loop closure, add Loop/Suppressed_hypothesis_id statistics to know when this happens). Changed Loop/Map_correction to Loop/Odom_correction (to better see the actual jumps of localization about /base_link frame, not /odom frame). util3d::generateWords3DMono() is now using openCV's implementation of five-point algorithm (this fixed some cases for which the older approach couldn't find any solution). UPlot: added scrolling area on the legend, added global legend option to show all curve statistics (mean, stddev,max). MainWindow's open dialog: reopen last directory when reopening a different database. ParametersToolBox: show default parameter value in tooltip. rtabmap-report: add --start option. rtabmap-reprocess: show details about proximity and loop detections, reset all localization statistics after changing database.
This commit is contained in:
@@ -329,6 +329,7 @@ private:
|
||||
QString _newDatabasePath;
|
||||
QString _newDatabasePathOutput;
|
||||
QString _openedDatabasePath;
|
||||
QString _defaultOpenDatabasePath;
|
||||
bool _databaseUpdated;
|
||||
bool _odomImageShow;
|
||||
bool _odomImageDepthShow;
|
||||
|
||||
@@ -37,6 +37,7 @@ class QGraphicsView;
|
||||
class QGraphicsScene;
|
||||
class QGraphicsItem;
|
||||
class QFormLayout;
|
||||
class QScrollArea;
|
||||
|
||||
/**
|
||||
* UPlotItem is a QGraphicsEllipseItem and can be inherited to do custom behaviors
|
||||
@@ -353,6 +354,7 @@ public:
|
||||
virtual ~UPlotLegendItem();
|
||||
const UPlotCurve * curve() const {return _curve;}
|
||||
QPixmap createSymbol(const QPen & pen, const QBrush & brush);
|
||||
void showStdDevMeanMax(bool shown);
|
||||
|
||||
Q_SIGNALS:
|
||||
void legendItemRemoved(const UPlotCurve *);
|
||||
@@ -418,6 +420,9 @@ private:
|
||||
QMenu * _menu;
|
||||
QAction * _aUseFlatButtons;
|
||||
QAction * _aCopyAllCurvesToClipboard;
|
||||
QAction * _aShowAllStdDevMeanMax;
|
||||
QLayout * _contentLayout;
|
||||
QScrollArea * _scrollArea;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -4817,7 +4817,7 @@ void MainWindow::newDatabase()
|
||||
|
||||
void MainWindow::openDatabase()
|
||||
{
|
||||
QString path = QFileDialog::getOpenFileName(this, tr("Open database..."), _preferencesDialog->getWorkingDirectory(), tr("RTAB-Map database files (*.db)"));
|
||||
QString path = QFileDialog::getOpenFileName(this, tr("Open database..."), _defaultOpenDatabasePath.isEmpty()?_preferencesDialog->getWorkingDirectory():_defaultOpenDatabasePath, tr("RTAB-Map database files (*.db)"));
|
||||
if(!path.isEmpty())
|
||||
{
|
||||
this->openDatabase(path);
|
||||
@@ -4843,6 +4843,7 @@ void MainWindow::openDatabase(const QString & path, const ParametersMap & overri
|
||||
|
||||
this->clearTheCache();
|
||||
_openedDatabasePath = path;
|
||||
_defaultOpenDatabasePath = path;
|
||||
|
||||
// look if there are saved parameters
|
||||
DBDriver * driver = DBDriver::create();
|
||||
|
||||
@@ -521,7 +521,9 @@ void ParametersToolBox::addParameter(QVBoxLayout * layout, const QString & key,
|
||||
QString tmp = key.split('/').last();
|
||||
QLabel * label = new QLabel(tmp, this);
|
||||
label->setObjectName(key+"/label");
|
||||
label->setToolTip(QString("<FONT>%1</FONT>").arg(Parameters::getDescription(key.toStdString()).c_str()));
|
||||
label->setToolTip(QString("<FONT>%1 [default=%2]</FONT>")
|
||||
.arg(Parameters::getDescription(key.toStdString()).c_str())
|
||||
.arg(uValue(Parameters::getDefaultParameters(), key.toStdString(), std::string("?")).c_str()));
|
||||
label->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
||||
hLayout->addWidget(label);
|
||||
hLayout->addWidget(widget);
|
||||
|
||||
@@ -871,6 +871,7 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
||||
_ui->surf_doubleSpinBox_maxDepth->setObjectName(Parameters::kKpMaxDepth().c_str());
|
||||
_ui->surf_doubleSpinBox_minDepth->setObjectName(Parameters::kKpMinDepth().c_str());
|
||||
_ui->checkBox_memDepthAsMask->setObjectName(Parameters::kMemDepthAsMask().c_str());
|
||||
_ui->checkBox_memStereoFromMotion->setObjectName(Parameters::kMemStereoFromMotion().c_str());
|
||||
_ui->surf_spinBox_wordsPerImageTarget->setObjectName(Parameters::kKpMaxFeatures().c_str());
|
||||
_ui->spinBox_KPGridRows->setObjectName(Parameters::kKpGridRows().c_str());
|
||||
_ui->spinBox_KPGridCols->setObjectName(Parameters::kKpGridCols().c_str());
|
||||
@@ -1030,6 +1031,7 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
||||
_ui->localDetection_maxPaths->setObjectName(Parameters::kRGBDProximityMaxPaths().c_str());
|
||||
_ui->localDetection_pathFilteringRadius->setObjectName(Parameters::kRGBDProximityPathFilteringRadius().c_str());
|
||||
_ui->localDetection_angle->setObjectName(Parameters::kRGBDProximityAngle().c_str());
|
||||
_ui->checkBox_localSpaceOdomGuess->setObjectName(Parameters::kRGBDProximityOdomGuess().c_str());
|
||||
_ui->checkBox_localSpacePathOdomPosesUsed->setObjectName(Parameters::kRGBDProximityPathRawPosesUsed().c_str());
|
||||
_ui->rgdb_localImmunizationRatio->setObjectName(Parameters::kRGBDLocalImmunizationRatio().c_str());
|
||||
_ui->loopClosure_reextract->setObjectName(Parameters::kRGBDLoopClosureReextractFeatures().c_str());
|
||||
|
||||
@@ -63,9 +63,9 @@
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>-455</y>
|
||||
<y>0</y>
|
||||
<width>680</width>
|
||||
<height>3497</height>
|
||||
<height>3270</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_16">
|
||||
@@ -95,7 +95,7 @@
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>21</number>
|
||||
<number>19</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="page_22">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_29" stretch="0,1">
|
||||
@@ -4951,7 +4951,7 @@ when using the file type, logs are saved in LogRtabmap.txt (located in the worki
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>13</height>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
@@ -5231,21 +5231,7 @@ when using the file type, logs are saved in LogRtabmap.txt (located in the worki
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="page_77">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_135">
|
||||
<item>
|
||||
<spacer name="verticalSpacer_75">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>471</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_135"/>
|
||||
</widget>
|
||||
<widget class="QWidget" name="page_80">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_140">
|
||||
@@ -5364,7 +5350,7 @@ when using the file type, logs are saved in LogRtabmap.txt (located in the worki
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>596</height>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
@@ -8631,7 +8617,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
||||
<layout class="QVBoxLayout" name="verticalLayout_60">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_32" columnstretch="0,1">
|
||||
<item row="4" column="1">
|
||||
<item row="5" column="1">
|
||||
<widget class="QLabel" name="label_22">
|
||||
<property name="toolTip">
|
||||
<string>0 means that the response (hessian) threshold
|
||||
@@ -8650,7 +8636,7 @@ generate the number of words requested.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<item row="6" column="1">
|
||||
<widget class="QLabel" name="label_81">
|
||||
<property name="toolTip">
|
||||
<string>0 means that the response (hessian) threshold
|
||||
@@ -8669,7 +8655,7 @@ generate the number of words requested.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="1">
|
||||
<item row="10" column="1">
|
||||
<widget class="QLabel" name="label_99">
|
||||
<property name="text">
|
||||
<string>Top ROI ratio (0 = no change).</string>
|
||||
@@ -8682,7 +8668,7 @@ generate the number of words requested.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<item row="6" column="0">
|
||||
<widget class="QDoubleSpinBox" name="surf_doubleSpinBox_ratioBadSign">
|
||||
<property name="decimals">
|
||||
<number>2</number>
|
||||
@@ -8784,14 +8770,14 @@ generate the number of words requested.</string>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<item row="7" column="0">
|
||||
<widget class="QLineEdit" name="lineEdit_kp_roi">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<item row="7" column="1">
|
||||
<widget class="QLabel" name="label_101">
|
||||
<property name="text">
|
||||
<string>ROI ratios [left, right, top, bottom] between 0 and 1.</string>
|
||||
@@ -8823,7 +8809,7 @@ generate the number of words requested.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<item row="9" column="0">
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_kp_roi1">
|
||||
<property name="suffix">
|
||||
<string> %</string>
|
||||
@@ -8868,7 +8854,7 @@ generate the number of words requested.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<item row="5" column="0">
|
||||
<widget class="QSpinBox" name="surf_spinBox_wordsPerImageTarget">
|
||||
<property name="minimum">
|
||||
<number>-1</number>
|
||||
@@ -8881,7 +8867,7 @@ generate the number of words requested.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<item row="8" column="0">
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_kp_roi0">
|
||||
<property name="suffix">
|
||||
<string> %</string>
|
||||
@@ -8891,7 +8877,7 @@ generate the number of words requested.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<item row="8" column="1">
|
||||
<widget class="QLabel" name="label_97">
|
||||
<property name="text">
|
||||
<string>Left ROI ratio (0 = no change).</string>
|
||||
@@ -8904,7 +8890,7 @@ generate the number of words requested.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<item row="9" column="1">
|
||||
<widget class="QLabel" name="label_98">
|
||||
<property name="text">
|
||||
<string>Right ROI ratio (0 = no change).</string>
|
||||
@@ -8917,7 +8903,7 @@ generate the number of words requested.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<item row="10" column="0">
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_kp_roi2">
|
||||
<property name="suffix">
|
||||
<string> %</string>
|
||||
@@ -8927,7 +8913,7 @@ generate the number of words requested.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0">
|
||||
<item row="11" column="0">
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_kp_roi3">
|
||||
<property name="suffix">
|
||||
<string> %</string>
|
||||
@@ -8937,7 +8923,7 @@ generate the number of words requested.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="1">
|
||||
<item row="11" column="1">
|
||||
<widget class="QLabel" name="label_100">
|
||||
<property name="text">
|
||||
<string>Bottom ROI ratio (0 = no change).</string>
|
||||
@@ -8972,7 +8958,7 @@ generate the number of words requested.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="1">
|
||||
<item row="12" column="1">
|
||||
<widget class="QLabel" name="label_50">
|
||||
<property name="toolTip">
|
||||
<string>0 means that the response (hessian) threshold
|
||||
@@ -8991,7 +8977,7 @@ generate the number of words requested.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="0">
|
||||
<item row="12" column="0">
|
||||
<widget class="QSpinBox" name="spinBox_KPGridRows">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
@@ -9004,7 +8990,7 @@ generate the number of words requested.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="0">
|
||||
<item row="13" column="0">
|
||||
<widget class="QSpinBox" name="spinBox_KPGridCols">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
@@ -9017,7 +9003,7 @@ generate the number of words requested.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="1">
|
||||
<item row="13" column="1">
|
||||
<widget class="QLabel" name="label_86">
|
||||
<property name="toolTip">
|
||||
<string>0 means that the response (hessian) threshold
|
||||
@@ -9062,6 +9048,32 @@ generate the number of words requested.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLabel" name="label_582">
|
||||
<property name="toolTip">
|
||||
<string>0 means that the response (hessian) threshold
|
||||
used for the detector will not be adapted.
|
||||
Otherwise, the threshold is modified to
|
||||
generate the number of words requested.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Triangulate features without depth using stereo from motion (odometry). It would be ignored if depth as mask is checked and the feature detector used supports masking.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QCheckBox" name="checkBox_memStereoFromMotion">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
@@ -10497,7 +10509,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_50" columnstretch="0,1">
|
||||
<item row="4" column="0">
|
||||
<item row="5" column="0">
|
||||
<widget class="QDoubleSpinBox" name="localDetection_pathFilteringRadius">
|
||||
<property name="suffix">
|
||||
<string> m</string>
|
||||
@@ -10513,7 +10525,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<item row="6" column="1">
|
||||
<widget class="QLabel" name="label_scanMatching_4">
|
||||
<property name="text">
|
||||
<string>When comparing to a local path, merge the laser scans using the odometry poses instead of the ones in the optimized local graph.</string>
|
||||
@@ -10526,7 +10538,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<item row="5" column="1">
|
||||
<widget class="QLabel" name="label_space3_3">
|
||||
<property name="text">
|
||||
<string>Path filtering radius to avoid merging laser scans which are close. 0 to ignore. A path should also be inside that radius to be considered for proximity detection.</string>
|
||||
@@ -10539,7 +10551,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<item row="6" column="0">
|
||||
<widget class="QCheckBox" name="checkBox_localSpacePathOdomPosesUsed">
|
||||
<property name="text">
|
||||
<string/>
|
||||
@@ -10569,7 +10581,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<item row="8" column="1">
|
||||
<widget class="QLabel" name="label_scanMatching_6">
|
||||
<property name="text">
|
||||
<string>Save scan matching IDs in link's user data.</string>
|
||||
@@ -10582,7 +10594,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<item row="8" column="0">
|
||||
<widget class="QCheckBox" name="checkBox_localSpaceScanMatchingIDsSaved">
|
||||
<property name="text">
|
||||
<string/>
|
||||
@@ -10664,6 +10676,26 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLabel" name="label_scanMatching_13">
|
||||
<property name="text">
|
||||
<string>Use odometry as motion guess for visual proximity detection.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QCheckBox" name="checkBox_localSpaceOdomGuess">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
@@ -14901,7 +14933,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>1029</height>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
@@ -15124,7 +15156,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
@@ -15193,7 +15225,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
@@ -15387,7 +15419,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>961</height>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
@@ -16200,7 +16232,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>1090</height>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
@@ -16236,7 +16268,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
@@ -21674,19 +21706,6 @@ Lower the ratio -> higher the precision.</string>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_42">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <QToolButton>
|
||||
#include <QLabel>
|
||||
#include <QMenu>
|
||||
#include <QStyle>
|
||||
#include <QInputDialog>
|
||||
#include <QMessageBox>
|
||||
#include <QFileDialog>
|
||||
@@ -1453,18 +1454,7 @@ void UPlotLegendItem::contextMenuEvent(QContextMenuEvent * event)
|
||||
}
|
||||
else if(action == _aShowStdDevMeanMax)
|
||||
{
|
||||
if(_aShowStdDevMeanMax->isChecked())
|
||||
{
|
||||
connect(_curve, SIGNAL(dataChanged(const UPlotCurve *)), this, SLOT(updateStdDevMeanMax()));
|
||||
updateStdDevMeanMax();
|
||||
}
|
||||
else
|
||||
{
|
||||
disconnect(_curve, SIGNAL(dataChanged(const UPlotCurve *)), this, SLOT(updateStdDevMeanMax()));
|
||||
QString nameSpaced = _curve->name();
|
||||
nameSpaced.replace('_', ' ');
|
||||
this->setText(nameSpaced);
|
||||
}
|
||||
showStdDevMeanMax(_aShowStdDevMeanMax->isChecked());
|
||||
}
|
||||
else if(action == _aRemoveCurve)
|
||||
{
|
||||
@@ -1480,6 +1470,23 @@ void UPlotLegendItem::contextMenuEvent(QContextMenuEvent * event)
|
||||
}
|
||||
}
|
||||
|
||||
void UPlotLegendItem::showStdDevMeanMax(bool shown)
|
||||
{
|
||||
_aShowStdDevMeanMax->setChecked(shown);
|
||||
if(shown)
|
||||
{
|
||||
connect(_curve, SIGNAL(dataChanged(const UPlotCurve *)), this, SLOT(updateStdDevMeanMax()));
|
||||
updateStdDevMeanMax();
|
||||
}
|
||||
else
|
||||
{
|
||||
disconnect(_curve, SIGNAL(dataChanged(const UPlotCurve *)), this, SLOT(updateStdDevMeanMax()));
|
||||
QString nameSpaced = _curve->name();
|
||||
nameSpaced.replace('_', ' ');
|
||||
this->setText(nameSpaced);
|
||||
}
|
||||
}
|
||||
|
||||
QPixmap UPlotLegendItem::createSymbol(const QPen & pen, const QBrush & brush)
|
||||
{
|
||||
QPixmap pixmap(50, 50);
|
||||
@@ -1501,7 +1508,7 @@ void UPlotLegendItem::updateStdDevMeanMax()
|
||||
float max = uMax(y.data(), y.size());
|
||||
QString nameSpaced = _curve->name();
|
||||
nameSpaced.replace('_', ' ');
|
||||
nameSpaced += QString("\n(%1=%2, %3=%4, max=%5)").arg(QChar(0xbc, 0x03)).arg(mean).arg(QChar(0xc3, 0x03)).arg(stdDev).arg(max);
|
||||
nameSpaced += QString("\n(%1=%2, %3=%4, max=%5, n=%6)").arg(QChar(0xbc, 0x03)).arg(QString::number(mean, 'f', 3)).arg(QChar(0xc3, 0x03)).arg(QString::number(stdDev, 'f', 3)).arg(QString::number(max, 'f', 3)).arg(y.size());
|
||||
this->setText(nameSpaced);
|
||||
}
|
||||
|
||||
@@ -1519,15 +1526,30 @@ UPlotLegend::UPlotLegend(QWidget * parent) :
|
||||
_aUseFlatButtons->setCheckable(true);
|
||||
_aUseFlatButtons->setChecked(_flat);
|
||||
_aCopyAllCurvesToClipboard = new QAction(tr("Copy all curve data to clipboard"), this);
|
||||
_aShowAllStdDevMeanMax = new QAction(tr("Show all %1, %2, max").arg(QChar(0xbc, 0x03)).arg(QChar(0xc3, 0x03)), this);
|
||||
_aShowAllStdDevMeanMax->setCheckable(true);
|
||||
_aShowAllStdDevMeanMax->setChecked(false);
|
||||
_menu = new QMenu(tr("Legend"), this);
|
||||
_menu->addAction(_aUseFlatButtons);
|
||||
_menu->addAction(_aShowAllStdDevMeanMax);
|
||||
_menu->addAction(_aCopyAllCurvesToClipboard);
|
||||
|
||||
QVBoxLayout * vLayout = new QVBoxLayout(this);
|
||||
vLayout->setContentsMargins(0,0,0,0);
|
||||
this->setLayout(vLayout);
|
||||
vLayout->addStretch(0);
|
||||
vLayout->setSpacing(0);
|
||||
_scrollArea = new QScrollArea(this);
|
||||
_scrollArea->setWidgetResizable( true );
|
||||
_scrollArea->setFrameShape(QFrame::NoFrame);
|
||||
|
||||
this->setLayout(new QVBoxLayout());
|
||||
this->layout()->setContentsMargins(0,0,0,0);
|
||||
this->layout()->addWidget(_scrollArea);
|
||||
|
||||
QWidget * _scrollAreaWidgetContent = new QWidget();
|
||||
_scrollArea->setWidget( _scrollAreaWidgetContent );
|
||||
|
||||
_contentLayout = new QVBoxLayout();
|
||||
_scrollAreaWidgetContent->setLayout(_contentLayout);
|
||||
_contentLayout->setContentsMargins(0,0,0,0);
|
||||
((QVBoxLayout*)_contentLayout)->addStretch(0);
|
||||
_contentLayout->setSpacing(0);
|
||||
}
|
||||
|
||||
UPlotLegend::~UPlotLegend()
|
||||
@@ -1573,7 +1595,9 @@ void UPlotLegend::addItem(UPlotCurve * curve)
|
||||
hLayout->setMargin(0);
|
||||
|
||||
// add to the legend
|
||||
((QVBoxLayout*)this->layout())->insertLayout(this->layout()->count()-1, hLayout);
|
||||
((QVBoxLayout*)_contentLayout)->insertLayout(_contentLayout->count()-1, hLayout);
|
||||
|
||||
_scrollArea->setMinimumWidth(std::min(480, _scrollArea->widget()->sizeHint().width()+QApplication::style()->pixelMetric(QStyle::PM_ScrollBarExtent)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1585,6 +1609,7 @@ bool UPlotLegend::remove(const UPlotCurve * curve)
|
||||
if(items.at(i)->curve() == curve)
|
||||
{
|
||||
delete items.at(i);
|
||||
_scrollArea->setMinimumWidth(std::min(480, _scrollArea->widget()->sizeHint().width()+QApplication::style()->pixelMetric(QStyle::PM_ScrollBarExtent)));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1603,24 +1628,24 @@ void UPlotLegend::moveUp(UPlotLegendItem * item)
|
||||
{
|
||||
int index = -1;
|
||||
QLayoutItem * layoutItem = 0;
|
||||
for(int i=0; i<this->layout()->count(); ++i)
|
||||
for(int i=0; i<_contentLayout->count(); ++i)
|
||||
{
|
||||
if(this->layout()->itemAt(i)->layout() &&
|
||||
this->layout()->itemAt(i)->layout()->indexOf(item) != -1)
|
||||
if(_contentLayout->itemAt(i)->layout() &&
|
||||
_contentLayout->itemAt(i)->layout()->indexOf(item) != -1)
|
||||
{
|
||||
layoutItem = this->layout()->itemAt(i);
|
||||
layoutItem = _contentLayout->itemAt(i);
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(index > 0 && layoutItem)
|
||||
{
|
||||
this->layout()->removeItem(layoutItem);
|
||||
_contentLayout->removeItem(layoutItem);
|
||||
QHBoxLayout * hLayout = new QHBoxLayout();
|
||||
hLayout->addWidget(layoutItem->layout()->itemAt(0)->widget());
|
||||
hLayout->addStretch(0);
|
||||
hLayout->setMargin(0);
|
||||
((QVBoxLayout*)this->layout())->insertLayout(index-1, hLayout);
|
||||
((QVBoxLayout*)_contentLayout)->insertLayout(index-1, hLayout);
|
||||
delete layoutItem;
|
||||
Q_EMIT legendItemMoved(item->curve(), index-1);
|
||||
}
|
||||
@@ -1630,24 +1655,24 @@ void UPlotLegend::moveDown(UPlotLegendItem * item)
|
||||
{
|
||||
int index = -1;
|
||||
QLayoutItem * layoutItem = 0;
|
||||
for(int i=0; i<this->layout()->count(); ++i)
|
||||
for(int i=0; i<_contentLayout->count(); ++i)
|
||||
{
|
||||
if(this->layout()->itemAt(i)->layout() &&
|
||||
this->layout()->itemAt(i)->layout()->indexOf(item) != -1)
|
||||
if(_contentLayout->itemAt(i)->layout() &&
|
||||
_contentLayout->itemAt(i)->layout()->indexOf(item) != -1)
|
||||
{
|
||||
layoutItem = this->layout()->itemAt(i);
|
||||
layoutItem = _contentLayout->itemAt(i);
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(index < this->layout()->count()-2 && layoutItem)
|
||||
if(index < _contentLayout->count()-2 && layoutItem)
|
||||
{
|
||||
this->layout()->removeItem(layoutItem);
|
||||
_contentLayout->removeItem(layoutItem);
|
||||
QHBoxLayout * hLayout = new QHBoxLayout();
|
||||
hLayout->addWidget(layoutItem->layout()->itemAt(0)->widget());
|
||||
hLayout->addStretch(0);
|
||||
hLayout->setMargin(0);
|
||||
((QVBoxLayout*)this->layout())->insertLayout(index+1, hLayout);
|
||||
((QVBoxLayout*)_contentLayout)->insertLayout(index+1, hLayout);
|
||||
delete layoutItem;
|
||||
Q_EMIT legendItemMoved(item->curve(), index+1);
|
||||
}
|
||||
@@ -1739,6 +1764,14 @@ void UPlotLegend::contextMenuEvent(QContextMenuEvent * event)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(action == _aShowAllStdDevMeanMax)
|
||||
{
|
||||
QList<UPlotLegendItem *> items = this->findChildren<UPlotLegendItem*>();
|
||||
for(int i=0; i<items.size(); ++i)
|
||||
{
|
||||
items.at(i)->showStdDevMeanMax(_aShowAllStdDevMeanMax->isChecked());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UPlotLegend::redirectToggled(bool toggled)
|
||||
|
||||
Reference in New Issue
Block a user