Option to display only the current span in smithchart

This commit is contained in:
Jan Käberich 2020-11-06 13:05:09 +01:00
parent c3bcb70d87
commit 1dab72238b
12 changed files with 194 additions and 60 deletions

View File

@ -108,6 +108,7 @@ FORMS += \
Generator/signalgenwidget.ui \ Generator/signalgenwidget.ui \
Tools/impedancematchdialog.ui \ Tools/impedancematchdialog.ui \
Traces/markerwidget.ui \ Traces/markerwidget.ui \
Traces/smithchartdialog.ui \
Traces/traceeditdialog.ui \ Traces/traceeditdialog.ui \
Traces/traceexportdialog.ui \ Traces/traceexportdialog.ui \
Traces/traceimportdialog.ui \ Traces/traceimportdialog.ui \

View File

@ -40,6 +40,7 @@ bool SIUnitEdit::eventFilter(QObject *, QEvent *event)
if(key == Qt::Key_Escape) { if(key == Qt::Key_Escape) {
// abort editing process and set old value // abort editing process and set old value
setValueQuiet(_value); setValueQuiet(_value);
emit editingAborted();
clearFocus(); clearFocus();
return true; return true;
} }
@ -62,6 +63,7 @@ bool SIUnitEdit::eventFilter(QObject *, QEvent *event)
parseNewValue(1.0); parseNewValue(1.0);
} else { } else {
setValueQuiet(_value); setValueQuiet(_value);
emit editingAborted();
} }
} }
return false; return false;

View File

@ -20,6 +20,7 @@ public slots:
signals: signals:
void valueChanged(double newvalue); void valueChanged(double newvalue);
void valueUpdated(QWidget *w); void valueUpdated(QWidget *w);
void editingAborted();
protected: protected:
bool eventFilter(QObject *obj, QEvent *event) override; bool eventFilter(QObject *obj, QEvent *event) override;
private: private:

View File

@ -22,7 +22,7 @@ DeviceLog::DeviceLog(QWidget *parent) :
} }
}); });
connect(ui->numLines, qOverload<int>(&QSpinBox::valueChanged), [=](int lines) { connect(ui->numLines, qOverload<int>(&QSpinBox::valueChanged), [=](int lines) {
ui->text->setMaximumBlockCount(lines); ui->text->setMaximumBlockCount(lines );
}); });
} }

View File

@ -0,0 +1,89 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SmithChartDialog</class>
<widget class="QDialog" name="SmithChartDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>224</width>
<height>69</height>
</rect>
</property>
<property name="windowTitle">
<string>Smithchart Setup</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Display mode:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="displayMode">
<item>
<property name="text">
<string>Show complete traces</string>
</property>
</item>
<item>
<property name="text">
<string>Limit to current span</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>SmithChartDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>SmithChartDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -316,6 +316,9 @@ QWidget *MarkerSettingsDelegate::createEditor(QWidget *parent, const QStyleOptio
e->setMaximumHeight(rowHeight); e->setMaximumHeight(rowHeight);
e->setParent(parent); e->setParent(parent);
connect(e, &SIUnitEdit::valueUpdated, this, &MarkerSettingsDelegate::commitData); connect(e, &SIUnitEdit::valueUpdated, this, &MarkerSettingsDelegate::commitData);
connect(e, &SIUnitEdit::editingAborted, [=](){
marker->editingFrequeny = false;
});
} }
return e; return e;
} }

View File

