PDA

View Full Version : some questions about qwt scale and manipulation



silent_missile
25th June 2014, 09:19
now I'm developing a software to plot and manipulate some lines in the GUI, but I meet some difficulties.


1) I hope to have a fixed scale when resize the window or the tabwidget, so that means the scale range would change but the div would not change. I read all examples of qwt, but I can't find it. it seems QwtPlotRescaler can realize it, but it seems conflict with the 2nd requirement.

2) I have a tabwidget with more than 1 tabs for the manipulation, I hope they can use same scale, it seems I can add signal and slot connection to solve it, but when I test it, I found there is different display when I scale it by mouse wheel or resize the window. because only one tab is shown, so the hidden tab would not rescale.

3) I hope to add manipulation of the plot. left button to manipulate the point to move and replot the line simultaneously, mid button to move, and wheel to zoom, also mouse position as the zoom center. I find some helpful information about it. QwtPlotMagnifier can help the wheel zoom, but I can't find the setting of zoom center, it always zoom by original point. QwtPlotPanner can help the move operation, what I need to do is just to change the mouse button to mid button. but I can't find any class can help for the point drag and move manipulation. In examples I found the event_filter example, it's very similar like what I need, and I tried to use similar method, but it can't work, if I set the mouse button to left button, then I can't move the point.

A simple summary is if I want to have a lot of operations on keyboard and mouse, such as:
a) left button single click/double click means different action
b) left button drag from empty position is rubber band picker, from some element means drag the element
c) midbutton drag to move the plot
d) right button single click zoom to fit, drag means rubber band zoom
e) left and mid button together means some operation
f) keep left pressed, and press mid button then release left button means some operation
...a lot of operations, how can I realize it?

eventFilter maybe a good solution. but if I want to use existing classes within qwt to move plot, move item, zoom...how can I call them in the eventFilter?




class main_window : public QMainWindow
{
Q_OBJECT
public:
explicit main_window(QWidget *parent = 0);
~main_window();
signals:

public slots:

private:
QTabWidget *_tabs;
};

main_window::main_window(QWidget *parent) :
QMainWindow(parent)
{
_tabs = new QTabWidget(this);
for(int n1(0);n1<2;++n1
{
_tabs->addTab(new QWidget(), QString::number(n1));
_plots.push_back(new main_plot(_tabs->widget(n1)));
QGridLayout *lay = new QGridLayout(meridional_tabs->widget(n1));
lay->addWidget(main_plots[n1],0,0);
main_plots[n1]->plot_curves();
for(int n2(0);n2<static_cast<int>(main_plots.size());++n2)
{
if(n1!=n2)
{
connect((QObject*)(main_plots[n1]->axisWidget(QwtPlot::xBottom)),SIGNAL(scaleDivChang ed()),meridional_plots[n2],SLOT(scaleDivChangedSlot()));
connect((QObject*)(main_plots[n2]->axisWidget(QwtPlot::xBottom)),SIGNAL(scaleDivChang ed()),meridional_plots[n1],SLOT(scaleDivChangedSlot()));
}
}
}
setCentralWidget(_tabs);
}

class main_plot : public QwtPlot
{
Q_OBJECT
public:
main_plot(QWidget *parent = nullptr);
public Q_SLOTS:
void plot_curves();
private:
QVector<QwtPlotCurve*> curves;
QwtPlotRescaler *rescaler;
QwtPlotMagnifier *pm;
QwtPlotPanner *pp;
private Q_SLOTS:
void scaleDivChangedSlot();
};

ain_plot::main_plot(QWidget *parent ):
QwtPlot( parent )
{
setCanvasColor( Qt::white );
// Avoid jumping when label with 3 digits
// appear/disappear when scrolling especially for y axis
QwtScaleDraw *sdy = axisScaleDraw( QwtPlot::yLeft );
sdy->setMinimumExtent( sdy->extent( axisWidget( QwtPlot::yLeft )->font() ) );
setAxisTitle(QwtPlot::yLeft, "r");
QwtScaleDraw *sdx = axisScaleDraw( QwtPlot::xBottom );
sdx->setMinimumExtent( sdx->extent( axisWidget( QwtPlot::xBottom )->font() ) );
setAxisTitle(QwtPlot::xBottom, "z");
plotLayout()->setAlignCanvasToScales( true );
rescaler = new QwtPlotRescaler(canvas(),QwtPlot::xBottom,QwtPlotR escaler::Expanding);
rescaler->setAspectRatio(QwtPlot::yLeft,1.0);
rescaler->setAspectRatio(QwtPlot::xTop,0.0);
rescaler->setAspectRatio(QwtPlot::yRight,0.0);
pm = new QwtPlotMagnifier( canvas() );
pp = new QwtPlotPanner(canvas());
pp->setMouseButton(Qt::MidButton,Qt::NoModifier);
replot();
}

void main_plot::plot_curves()
{
//add some code to plot a simple curve
}

void main_plot::scaleDivChangedSlot()
{
QwtPlot *plt = qobject_cast<QwtPlot*>((sender())->parent());
QwtInterval intv = plt->axisInterval (QwtPlot::xBottom);
this->setAxisScale(QwtPlot::xBottom, intv.minValue(), intv.maxValue());
intv = plt->axisInterval (QwtPlot::yLeft);
this->setAxisScale(QwtPlot::yLeft, intv.minValue(), intv.maxValue());
this->replot();
}


also English is not my mother language, sometimes I can't understand the difference of scale/zoom, div/scale/interval, if anybody can explain it to me more visually, I appreciate very much.

Uwe
25th June 2014, 19:20
1) I hope to have a fixed scale when resize the window or the tabwidget, so that means the scale range would change but the div would not change. I read all examples of qwt, but I can't find it. it seems QwtPlotRescaler can realize it, but it seems conflict with the 2nd requirement.
QwtPlotRescaler adjusts the scales/axes according to resize events of the plot canvas and it sounds like this is indeed what you are looking for. How to synchronize these changes with scales of another plot is another story - usually somehow done by connecting to the QwtScaleWidget::scaleDivChanged() signal.



3) I hope to add manipulation of the plot. left button to manipulate the point to move and replot the line simultaneously, mid button to move, and wheel to zoom, also mouse position as the zoom center.

Here you have to overload some methods of QwtPlotMagnifier.



QwtPlotMagnifier::widgetWheelEvent to store the position of the wheel.
QwtPlotMagnifier::rescale to use the position



QwtPlotMagnifier::rescale is only a couple of lines. I would copy them to your overloaded method and modify it.


I can't understand the difference of scale/zoom, div/scale/interval, if anybody can explain it to me more visually, I appreciate very much.
In the terminology of qwt ( what does not necessarily has to be good English ) a scale is a scale, while zooming is usually used for for setting the range of a scale. An interval is a range with a lower and an upper bound, while a scale division is the bounding interval and the position of the ticks of a scale.

Uwe