Added a scope widget in the channel analyzer plugin

This commit is contained in:
f4exb 2015-06-22 04:16:27 +02:00
parent cf198f0450
commit c9f9990764
10 changed files with 680 additions and 24 deletions

View File

@ -77,6 +77,7 @@ set(sdrbase_SOURCES
sdrbase/gui/buttonswitch.cpp
sdrbase/gui/channelwindow.cpp
sdrbase/gui/glscope.cpp
sdrbase/gui/glscopegui.cpp
sdrbase/gui/glspectrum.cpp
sdrbase/gui/glspectrumgui.cpp
sdrbase/gui/indicator.cpp
@ -147,6 +148,7 @@ set(sdrbase_HEADERS
include-gpl/gui/buttonswitch.h
include-gpl/gui/channelwindow.h
include-gpl/gui/glscope.h
include-gpl/gui/glscopegui.h
include-gpl/gui/glspectrum.h
include-gpl/gui/glspectrumgui.h
include-gpl/gui/indicator.h
@ -190,6 +192,7 @@ set(sdrbase_FORMS
sdrbase/gui/aboutdialog.ui
sdrbase/gui/addpresetdialog.ui
sdrbase/gui/basicchannelsettingswidget.ui
sdrbase/gui/glscopegui.ui
sdrbase/gui/glspectrumgui.ui
sdrbase/gui/pluginsdialog.ui
sdrbase/gui/preferencesdialog.ui

View File

@ -109,6 +109,7 @@ Done since the fork
- Filter out CTCSS tones for audio and full CTCSS support in NFMDemod
- Enhancement of the NFM squelch
- Added a channel analyzer plugin focusing on measurement (DSA/DSO functionnality). Basic functions.
- Added a scope widget in the channel analyzer plugin
=====
To Do

View File

@ -0,0 +1,60 @@
#ifndef INCLUDE_GLSCOPEGUI_H
#define INCLUDE_GLSCOPEGUI_H
#include <QWidget>
#include "dsp/dsptypes.h"
#include "util/export.h"
#include "util/message.h"
namespace Ui {
class GLScopeGUI;
}
class MessageQueue;
class ScopeVis;
class GLScope;
class SDRANGELOVE_API GLScopeGUI : public QWidget {
Q_OBJECT
public:
explicit GLScopeGUI(QWidget* parent = NULL);
~GLScopeGUI();
void setBuddies(MessageQueue* messageQueue, ScopeVis* scopeVis, GLScope* glScope);
void resetToDefaults();
QByteArray serialize() const;
bool deserialize(const QByteArray& data);
bool handleMessage(Message* message);
private:
Ui::GLScopeGUI* ui;
MessageQueue* m_messageQueue;
ScopeVis* m_scopeVis;
GLScope* m_glScope;
int m_sampleRate;
qint32 m_displayData;
qint32 m_displayOrientation;
qint32 m_timeBase;
qint32 m_timeOffset;
qint32 m_amplification;
void applySettings();
private slots:
void on_amp_valueChanged(int value);
void on_scope_traceSizeChanged(int value);
void on_time_valueChanged(int value);
void on_timeOfs_valueChanged(int value);
void on_displayMode_currentIndexChanged(int index);
void on_horizView_clicked();
void on_vertView_clicked();
};
#endif // INCLUDE_GLSCOPEGUI_H

View File

@ -26,8 +26,9 @@
MESSAGE_CLASS_DEFINITION(ChannelAnalyzer::MsgConfigureChannelAnalyzer, Message)
ChannelAnalyzer::ChannelAnalyzer(SampleSink* sampleSink) :
m_sampleSink(sampleSink)
ChannelAnalyzer::ChannelAnalyzer(SampleSink* spectrumSink, SampleSink* scopeSink) :
m_spectrumSink(spectrumSink),
m_scopeSink(scopeSink)
{
m_Bandwidth = 5000;
m_LowCutoff = 300;
@ -101,9 +102,14 @@ void ChannelAnalyzer::feed(SampleVector::const_iterator begin, SampleVector::con
}
}
if(m_sampleSink != NULL)
if(m_spectrumSink != NULL)
{
m_sampleSink->feed(m_sampleBuffer.begin(), m_sampleBuffer.end(), m_ssb); // m_ssb = positive only
m_spectrumSink->feed(m_sampleBuffer.begin(), m_sampleBuffer.end(), m_ssb); // m_ssb = positive only
}
if(m_scopeSink != NULL)
{
m_scopeSink->feed(m_sampleBuffer.begin(), m_sampleBuffer.end(), false); // positive only is unused
}
m_sampleBuffer.clear();
@ -160,8 +166,8 @@ bool ChannelAnalyzer::handleMessage(Message* cmd)
cmd->completed();
return true;
} else {
if(m_sampleSink != NULL)
return m_sampleSink->handleMessage(cmd);
if(m_spectrumSink != NULL)
return m_spectrumSink->handleMessage(cmd);
else return false;
}
}

View File

@ -32,7 +32,7 @@
class ChannelAnalyzer : public SampleSink {
public:
ChannelAnalyzer(SampleSink* sampleSink);
ChannelAnalyzer(SampleSink* spectrumSink, SampleSink* scopeSink);
~ChannelAnalyzer();
void configure(MessageQueue* messageQueue,
@ -100,7 +100,8 @@ private:
fftfilt* SSBFilter;
fftfilt* DSBFilter;
SampleSink* m_sampleSink;
SampleSink* m_spectrumSink;
SampleSink* m_scopeSink;
SampleVector m_sampleBuffer;
};

View File

@ -4,7 +4,9 @@
#include "dsp/threadedsamplesink.h"
#include "dsp/channelizer.h"
#include "dsp/spectrumvis.h"
#include "dsp/scopevis.h"
#include "gui/glspectrum.h"
#include "gui/glscope.h"
#include "plugin/pluginapi.h"
#include "util/simpleserializer.h"
#include "gui/basicchannelsettingswidget.h"
@ -245,13 +247,12 @@ ChannelAnalyzerGUI::ChannelAnalyzerGUI(PluginAPI* pluginAPI, QWidget* parent) :
connect(this, SIGNAL(widgetRolled(QWidget*,bool)), this, SLOT(onWidgetRolled(QWidget*,bool)));
connect(this, SIGNAL(menuDoubleClickEvent()), this, SLOT(onMenuDoubleClicked()));
//m_audioFifo = new AudioFifo(4, 48000 / 4);
m_spectrumVis = new SpectrumVis(ui->glSpectrum);
m_channelAnalyzer = new ChannelAnalyzer(m_spectrumVis);
m_scopeVis = new ScopeVis(ui->glScope);
m_channelAnalyzer = new ChannelAnalyzer(m_spectrumVis, m_scopeVis);
m_channelizer = new Channelizer(m_channelAnalyzer);
m_threadedSampleSink = new ThreadedSampleSink(m_channelizer);
//m_pluginAPI->addAudioSource(m_audioFifo);
m_pluginAPI->addSampleSink(m_threadedSampleSink);
m_threadedSpectrumSampleSink = new ThreadedSampleSink(m_channelizer);
m_pluginAPI->addSampleSink(m_threadedSpectrumSampleSink);
ui->glSpectrum->setCenterFrequency(m_rate/2);
ui->glSpectrum->setSampleRate(m_rate);
@ -268,7 +269,8 @@ ChannelAnalyzerGUI::ChannelAnalyzerGUI(PluginAPI* pluginAPI, QWidget* parent) :
connect(m_channelMarker, SIGNAL(changed()), this, SLOT(viewChanged()));
m_pluginAPI->addChannelMarker(m_channelMarker);
ui->spectrumGUI->setBuddies(m_threadedSampleSink->getMessageQueue(), m_spectrumVis, ui->glSpectrum);
ui->spectrumGUI->setBuddies(m_threadedSpectrumSampleSink->getMessageQueue(), m_spectrumVis, ui->glSpectrum);
ui->scopeGUI->setBuddies(m_threadedScopeSampleSink->getMessageQueue(), m_scopeVis, ui->glScope);
applySettings();
}
@ -276,13 +278,14 @@ ChannelAnalyzerGUI::ChannelAnalyzerGUI(PluginAPI* pluginAPI, QWidget* parent) :
ChannelAnalyzerGUI::~ChannelAnalyzerGUI()
{
m_pluginAPI->removeChannelInstance(this);
//m_pluginAPI->removeAudioSource(m_audioFifo);
m_pluginAPI->removeSampleSink(m_threadedSampleSink);
delete m_threadedSampleSink;
m_pluginAPI->removeSampleSink(m_threadedSpectrumSampleSink);
m_pluginAPI->removeSampleSink(m_threadedScopeSampleSink);
delete m_threadedSpectrumSampleSink;
delete m_threadedScopeSampleSink;
delete m_channelizer;
delete m_channelAnalyzer;
delete m_spectrumVis;
//delete m_audioFifo;
delete m_scopeVis;
delete m_channelMarker;
delete ui;
}
@ -348,10 +351,10 @@ void ChannelAnalyzerGUI::applySettings()
setTitleColor(m_channelMarker->getColor());
ui->deltaFrequency->setValue(abs(m_channelMarker->getCenterFrequency()));
ui->deltaMinus->setChecked(m_channelMarker->getCenterFrequency() < 0);
m_channelizer->configure(m_threadedSampleSink->getMessageQueue(),
m_channelizer->configure(m_threadedSpectrumSampleSink->getMessageQueue(),
48000,
m_channelMarker->getCenterFrequency());
m_channelAnalyzer->configure(m_threadedSampleSink->getMessageQueue(),
m_channelAnalyzer->configure(m_threadedSpectrumSampleSink->getMessageQueue(),
ui->BW->value() * 100.0,
ui->lowCut->value() * 100.0,
m_spanLog2,

View File

@ -12,6 +12,7 @@ class ThreadedSampleSink;
class Channelizer;
class ChannelAnalyzer;
class SpectrumVis;
class ScopeVis;
namespace Ui {
class ChannelAnalyzerGUI;
@ -52,11 +53,12 @@ private:
int m_rate;
int m_spanLog2;
//AudioFifo* m_audioFifo;
ThreadedSampleSink* m_threadedSampleSink;
ThreadedSampleSink* m_threadedSpectrumSampleSink;
ThreadedSampleSink* m_threadedScopeSampleSink;
Channelizer* m_channelizer;
ChannelAnalyzer* m_channelAnalyzer;
SpectrumVis* m_spectrumVis;
ScopeVis* m_scopeVis;
explicit ChannelAnalyzerGUI(PluginAPI* pluginAPI, QWidget* parent = NULL);
~ChannelAnalyzerGUI();

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>302</width>
<height>439</height>
<height>719</height>
</rect>
</property>
<property name="minimumSize">
@ -347,7 +347,7 @@
<property name="windowTitle">
<string>Channel Spectrum</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<layout class="QVBoxLayout" name="verticalLayoutSpectrum">
<property name="spacing">
<number>2</number>
</property>
@ -384,6 +384,55 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="scopeContainer" native="true">
<property name="geometry">
<rect>
<x>40</x>
<y>430</y>
<width>241</width>
<height>284</height>
</rect>
</property>
<property name="windowTitle">
<string>Channel Scope</string>
</property>
<layout class="QVBoxLayout" name="verticalLayoutScope">
<property name="spacing">
<number>2</number>
</property>
<property name="leftMargin">
<number>3</number>
</property>
<property name="topMargin">
<number>3</number>
</property>
<property name="rightMargin">
<number>3</number>
</property>
<property name="bottomMargin">
<number>3</number>
</property>
<item>
<widget class="GLScope" name="glScope" native="true">
<property name="minimumSize">
<size>
<width>200</width>
<height>250</height>
</size>
</property>
<property name="font">
<font>
<family>Courier</family>
<pointsize>8</pointsize>
</font>
</property>
</widget>
</item>
<item>
<widget class="GLScopeGUI" name="scopeGUI" native="true"/>
</item>
</layout>
</widget>
</widget>
<customwidgets>
<customwidget>
@ -410,6 +459,18 @@
<header>gui/valuedial.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>GLScope</class>
<extends>QWidget</extends>
<header>gui/glscope.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>GLScopeGUI</class>
<extends>QWidget</extends>
<header>gui/glscopegui.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>

198
sdrbase/gui/glscopegui.cpp Normal file
View File

@ -0,0 +1,198 @@
#include "gui/glscopegui.h"
#include "dsp/scopevis.h"
#include "dsp/dspcommands.h"
#include "gui/glscope.h"
#include "util/simpleserializer.h"
#include "ui_glscopegui.h"
GLScopeGUI::GLScopeGUI(QWidget* parent) :
QWidget(parent),
ui(new Ui::GLScopeGUI),
m_messageQueue(NULL),
m_scopeVis(NULL),
m_glScope(NULL),
m_sampleRate(0),
m_displayData(GLScope::ModeIQ),
m_displayOrientation(Qt::Horizontal),
m_timeBase(1),
m_timeOffset(0),
m_amplification(0)
{
ui->setupUi(this);
}
GLScopeGUI::~GLScopeGUI()
{
delete ui;
}
void GLScopeGUI::setBuddies(MessageQueue* messageQueue, ScopeVis* scopeVis, GLScope* glScope)
{
m_messageQueue = messageQueue;
m_scopeVis = scopeVis;
m_glScope = glScope;
applySettings();
}
void GLScopeGUI::resetToDefaults()
{
m_displayData = GLScope::ModeIQ;
m_displayOrientation = Qt::Horizontal;
m_timeBase = 1;
m_timeOffset = 0;
m_amplification = 0;
applySettings();
}
QByteArray GLScopeGUI::serialize() const
{
SimpleSerializer s(1);
s.writeS32(1, m_displayData);
s.writeS32(2, m_displayOrientation);
s.writeS32(3, m_timeBase);
s.writeS32(4, m_timeOffset);
s.writeS32(5, m_amplification);
return s.final();
}
bool GLScopeGUI::deserialize(const QByteArray& data)
{
SimpleDeserializer d(data);
if(!d.isValid()) {
resetToDefaults();
return false;
}
if(d.getVersion() == 1) {
d.readS32(1, &m_displayData, GLScope::ModeIQ);
d.readS32(2, &m_displayOrientation, Qt::Horizontal);
d.readS32(3, &m_timeBase, 1);
d.readS32(4, &m_timeOffset, 0);
d.readS32(5, &m_amplification, 0);
if(m_timeBase < 0)
m_timeBase = 1;
applySettings();
return true;
} else {
resetToDefaults();
return false;
}
}
void GLScopeGUI::applySettings()
{
ui->dataMode->setCurrentIndex(m_displayData);
if(m_displayOrientation == Qt::Horizontal) {
m_glScope->setOrientation(Qt::Horizontal);
ui->horizView->setChecked(true);
ui->vertView->setChecked(false);
} else {
m_glScope->setOrientation(Qt::Vertical);
ui->horizView->setChecked(false);
ui->vertView->setChecked(true);
}
ui->time->setValue(m_timeBase);
ui->timeOfs->setValue(m_timeOffset);
ui->amp->setValue(m_amplification);
}
void GLScopeGUI::on_amp_valueChanged(int value)
{
static qreal amps[11] = { 0.2, 0.1, 0.05, 0.02, 0.01, 0.005, 0.002, 0.001, 0.0005, 0.0002, 0.0001 };
ui->ampText->setText(tr("%1\n/div").arg(amps[value], 0, 'f', 4));
m_glScope->setAmp(0.2 / amps[value]);
m_amplification = value;
}
void GLScopeGUI::on_scope_traceSizeChanged(int)
{
qreal t = (m_glScope->getTraceSize() * 0.1 / m_sampleRate) / (qreal)m_timeBase;
if(t < 0.000001)
ui->timeText->setText(tr("%1\nns/div").arg(t * 1000000000.0));
else if(t < 0.001)
ui->timeText->setText(tr("%1\nµs/div").arg(t * 1000000.0));
else if(t < 1.0)
ui->timeText->setText(tr("%1\nms/div").arg(t * 1000.0));
else ui->timeText->setText(tr("%1\ns/div").arg(t * 1.0));
}
void GLScopeGUI::on_time_valueChanged(int value)
{
m_timeBase = value;
on_scope_traceSizeChanged(0);
m_glScope->setTimeBase(m_timeBase);
}
void GLScopeGUI::on_timeOfs_valueChanged(int value)
{
m_timeOffset = value;
m_glScope->setTimeOfsProMill(value);
}
void GLScopeGUI::on_displayMode_currentIndexChanged(int index)
{
m_displayData = index;
switch(index) {
case 0: // i+q
m_glScope->setMode(GLScope::ModeIQ);
break;
case 1: // mag(lin)+pha
m_glScope->setMode(GLScope::ModeMagLinPha);
break;
case 2: // mag(dB)+pha
m_glScope->setMode(GLScope::ModeMagdBPha);
break;
case 3: // derived1+derived2
m_glScope->setMode(GLScope::ModeDerived12);
break;
case 4: // clostationary
m_glScope->setMode(GLScope::ModeCyclostationary);
break;
default:
break;
}
}
void GLScopeGUI::on_horizView_clicked()
{
m_displayOrientation = Qt::Horizontal;
if(ui->horizView->isChecked()) {
ui->vertView->setChecked(false);
m_glScope->setOrientation(Qt::Horizontal);
} else {
ui->horizView->setChecked(true);
}
}
void GLScopeGUI::on_vertView_clicked()
{
m_displayOrientation = Qt::Vertical;
if(ui->vertView->isChecked()) {
ui->horizView->setChecked(false);
m_glScope->setOrientation(Qt::Vertical);
} else {
ui->vertView->setChecked(true);
m_glScope->setOrientation(Qt::Vertical);
}
}
bool GLScopeGUI::handleMessage(Message* cmd)
{
if(DSPSignalNotification::match(cmd))
{
DSPSignalNotification* signal = (DSPSignalNotification*)cmd;
//fprintf(stderr, "%d samples/sec, %lld Hz offset", signal->getSampleRate(), signal->getFrequencyOffset());
m_sampleRate = signal->getSampleRate();
cmd->completed();
return true;
}
else
{
return false;
}
}

321
sdrbase/gui/glscopegui.ui Normal file
View File

@ -0,0 +1,321 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>GLScopeGUI</class>
<widget class="QWidget" name="GLScopeGUI">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>798</width>
<height>40</height>
</rect>
</property>
<property name="windowTitle">
<string>Oscilloscope</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>3</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>3</number>
</property>
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
<widget class="QLabel" name="dataLabel">
<property name="text">
<string>Data</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="dataMode">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContentsOnFirstShow</enum>
</property>
<item>
<property name="text">
<string>I+Q Level (linear)</string>
</property>
</item>
<item>
<property name="text">
<string>Magnitude (linear) + Phase</string>
</property>
</item>
<item>
<property name="text">
<string>Magnitude (dB) + Phase</string>
</property>
</item>
<item>
<property name="text">
<string>Derived 1st + 2nd order</string>
</property>
</item>
<item>
<property name="text">
<string>Cyclostationary</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="Line" name="dataLine">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="viewLayout">
<property name="spacing">
<number>0</number>
</property>
<item>
<widget class="QToolButton" name="horizView">
<property name="toolTip">
<string>Horizontal display arrangement</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../resources/res.qrc">
<normaloff>:/horizontal.png</normaloff>:/horizontal.png</iconset>
</property>
<property name="iconSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="vertView">
<property name="toolTip">
<string>Vertical display arrangement</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../resources/res.qrc">
<normaloff>:/vertical.png</normaloff>:/vertical.png</iconset>
</property>
<property name="iconSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="Line" name="viewLine">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="timeLabel">
<property name="text">
<string>Time</string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="time">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="pageStep">
<number>5</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
<property name="tickInterval">
<number>5</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="timeText">
<property name="minimumSize">
<size>
<width>40</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>0.1000
/div</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="timeOfs">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="pageStep">
<number>10</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::NoTicks</enum>
</property>
<property name="tickInterval">
<number>50</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="timeOfsLabel">
<property name="text">
<string>0</string>
</property>
</widget>
</item>
<item>
<widget class="Line" name="timeLine">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="ampLabel">
<property name="text">
<string>Amp</string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="amp">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>8</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="value">
<number>0</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
<property name="tickInterval">
<number>1</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="ampText">
<property name="minimumSize">
<size>
<width>40</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>0.2000
/div</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources>
<include location="../resources/res.qrc"/>
</resources>
<connections/>
</ui>