@ -1,18 +1,20 @@
#include "traceplot.h" #include "traceplot.h"
//const QColor TracePlot::Background = QColor(0,0,0);
//const QColor TracePlot::Border = QColor(255,255,255);
//const QColor TracePlot::Divisions = QColor(255,255,255);
#include "tracemarker.h" #include "tracemarker.h"
std::set<TracePlot*> TracePlot::plots; std::set<TracePlot*> TracePlot::plots;
TracePlot::TracePlot(QWidget *parent) : QWidget(parent) TracePlot::TracePlot(TraceModel &model, QWidget *parent)
: QWidget(parent),
model(model)
{ {
contextmenu = new QMenu(); contextmenu = new QMenu();
markedForDeletion = false; markedForDeletion = false;
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
lastUpdate = QTime::currentTime(); lastUpdate = QTime::currentTime();
sweep_fmin = std::numeric_limits<double>::lowest();
sweep_fmax = std::numeric_limits<double>::max();
// get notified when the span changes
connect(&model, &TraceModel::SpanChanged, this, qOverload<double, double>(&TracePlot::updateSpan));
plots.insert(this); plots.insert(this);
} }
@ -48,7 +50,14 @@ void TracePlot::mouseDoubleClickEvent(QMouseEvent *) {
emit doubleClicked(this); emit doubleClicked(this);
} }
void TracePlot::initializeTraceInfo(TraceModel &model) void TracePlot::updateSpan(double min, double max)
{
sweep_fmin = min;
sweep_fmax = max;
triggerReplot();
}
void TracePlot::initializeTraceInfo()
{ {
// Populate already present traces // Populate already present traces
auto tvect = model.getTraces(); auto tvect = model.getTraces();
@ -69,30 +78,6 @@ void TracePlot::contextMenuEvent(QContextMenuEvent *event)
} }
} }
void TracePlot::updateContextMenu()
{
contextmenu->clear();
contextmenu->addSection("Traces");
// Populate context menu
for(auto t : traces) {
auto action = new QAction(t.first->name(), contextmenu);
action->setCheckable(true);
if(t.second) {
action->setChecked(true);
}
connect(action, &QAction::toggled, [=](bool active) {
enableTrace(t.first, active);
});
contextmenu->addAction(action);
}
contextmenu->addSeparator();
auto close = new QAction("Close", contextmenu);
contextmenu->addAction(close);
connect(close, &QAction::triggered, [=]() {
markedForDeletion = true;
});
}
std::set<TracePlot *> TracePlot::getPlots() std::set<TracePlot *> TracePlot::getPlots()
{ {
return plots; return plots;

View File

@ -11,12 +11,12 @@ class TracePlot : public QWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
TracePlot( QWidget *parent = nullptr); TracePlot(TraceModel &model, QWidget *parent = nullptr);
~TracePlot(); ~TracePlot();
virtual void enableTrace(Trace *t, bool enabled); virtual void enableTrace(Trace *t, bool enabled);
void mouseDoubleClickEvent(QMouseEvent *event) override; void mouseDoubleClickEvent(QMouseEvent *event) override;
virtual void updateSpan(double min, double max){Q_UNUSED(min);Q_UNUSED(max)}; virtual void updateSpan(double min, double max);
static std::set<TracePlot *> getPlots(); static std::set<TracePlot *> getPlots();
@ -25,14 +25,11 @@ signals:
void deleted(TracePlot*); void deleted(TracePlot*);
protected: protected:
// static const QColor Background;// = QColor(0,0,0);
// static const QColor Border;// = QColor(255,255,255);
// static const QColor Divisions;// = QColor(255,255,255);
static constexpr int MinUpdateInterval = 100; static constexpr int MinUpdateInterval = 100;
// need to be called in derived class constructor // need to be called in derived class constructor
void initializeTraceInfo(TraceModel &model); void initializeTraceInfo();
void contextMenuEvent(QContextMenuEvent *event) override; void contextMenuEvent(QContextMenuEvent *event) override;
virtual void updateContextMenu(); virtual void updateContextMenu(){};
virtual bool supported(Trace *t) = 0; virtual bool supported(Trace *t) = 0;
virtual void replot(){}; virtual void replot(){};
std::map<Trace*, bool> traces; std::map<Trace*, bool> traces;
@ -48,6 +45,9 @@ protected slots:
void triggerReplot(); void triggerReplot();
virtual void markerAdded(TraceMarker *m); virtual void markerAdded(TraceMarker *m);
virtual void markerRemoved(TraceMarker *m); virtual void markerRemoved(TraceMarker *m);
protected:
double sweep_fmin, sweep_fmax;
TraceModel &model;
}; };

View File

@ -5,18 +5,37 @@
#include "tracemarker.h" #include "tracemarker.h"
#include <QDebug> #include <QDebug>
#include "preferences.h" #include "preferences.h"
#include "ui_smithchartdialog.h"
using namespace std; using namespace std;
TraceSmithChart::TraceSmithChart(TraceModel &model, QWidget *parent) TraceSmithChart::TraceSmithChart(TraceModel &model, QWidget *parent)
: TracePlot(parent) : TracePlot(model, parent)
{ {
chartLinesPen = QPen(palette().windowText(), 0.75); chartLinesPen = QPen(palette().windowText(), 0.75);
thinPen = QPen(palette().windowText(), 0.25); thinPen = QPen(palette().windowText(), 0.25);
textPen = QPen(palette().windowText(), 0.25); textPen = QPen(palette().windowText(), 0.25);
pointDataPen = QPen(QColor("red"), 4.0, Qt::SolidLine, Qt::RoundCap); pointDataPen = QPen(QColor("red"), 4.0, Qt::SolidLine, Qt::RoundCap);
lineDataPen = QPen(QColor("blue"), 1.0); lineDataPen = QPen(QColor("blue"), 1.0);
initializeTraceInfo(model); limitToSpan = true;
initializeTraceInfo();
}
void TraceSmithChart::axisSetupDialog()
{
auto dialog = new QDialog();
auto ui = new Ui::SmithChartDialog();
ui->setupUi(dialog);
if(limitToSpan) {
ui->displayMode->setCurrentIndex(1);
} else {
ui->displayMode->setCurrentIndex(0);
}
connect(ui->buttonBox, &QDialogButtonBox::accepted, [=](){
limitToSpan = ui->displayMode->currentIndex() == 1;
triggerReplot();
});
dialog->show();
} }
QPoint TraceSmithChart::plotToPixel(std::complex<double> S) QPoint TraceSmithChart::plotToPixel(std::complex<double> S)
@ -43,6 +62,10 @@ void TraceSmithChart::mousePressEvent(QMouseEvent *event)
if(!m->isMovable()) { if(!m->isMovable()) {
continue; continue;
} }
if (limitToSpan && (m->getFrequency() < sweep_fmin || m->getFrequency() > sweep_fmax)) {
// marker outside of currently displayed range
continue;
}
auto S = m->getData(); auto S = m->getData();
auto markerPoint = plotToPixel(S); auto markerPoint = plotToPixel(S);
auto yDiff = abs(markerPoint.y() - clickPoint.y()); auto yDiff = abs(markerPoint.y() - clickPoint.y());
@ -74,6 +97,10 @@ void TraceSmithChart::mouseMoveEvent(QMouseEvent *event)
unsigned int closestIndex = 0; unsigned int closestIndex = 0;
for(unsigned int i=0;i<samples;i++) { for(unsigned int i=0;i<samples;i++) {
auto data = t->sample(i); auto data = t->sample(i);
if (limitToSpan && (data.frequency < sweep_fmin || data.frequency > sweep_fmax)) {
// destination point outside of currently displayed range
continue;
}
auto distance = norm(data.S - mouseS); auto distance = norm(data.S - mouseS);
if(distance < closestDistance) { if(distance < closestDistance) {
closestDistance = distance; closestDistance = distance;
@ -136,21 +163,27 @@ void TraceSmithChart::draw(QPainter * painter, double width_factor) {
painter->setPen(QPen(trace->color(), 1.5 * width_factor)); painter->setPen(QPen(trace->color(), 1.5 * width_factor));
int nPoints = trace->size(); int nPoints = trace->size();
for(int i=1;i<nPoints;i++) { for(int i=1;i<nPoints;i++) {
auto last = trace->sample(i-1).S; auto last = trace->sample(i-1);
auto now = trace->sample(i).S; auto now = trace->sample(i);
if(isnan(now.real())) { if (limitToSpan && (last.frequency < sweep_fmin || now.frequency > sweep_fmax)) {
continue;
}
if(isnan(now.S.real())) {
break; break;
} }
// scale to size of smith diagram // scale to size of smith diagram
last *= smithCoordMax; last.S *= smithCoordMax;
now *= smithCoordMax; now.S *= smithCoordMax;
// draw line // draw line
painter->drawLine(std::real(last), -std::imag(last), std::real(now), -std::imag(now)); painter->drawLine(std::real(last.S), -std::imag(last.S), std::real(now.S), -std::imag(now.S));
} }
if(trace->size() > 0) { if(trace->size() > 0) {
// only draw markers if the trace has at least one point // only draw markers if the trace has at least one point
auto markers = t.first->getMarkers(); auto markers = t.first->getMarkers();
for(auto m : markers) { for(auto m : markers) {
if (limitToSpan && (m->getFrequency() < sweep_fmin || m->getFrequency() > sweep_fmax)) {
continue;
}
auto coords = m->getData(); auto coords = m->getData();
coords *= smithCoordMax; coords *= smithCoordMax;
auto symbol = m->getSymbol(); auto symbol = m->getSymbol();
@ -187,6 +220,34 @@ void TraceSmithChart::paintEvent(QPaintEvent * /* the event */)
draw(&painter, 2*smithCoordMax/side); draw(&painter, 2*smithCoordMax/side);
} }
void TraceSmithChart::updateContextMenu()
{
contextmenu->clear();
contextmenu->clear();
auto setup = new QAction("Setup...", contextmenu);
connect(setup, &QAction::triggered, this, &TraceSmithChart::axisSetupDialog);
contextmenu->addAction(setup);
contextmenu->addSection("Traces");
// Populate context menu
for(auto t : traces) {
auto action = new QAction(t.first->name(), contextmenu);
action->setCheckable(true);
if(t.second) {
action->setChecked(true);
}
connect(action, &QAction::toggled, [=](bool active) {
enableTrace(t.first, active);
});
contextmenu->addAction(action);
}
contextmenu->addSeparator();
auto close = new QAction("Close", contextmenu);
contextmenu->addAction(close);
connect(close, &QAction::triggered, [=]() {
markedForDeletion = true;
});
}
bool TraceSmithChart::supported(Trace *t) bool TraceSmithChart::supported(Trace *t)
{ {
if(t->isReflection()) { if(t->isReflection()) {

View File

@ -9,7 +9,8 @@ class TraceSmithChart : public TracePlot
Q_OBJECT Q_OBJECT
public: public:
TraceSmithChart(TraceModel &model, QWidget *parent = 0); TraceSmithChart(TraceModel &model, QWidget *parent = 0);
public slots:
void axisSetupDialog();
protected: protected:
static constexpr double ReferenceImpedance = 50.0; static constexpr double ReferenceImpedance = 50.0;
static constexpr double screenUsage = 0.9; static constexpr double screenUsage = 0.9;
@ -21,7 +22,7 @@ protected:
void mousePressEvent(QMouseEvent *event) override; void mousePressEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override; void mouseMoveEvent(QMouseEvent *event) override;
void paintEvent(QPaintEvent *event) override; void paintEvent(QPaintEvent *event) override;
virtual void updateContextMenu() override;
bool supported(Trace *t) override; bool supported(Trace *t) override;
void draw(QPainter * painter, double width_factor); void draw(QPainter * painter, double width_factor);
void replot() override; void replot() override;
@ -30,6 +31,7 @@ protected:
QPen thinPen; QPen thinPen;
QPen pointDataPen; QPen pointDataPen;
QPen lineDataPen; QPen lineDataPen;
bool limitToSpan;
/// Path for the thin arcs /// Path for the thin arcs
QPainterPath thinArcsPath; QPainterPath thinArcsPath;

View File

@ -115,7 +115,7 @@ private:
}; };
TraceXYPlot::TraceXYPlot(TraceModel &model, QWidget *parent) TraceXYPlot::TraceXYPlot(TraceModel &model, QWidget *parent)
: TracePlot(parent), : TracePlot(model, parent),
selectedMarker(nullptr) selectedMarker(nullptr)
{ {
YAxis[0].log = false; YAxis[0].log = false;
@ -164,7 +164,7 @@ TraceXYPlot::TraceXYPlot(TraceModel &model, QWidget *parent)
layout->setContentsMargins(0, 0, 0, 0); layout->setContentsMargins(0, 0, 0, 0);
setLayout(layout); setLayout(layout);
plot->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); plot->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
initializeTraceInfo(model); initializeTraceInfo();
setAutoFillBackground(true); setAutoFillBackground(true);
// Setup default axis // Setup default axis
@ -173,8 +173,6 @@ TraceXYPlot::TraceXYPlot(TraceModel &model, QWidget *parent)
// enable autoscaling and set for full span (no information about actual span available yet) // enable autoscaling and set for full span (no information about actual span available yet)
updateSpan(0, 6000000000); updateSpan(0, 6000000000);
setXAxis(XAxisType::Frequency, XAxisMode::UseSpan, 0, 6000000000, 600000000); setXAxis(XAxisType::Frequency, XAxisMode::UseSpan, 0, 6000000000, 600000000);
// get notified when the span changes
connect(&model, &TraceModel::SpanChanged, this, qOverload<double, double>(&TraceXYPlot::updateSpan));
allPlots.insert(this); allPlots.insert(this);
} }
@ -190,12 +188,6 @@ TraceXYPlot::~TraceXYPlot()
allPlots.erase(this); allPlots.erase(this);
} }
void TraceXYPlot::updateSpan(double min, double max)
{
sweep_fmin = min;
sweep_fmax = max;
}
void TraceXYPlot::setYAxis(int axis, TraceXYPlot::YAxisType type, bool log, bool autorange, double min, double max, double div) void TraceXYPlot::setYAxis(int axis, TraceXYPlot::YAxisType type, bool log, bool autorange, double min, double max, double div)
{ {
if(YAxis[axis].type != type) { if(YAxis[axis].type != type) {

View File

@ -57,7 +57,6 @@ public:
Manual, Manual,
}; };
virtual void updateSpan(double min, double max) override;
void setYAxis(int axis, YAxisType type, bool log, bool autorange, double min, double max, double div); void setYAxis(int axis, YAxisType type, bool log, bool autorange, double min, double max, double div);
void setXAxis(XAxisType type, XAxisMode mode, double min, double max, double div); void setXAxis(XAxisType type, XAxisMode mode, double min, double max, double div);
void enableTrace(Trace *t, bool enabled) override; void enableTrace(Trace *t, bool enabled) override;
@ -114,7 +113,6 @@ private:
YAxis YAxis[2]; YAxis YAxis[2];
XAxis XAxis; XAxis XAxis;
double sweep_fmin, sweep_fmax;
using CurveData = struct { using CurveData = struct {
QwtPlotCurve *curve; QwtPlotCurve *curve;