diff options
author | Tom Rondeau <tom@trondeau.com> | 2014-03-10 23:52:21 -0400 |
---|---|---|
committer | Tom Rondeau <tom@trondeau.com> | 2014-03-14 18:23:16 +0100 |
commit | 7d4c52b4e98ff02ac3bc73a5e543ad7dfb26e69b (patch) | |
tree | 7dedefb7b1a9ee80553ce5cb6a44793e84d97b87 | |
parent | 5568d1e1ca12f0d002541b8cbb68ac558e826a47 (diff) |
qtgui: Adding a Number sink with options to set autoscale, layout style, colors, averaging.
-rw-r--r-- | gr-qtgui/grc/qtgui_block_tree.xml | 9 | ||||
-rw-r--r-- | gr-qtgui/grc/qtgui_number_sink.xml | 118 | ||||
-rw-r--r-- | gr-qtgui/include/gnuradio/qtgui/CMakeLists.txt | 3 | ||||
-rw-r--r-- | gr-qtgui/include/gnuradio/qtgui/DisplayPlot.h | 3 | ||||
-rw-r--r-- | gr-qtgui/include/gnuradio/qtgui/NumberDisplayPlot.h | 54 | ||||
-rw-r--r-- | gr-qtgui/include/gnuradio/qtgui/form_menus.h | 210 | ||||
-rw-r--r-- | gr-qtgui/include/gnuradio/qtgui/number_sink.h | 110 | ||||
-rw-r--r-- | gr-qtgui/include/gnuradio/qtgui/numberdisplayform.h | 101 | ||||
-rw-r--r-- | gr-qtgui/include/gnuradio/qtgui/spectrumUpdateEvents.h | 26 | ||||
-rw-r--r-- | gr-qtgui/lib/CMakeLists.txt | 5 | ||||
-rw-r--r-- | gr-qtgui/lib/NumberDisplayPlot.cc | 63 | ||||
-rw-r--r-- | gr-qtgui/lib/number_sink_impl.cc | 290 | ||||
-rw-r--r-- | gr-qtgui/lib/number_sink_impl.h | 114 | ||||
-rw-r--r-- | gr-qtgui/lib/numberdisplayform.cc | 375 | ||||
-rw-r--r-- | gr-qtgui/lib/spectrumUpdateEvents.cc | 22 | ||||
-rw-r--r-- | gr-qtgui/swig/qtgui_swig.i | 3 |
16 files changed, 1481 insertions, 25 deletions
diff --git a/gr-qtgui/grc/qtgui_block_tree.xml b/gr-qtgui/grc/qtgui_block_tree.xml index 14516df71e..2fc1b0343e 100644 --- a/gr-qtgui/grc/qtgui_block_tree.xml +++ b/gr-qtgui/grc/qtgui_block_tree.xml @@ -2,19 +2,19 @@ <!-- Copyright 2012-2013 Free Software Foundation, Inc. - + This file is part of GNU Radio - + GNU Radio is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. - + GNU Radio is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with GNU Radio; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, @@ -38,6 +38,7 @@ <block>qtgui_waterfall_sink_x</block> <block>qtgui_time_raster_sink_x</block> <block>qtgui_histogram_sink_x</block> + <block>qtgui_number_sink</block> <block>qtgui_sink_x</block> </cat> </cat> diff --git a/gr-qtgui/grc/qtgui_number_sink.xml b/gr-qtgui/grc/qtgui_number_sink.xml new file mode 100644 index 0000000000..4471d708b9 --- /dev/null +++ b/gr-qtgui/grc/qtgui_number_sink.xml @@ -0,0 +1,118 @@ +<?xml version="1.0"?> +<!-- +################################################### +##QT GUI Number Sink +################################################### + --> +<block> + <name>QT GUI Number Sink</name> + <key>qtgui_number_sink</key> + <import>from PyQt4 import Qt</import> + <import>from gnuradio import qtgui</import> + <import>import sip</import> + <make>#set $win = 'self._%s_win'%$id +qtgui.number_sink( + $type.size, + $name, + $avg, + $graph_type, + $nconnections +) +self.$(id).set_update_time($update_time) +self._$(id)_win = sip.wrapinstance(self.$(id).pyqwidget(), Qt.QWidget) +$(gui_hint()($win))</make> + <callback>set_update_time($update_time)</callback> + + <param> + <name>Input Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + + <param> + <name>Name</name> + <key>name</key> + <value>QT GUI Plot</value> + <type>string</type> + </param> + + <param> + <name>Average</name> + <key>avg</key> + <value>0</value> + <type>float</type> + </param> + + <param> + <name>Graph Type</name> + <key>graph_type</key> + <type>enum</type> + <option> + <name>Horizontal</name> + <key>qtgui.NUM_GRAPH_HORIZ</key> + </option> + <option> + <name>Verticle</name> + <key>qtgui.NUM_GRAPH_VERT</key> + </option> + <option> + <name>None</name> + <key>qtgui.NUM_GRAPH_NONE</key> + </option> + </param> + + <param> + <name>Number of Inputs</name> + <key>nconnections</key> + <value>1</value> + <type>int</type> + <hide>part</hide> + </param> + + <param> + <name>Update Period</name> + <key>update_time</key> + <value>0.10</value> + <type>float</type> + <hide>part</hide> + </param> + + <param> + <name>GUI Hint</name> + <key>gui_hint</key> + <value></value> + <type>gui_hint</type> + <hide>part</hide> + </param> + + <sink> + <name>in</name> + <type>$type</type> + <nports>$nconnections</nports> + </sink> + <doc> + The GUI hint can be used to position the widget within the application. \ + The hint is of the form [tab_id@tab_index]: [row, col, row_span, col_span]. \ + Both the tab specification and the grid position are optional. + </doc> +</block> diff --git a/gr-qtgui/include/gnuradio/qtgui/CMakeLists.txt b/gr-qtgui/include/gnuradio/qtgui/CMakeLists.txt index 3c6309d9c3..bb0d3cf953 100644 --- a/gr-qtgui/include/gnuradio/qtgui/CMakeLists.txt +++ b/gr-qtgui/include/gnuradio/qtgui/CMakeLists.txt @@ -36,6 +36,9 @@ install(FILES histogram_sink_f.h histogramdisplayform.h HistogramDisplayPlot.h + number_sink.h + numberdisplayform.h + NumberDisplayPlot.h plot_raster.h plot_waterfall.h qtgui_types.h diff --git a/gr-qtgui/include/gnuradio/qtgui/DisplayPlot.h b/gr-qtgui/include/gnuradio/qtgui/DisplayPlot.h index 517f69f603..73c744063b 100644 --- a/gr-qtgui/include/gnuradio/qtgui/DisplayPlot.h +++ b/gr-qtgui/include/gnuradio/qtgui/DisplayPlot.h @@ -50,7 +50,8 @@ Q_DECLARE_METATYPE ( QColorList ) * \brief QWidget base plot to build QTGUI plotting tools. * \ingroup qtgui_blk */ -class DisplayPlot:public QwtPlot{ +class DisplayPlot:public QwtPlot +{ Q_OBJECT Q_PROPERTY ( QColor line_color1 READ getLineColor1 WRITE setLineColor1 ) diff --git a/gr-qtgui/include/gnuradio/qtgui/NumberDisplayPlot.h b/gr-qtgui/include/gnuradio/qtgui/NumberDisplayPlot.h new file mode 100644 index 0000000000..307d806b87 --- /dev/null +++ b/gr-qtgui/include/gnuradio/qtgui/NumberDisplayPlot.h @@ -0,0 +1,54 @@ +/* -*- c++ -*- */ +/* + * Copyright 2014 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef NUMBER_DISPLAY_PLOT_H +#define NUMBER_DISPLAY_PLOT_H + +#include <stdint.h> +#include <cstdio> +#include <vector> +#include <gnuradio/qtgui/DisplayPlot.h> +#include <gnuradio/tags.h> +#include <qwt_plot.h> + +/*! + * \brief QWidget for displaying number plots. + * \ingroup qtgui_blk + */ +class NumberDisplayPlot: public DisplayPlot +{ + Q_OBJECT + +public: + NumberDisplayPlot(int nplots, QWidget*); + virtual ~NumberDisplayPlot(); + + void plotNewData(const std::vector<double> samples); + + void replot(); + +public slots: + +private: +}; + +#endif /* NUMBER_DISPLAY_PLOT_H */ diff --git a/gr-qtgui/include/gnuradio/qtgui/form_menus.h b/gr-qtgui/include/gnuradio/qtgui/form_menus.h index e7ebc3a797..cbd01e64be 100644 --- a/gr-qtgui/include/gnuradio/qtgui/form_menus.h +++ b/gr-qtgui/include/gnuradio/qtgui/form_menus.h @@ -32,6 +32,7 @@ #include <gnuradio/filter/firdes.h> #include <gnuradio/qtgui/qtgui_types.h> #include <gnuradio/qtgui/trigger_mode.h> +#include <gnuradio/qtgui/number_sink.h> class LineColorMenu: public QMenu { @@ -81,7 +82,7 @@ public: { return d_act.size(); } - + QAction * getAction(int which) { if(which < d_act.size()) @@ -160,7 +161,7 @@ public: { return d_act.size(); } - + QAction * getAction(int which) { if(which < d_act.size()) @@ -229,7 +230,7 @@ public: { return d_act.size(); } - + QAction * getAction(int which) { if(which < d_act.size()) @@ -312,7 +313,7 @@ public: { return d_act.size(); } - + QAction * getAction(int which) { if(which < d_act.size()) @@ -384,7 +385,7 @@ public: { return d_act.size(); } - + QAction * getAction(int which) { if(which < d_act.size()) @@ -441,7 +442,7 @@ public: ~LineTitleAction() {} - + signals: void whichTrigger(int which, const QString &text); @@ -453,7 +454,7 @@ public slots: private slots: void getText() - { + { emit whichTrigger(d_which, d_text->text()); d_diag->accept(); } @@ -521,7 +522,7 @@ public slots: private slots: void getText() - { + { emit whichTrigger(d_text->text()); d_diag->accept(); } @@ -548,7 +549,7 @@ public: d_text0 = new QLineEdit(); d_text1 = new QLineEdit(); - + QLabel *_label0 = new QLabel(label0); QLabel *_label1 = new QLabel(label1); @@ -584,7 +585,7 @@ public slots: private slots: void getText() - { + { emit whichTrigger(d_text0->text(), d_text1->text()); d_diag->accept(); } @@ -699,7 +700,7 @@ public slots: //void get13() { emit whichTrigger(8192); } //void get14() { emit whichTrigger(16384); } //void get15() { emit whichTrigger(32768); } - void getOther(const QString &str) + void getOther(const QString &str) { int value = str.toInt(); emit whichTrigger(value); @@ -741,7 +742,7 @@ public: } d_act[0]->setChecked(true); - QDoubleValidator *valid = new QDoubleValidator(0.0, 1.0, 2, this); + QDoubleValidator *valid = new QDoubleValidator(0.0, 1.0, 3, this); ((OtherAction*)d_act[d_act.size()-1])->setValidator(valid); connect(d_act[0], SIGNAL(triggered()), this, SLOT(getOff())); @@ -792,6 +793,21 @@ public: return d_act[static_cast<int>(which)]; } + void setHigh(float x) + { + d_high = x; + } + + void setMedium(float x) + { + d_medium = x; + } + + void setLow(float x) + { + d_low = x; + } + signals: void whichTrigger(float alpha); @@ -800,7 +816,7 @@ public: void getHigh() { emit whichTrigger(d_high); } void getMedium() { emit whichTrigger(d_medium); } void getLow() { emit whichTrigger(d_low); } - void getOther(const QString &str) + void getOther(const QString &str) { float value = str.toFloat(); emit whichTrigger(value); @@ -863,7 +879,7 @@ public: { return d_act.size(); } - + QAction * getAction(int which) { if(which < d_act.size()) @@ -958,7 +974,7 @@ public slots: private slots: void getText() - { + { emit whichTrigger(d_text->text().toInt()); d_diag->accept(); } @@ -1088,7 +1104,7 @@ public: { return d_act.size(); } - + QAction * getAction(int which) { if(which < d_act.size()) @@ -1166,7 +1182,7 @@ public: { return d_act.size(); } - + QAction * getAction(int which) { if(which < d_act.size()) @@ -1231,7 +1247,7 @@ public: { return d_act.size(); } - + QAction * getAction(int which) { if(which < d_act.size()) @@ -1261,6 +1277,162 @@ private: /********************************************************************/ +class NumberLayoutMenu: public QMenu +{ + Q_OBJECT + +public: + NumberLayoutMenu(QWidget *parent) + : QMenu("Layout", parent) + { + d_grp = new QActionGroup(this); + d_act.push_back(new QAction("Horizontal", this)); + d_act.push_back(new QAction("Vertical", this)); + d_act.push_back(new QAction("None", this)); + + connect(d_act[0], SIGNAL(triggered()), this, SLOT(getHoriz())); + connect(d_act[1], SIGNAL(triggered()), this, SLOT(getVert())); + connect(d_act[2], SIGNAL(triggered()), this, SLOT(getNone())); + + QListIterator<QAction*> i(d_act); + while(i.hasNext()) { + QAction *a = i.next(); + a->setCheckable(true); + a->setActionGroup(d_grp); + addAction(a); + } + } + + ~NumberLayoutMenu() + {} + + int getNumActions() const + { + return d_act.size(); + } + + QAction * getAction(int which) + { + if(which < d_act.size()) + return d_act[which]; + else + throw std::runtime_error("NumberLayoutMenu::getAction: which out of range.\n"); + } + + QAction * getAction(gr::qtgui::graph_t layout) + { + switch(layout) { + case gr::qtgui::NUM_GRAPH_HORIZ: + return d_act[0]; + break; + case gr::qtgui::NUM_GRAPH_VERT: + return d_act[1]; + break; + case gr::qtgui::NUM_GRAPH_NONE: + return d_act[1]; + break; + default: + throw std::runtime_error("NumberLayoutMenu::getAction: unknown layout type.\n"); + } + } + +signals: + void whichTrigger(gr::qtgui::graph_t layout); + +public slots: + void getHoriz() { emit whichTrigger(gr::qtgui::NUM_GRAPH_HORIZ); } + void getVert() { emit whichTrigger(gr::qtgui::NUM_GRAPH_VERT); } + void getNone() { emit whichTrigger(gr::qtgui::NUM_GRAPH_NONE); } + +private: + QList<QAction *> d_act; + QActionGroup *d_grp; +}; + + +/********************************************************************/ + + +class NumberColorMapMenu: public QMenu +{ + Q_OBJECT + +public: + NumberColorMapMenu(int which, QWidget *parent) + : QMenu("Color Map", parent), d_which(which) + { + d_act.push_back(new QAction("Black", this)); + d_act.push_back(new QAction("Blue-Red", this)); + d_act.push_back(new QAction("White Hot", this)); + d_act.push_back(new QAction("Black Hot", this)); + d_act.push_back(new QAction("Black-Red", this)); + d_act.push_back(new QAction("Other", this)); + + connect(d_act[0], SIGNAL(triggered()), this, SLOT(getBlack())); + connect(d_act[1], SIGNAL(triggered()), this, SLOT(getBlueRed())); + connect(d_act[2], SIGNAL(triggered()), this, SLOT(getWhiteHot())); + connect(d_act[3], SIGNAL(triggered()), this, SLOT(getBlackHot())); + connect(d_act[4], SIGNAL(triggered()), this, SLOT(getBlackRed())); + connect(d_act[5], SIGNAL(triggered()), this, SLOT(getOther())); + + QListIterator<QAction*> i(d_act); + while(i.hasNext()) { + QAction *a = i.next(); + addAction(a); + } + + d_max_value = QColor("black"); + d_min_value = QColor("black"); + } + + ~NumberColorMapMenu() + {} + + int getNumActions() const + { + return d_act.size(); + } + + QAction * getAction(int which) + { + if(which < d_act.size()) + return d_act[which]; + else + throw std::runtime_error("ColorMapMenu::getAction: which out of range.\n"); + } + + signals: + void whichTrigger(int which, + const QColor &min_color, + const QColor &max_color); + + public slots: + void getBlack() { emit whichTrigger(d_which, QColor("black"), QColor("black")); } + void getBlueRed() { emit whichTrigger(d_which, QColor("blue"), QColor("red")); } + void getWhiteHot() { emit whichTrigger(d_which, QColor("black"), QColor("white")); } + void getBlackHot() { emit whichTrigger(d_which, QColor("white"), QColor("black")); } + void getBlackRed() { emit whichTrigger(d_which, QColor("black"), QColor("red")); } + void getOther() + { + QMessageBox::information(this, "Set low and high intensities", + "In the next windows, select the low and then the high intensity colors.", + QMessageBox::Ok); + d_min_value = QColorDialog::getColor(d_min_value, this); + d_max_value = QColorDialog::getColor(d_max_value, this); + + emit whichTrigger(d_which, d_min_value, d_max_value); + } + +private: + QList<QAction *> d_act; + QColor d_max_value, d_min_value; + int d_which; +}; + + +/********************************************************************/ + + class PopupMenu: public QAction { Q_OBJECT @@ -1308,7 +1480,7 @@ public slots: private slots: void getText() - { + { emit whichTrigger(d_text->text()); d_diag->accept(); } diff --git a/gr-qtgui/include/gnuradio/qtgui/number_sink.h b/gr-qtgui/include/gnuradio/qtgui/number_sink.h new file mode 100644 index 0000000000..5532a96c8b --- /dev/null +++ b/gr-qtgui/include/gnuradio/qtgui/number_sink.h @@ -0,0 +1,110 @@ +/* -*- c++ -*- */ +/* + * Copyright 2014 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_QTGUI_NUMBER_SINK_H +#define INCLUDED_QTGUI_NUMBER_SINK_H + +#ifdef ENABLE_PYTHON +#include <Python.h> +#endif + +#include <gnuradio/qtgui/api.h> +#include <gnuradio/qtgui/trigger_mode.h> +#include <gnuradio/sync_block.h> +#include <qapplication.h> + +namespace gr { + namespace qtgui { + + enum graph_t { + NUM_GRAPH_NONE = 0, + NUM_GRAPH_HORIZ, + NUM_GRAPH_VERT, + }; + + + /*! + * \brief A graphical sink to display numerical values of input streams. + * \ingroup instrumentation_blk + * \ingroup qtgui_blk + * + * \details + * Number sink + */ + class QTGUI_API number_sink : virtual public sync_block + { + public: + + // gr::qtgui::number_sink::sptr + typedef boost::shared_ptr<number_sink> sptr; + + /*! + * \brief Build a number sink + * + * \param itemsize Size of input item stream + * \param name title for the plot + * \param average Averaging coefficient (0 - 1) + * \param graph_type Type of graph to use (number_sink::graph_t) + * \param nconnections number of signals connected to sink + * \param parent a QWidget parent object, if any + */ + static sptr make(size_t itemsize, + const std::string &name, + float average=0, + graph_t graph_type=NUM_GRAPH_HORIZ, + int nconnections=1, + QWidget *parent=NULL); + + virtual void exec_() = 0; + +#ifdef ENABLE_PYTHON + virtual PyObject* pyqwidget() = 0; +#endif + + virtual void set_update_time(double t) = 0; + virtual void set_title(const std::string &title) = 0; + virtual void set_average(const float avg) = 0; + virtual void set_graph_type(const graph_t type) = 0; + virtual void set_color(int which, + const std::string &min, + const std::string &max) = 0; + virtual void set_color(int which, int min, int max) = 0; + virtual void set_label(int which, const std::string &label) = 0; + + virtual std::string title() = 0; + virtual float average() const = 0; + virtual graph_t graph_type() const = 0; + virtual std::string color_min() const = 0; + virtual std::string color_max() const = 0; + virtual std::string label(int which) const = 0; + + virtual void enable_menu(bool en=true) = 0; + + virtual void reset() = 0; + + QApplication *d_qApplication; + }; + + } /* namespace qtgui */ +} /* namespace gr */ + +#endif /* INCLUDED_QTGUI_NUMBER_SINK_H */ diff --git a/gr-qtgui/include/gnuradio/qtgui/numberdisplayform.h b/gr-qtgui/include/gnuradio/qtgui/numberdisplayform.h new file mode 100644 index 0000000000..0bdda95b97 --- /dev/null +++ b/gr-qtgui/include/gnuradio/qtgui/numberdisplayform.h @@ -0,0 +1,101 @@ +/* -*- c++ -*- */ +/* + * Copyright 2014 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef NUMBER_DISPLAY_FORM_H +#define NUMBER_DISPLAY_FORM_H + +#include <gnuradio/qtgui/spectrumUpdateEvents.h> +#include <gnuradio/qtgui/number_sink.h> +#include <gnuradio/qtgui/form_menus.h> +#include <QtGui/QtGui> +#include <qwt_thermo.h> +#include <vector> + +/*! + * \brief DisplayForm child for managing number sink plots. + * \ingroup qtgui_blk + */ +class NumberDisplayForm : public QWidget +{ + Q_OBJECT + + public: + NumberDisplayForm(int nplots=1, + gr::qtgui::graph_t type=gr::qtgui::NUM_GRAPH_HORIZ, + QWidget* parent = 0); + ~NumberDisplayForm(); + + gr::qtgui::graph_t graphType() const; + QColor colorMin() const; + QColor colorMax() const; + std::string label(int which) const; + float average() const; + float updateTime() const; + +public slots: + void mousePressEvent(QMouseEvent * e); + void customEvent(QEvent * e); + void setStop(bool on); + void setStop(); + void setGraphType(const gr::qtgui::graph_t type); + void setColor(int which, const QColor &min, const QColor &max); + void setColorMin(int which, QString min); + void setColorMax(int which, QString max); + void setLabel(int which, const std::string &label); + void setLabel(int which, QString label); + void setAverage(const float avg); + void setUpdateTime(const float time); + void setUpdateTime(QString time); + void saveFigure(); + void autoScale(bool on); + +private slots: + void newData(const QEvent*); + +private: + int d_nplots; + QGridLayout *d_layout; + std::vector<QLabel*> d_label; + std::vector<QLabel*> d_text_box; + std::vector<QwtThermo*> d_indicator; + gr::qtgui::graph_t d_graph_type; + float d_avg, d_update_time; + std::vector<float> d_max, d_min; + + bool d_menu_on; + bool d_stop_state; + bool d_autoscale_state; + + QMenu *d_menu; + QAction *d_stop_act; + QList<QMenu*> d_label_menu; + std::vector<LineTitleAction*> d_label_act; + FFTAverageMenu *d_avg_menu; + NumberLayoutMenu *d_layout_menu; + std::vector<NumberColorMapMenu*> d_color_menu; + PopupMenu *d_maxcolor_menu; + QAction *d_autoscale_act; + PopupMenu *d_update_time_menu; + QAction *d_save_act; +}; + +#endif /* NUMBER_DISPLAY_FORM_H */ diff --git a/gr-qtgui/include/gnuradio/qtgui/spectrumUpdateEvents.h b/gr-qtgui/include/gnuradio/qtgui/spectrumUpdateEvents.h index dc31ba8601..d26f41e26d 100644 --- a/gr-qtgui/include/gnuradio/qtgui/spectrumUpdateEvents.h +++ b/gr-qtgui/include/gnuradio/qtgui/spectrumUpdateEvents.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2008-2013 Free Software Foundation, Inc. + * Copyright 2008-2014 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -295,4 +295,28 @@ private: }; +/********************************************************************/ + + +class NumberUpdateEvent: public QEvent +{ +public: + NumberUpdateEvent(const std::vector<float> samples); + ~NumberUpdateEvent(); + + int which() const; + const std::vector<float> getSamples() const; + + static QEvent::Type Type() + { return QEvent::Type(SpectrumUpdateEventType); } + +protected: + +private: + size_t _nplots; + std::vector<float> _samples; +}; + + + #endif /* SPECTRUM_UPDATE_EVENTS_H */ diff --git a/gr-qtgui/lib/CMakeLists.txt b/gr-qtgui/lib/CMakeLists.txt index afaadb929b..f46fe838a3 100644 --- a/gr-qtgui/lib/CMakeLists.txt +++ b/gr-qtgui/lib/CMakeLists.txt @@ -30,6 +30,7 @@ set(qtgui_moc_hdrs ${qtgui_mod_includedir}/constellationdisplayform.h ${qtgui_mod_includedir}/waterfalldisplayform.h ${qtgui_mod_includedir}/histogramdisplayform.h + ${qtgui_mod_includedir}/numberdisplayform.h ${qtgui_mod_includedir}/form_menus.h ${qtgui_mod_includedir}/DisplayPlot.h ${qtgui_mod_includedir}/FrequencyDisplayPlot.h @@ -38,6 +39,7 @@ set(qtgui_moc_hdrs ${qtgui_mod_includedir}/WaterfallDisplayPlot.h ${qtgui_mod_includedir}/ConstellationDisplayPlot.h ${qtgui_mod_includedir}/HistogramDisplayPlot.h + ${qtgui_mod_includedir}/NumberDisplayPlot.h ) QT4_WRAP_CPP(qtgui_moc_srcs ${qtgui_moc_hdrs}) QT4_WRAP_UI(qtgui_ui_hdrs spectrumdisplayform.ui) @@ -68,6 +70,8 @@ set(qtgui_srcs freqdisplayform.cc constellationdisplayform.cc histogramdisplayform.cc + NumberDisplayPlot.cc + numberdisplayform.cc waterfalldisplayform.cc SpectrumGUIClass.cc spectrumUpdateEvents.cc @@ -85,6 +89,7 @@ set(qtgui_srcs waterfall_sink_c_impl.cc waterfall_sink_f_impl.cc histogram_sink_f_impl.cc + number_sink_impl.cc qtgui_util.cc ) diff --git a/gr-qtgui/lib/NumberDisplayPlot.cc b/gr-qtgui/lib/NumberDisplayPlot.cc new file mode 100644 index 0000000000..b1fbca9ded --- /dev/null +++ b/gr-qtgui/lib/NumberDisplayPlot.cc @@ -0,0 +1,63 @@ +/* -*- c++ -*- */ +/* + * Copyright 2014 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef NUMBER_DISPLAY_PLOT_C +#define NUMBER_DISPLAY_PLOT_C + +#include <gnuradio/qtgui/NumberDisplayPlot.h> + +#include <qwt_scale_draw.h> +#include <QColor> +#include <cmath> +#include <iostream> +#include <volk/volk.h> + +NumberDisplayPlot::NumberDisplayPlot(int nplots, QWidget* parent) + : DisplayPlot(nplots, parent) +{ + resize(0, 0); + + // Setup dataPoints and plot vectors + // Automatically deleted when parent is deleted + for(int i = 0; i < d_nplots; i++) { + + } +} + +NumberDisplayPlot::~NumberDisplayPlot() +{ +} + +void +NumberDisplayPlot::replot() +{ + QwtPlot::replot(); +} + +void +NumberDisplayPlot::plotNewData(const std::vector<double> samples) +{ + if(!d_stop) { + } +} + +#endif /* NUMBER_DISPLAY_PLOT_C */ diff --git a/gr-qtgui/lib/number_sink_impl.cc b/gr-qtgui/lib/number_sink_impl.cc new file mode 100644 index 0000000000..faf7ad4a15 --- /dev/null +++ b/gr-qtgui/lib/number_sink_impl.cc @@ -0,0 +1,290 @@ +/* -*- c++ -*- */ +/* + * Copyright 2014 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "number_sink_impl.h" +#include <gnuradio/io_signature.h> +#include <string.h> +#include <volk/volk.h> +#include <gnuradio/fft/fft.h> +#include <qwt_symbol.h> + +namespace gr { + namespace qtgui { + + number_sink::sptr + number_sink::make(size_t itemsize, + const std::string &name, + float average, + graph_t graph_type, + int nconnections, + QWidget *parent) + { + return gnuradio::get_initial_sptr + (new number_sink_impl(itemsize, name, average, + graph_type, nconnections, parent)); + } + + number_sink_impl::number_sink_impl(size_t itemsize, + const std::string &name, + float average, + graph_t graph_type, + int nconnections, + QWidget *parent) + : sync_block("number_sink", + io_signature::make(nconnections, nconnections, itemsize), + io_signature::make(0, 0, 0)), + d_itemsize(itemsize), d_name(name), d_average(average), + d_type(graph_type), d_nconnections(nconnections), d_parent(parent), + d_avg_value(nconnections), d_iir(nconnections) + { + for(int n = 0; n < d_nconnections; n++) { + d_avg_value[n] = 0; + d_iir[n].set_taps(d_average); + } + + // Required now for Qt; argc must be greater than 0 and argv + // must have at least one valid character. Must be valid through + // life of the qApplication: + // http://harmattan-dev.nokia.com/docs/library/html/qt4/qapplication.html + d_argc = 1; + d_argv = new char; + d_argv[0] = '\0'; + + d_main_gui = NULL; + + // Set alignment properties for VOLK + const int alignment_multiple = + volk_get_alignment() / d_itemsize; + set_alignment(std::max(1,alignment_multiple)); + + initialize(); + } + + number_sink_impl::~number_sink_impl() + { + //if(!d_main_gui->isClosed()) + // d_main_gui->close(); + + delete d_argv; + } + + bool + number_sink_impl::check_topology(int ninputs, int noutputs) + { + return ninputs == d_nconnections; + } + + void + number_sink_impl::initialize() + { + if(qApp != NULL) { + d_qApplication = qApp; + } + else { + d_qApplication = new QApplication(d_argc, &d_argv); + } + + d_main_gui = new NumberDisplayForm(d_nconnections, d_type, d_parent); + + // initialize update time to 10 times a second + set_update_time(0.1); + } + + void + number_sink_impl::exec_() + { + d_qApplication->exec(); + } + + QWidget* + number_sink_impl::qwidget() + { + return d_main_gui; + } + +#ifdef ENABLE_PYTHON + PyObject* + number_sink_impl::pyqwidget() + { + PyObject *w = PyLong_FromVoidPtr((void*)d_main_gui); + PyObject *retarg = Py_BuildValue("N", w); + return retarg; + } +#endif + + void + number_sink_impl::set_update_time(double t) + { + //convert update time to ticks + gr::high_res_timer_type tps = gr::high_res_timer_tps(); + d_main_gui->setUpdateTime(t); + d_update_time = t * tps; + d_last_time = 0; + } + + void + number_sink_impl::set_title(const std::string &title) + { + //d_main_gui->setTitle(title.c_str()); + } + + void + number_sink_impl::set_average(const float avg) + { + d_average = avg; + for(int n = 0; n < d_nconnections; n++) { + d_avg_value[n] = 0; + d_iir[n].set_taps(d_average); + } + } + + void + number_sink_impl::set_graph_type(const graph_t type) + { + d_main_gui->setGraphType(type); + } + + void + number_sink_impl::set_color(int which, + const std::string &min, + const std::string &max) + { + d_main_gui->setColor(which, + QColor(min.c_str()), + QColor(max.c_str())); + } + + void + number_sink_impl::set_color(int which, int min, int max) + { + d_main_gui->setColor(which, QColor(min), QColor(max)); + } + + void + number_sink_impl::set_label(int which, const std::string &label) + { + d_main_gui->setLabel(which, label); + } + + std::string + number_sink_impl::title() + { + //return d_main_gui->title().toStdString(); + return ""; + } + + float + number_sink_impl::average() const + { + return d_average; + } + + graph_t + number_sink_impl::graph_type() const + { + return d_main_gui->graphType(); + } + + std::string + number_sink_impl::color_min() const + { + //return d_main_gui->colorMin(); + return "min color"; + } + + std::string + number_sink_impl::color_max() const + { + return d_main_gui->colorMax().name().toStdString(); + } + + std::string + number_sink_impl::label(int which) const + { + return d_main_gui->label(which); + } + + void + number_sink_impl::enable_menu(bool en) + { + //d_main_gui->enableMenu(en); + } + + void + number_sink_impl::reset() + { + gr::thread::scoped_lock lock(d_mutex); + _reset(); + } + + void + number_sink_impl::_reset() + { + } + + int + number_sink_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + gr::thread::scoped_lock lock(d_mutex); + + float new_avg = d_main_gui->average(); + set_update_time(d_main_gui->updateTime()); + if(new_avg != d_average) { + set_average(new_avg); + } + + if(d_average > 0) { + for(int n = 0; n < d_nconnections; n++) { + float *in = (float*)input_items[n]; + for(int i = 0; i < noutput_items; i++) { + d_avg_value[n] = d_iir[n].filter(in[i]); + } + } + } + + // Plot if we are able to update + if(gr::high_res_timer_now() - d_last_time > d_update_time) { + d_last_time = gr::high_res_timer_now(); + std::vector<float> d(d_nconnections); + if(d_average > 0) { + for(int n = 0; n < d_nconnections; n++) + d[n] = d_avg_value[n]; + } + else { + for(int n = 0; n < d_nconnections; n++) + d[n] = ((float*)input_items[n])[0]; + } + d_qApplication->postEvent(d_main_gui, + new NumberUpdateEvent(d)); + } + + return noutput_items;; + } + + } /* namespace qtgui */ +} /* namespace gr */ diff --git a/gr-qtgui/lib/number_sink_impl.h b/gr-qtgui/lib/number_sink_impl.h new file mode 100644 index 0000000000..c453923a17 --- /dev/null +++ b/gr-qtgui/lib/number_sink_impl.h @@ -0,0 +1,114 @@ +/* -*- c++ -*- */ +/* + * Copyright 2014 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_QTGUI_NUMBER_SINK_IMPL_H +#define INCLUDED_QTGUI_NUMBER_SINK_IMPL_H + +#include <gnuradio/qtgui/number_sink.h> +#include <gnuradio/qtgui/numberdisplayform.h> +#include <gnuradio/filter/single_pole_iir.h> +#include <gnuradio/thread/thread.h> +#include <gnuradio/high_res_timer.h> + +namespace gr { + namespace qtgui { + + class QTGUI_API number_sink_impl : public number_sink + { + private: + void initialize(); + + gr::thread::mutex d_mutex; + + size_t d_itemsize; + std::string d_name; + float d_average; + graph_t d_type; + int d_nconnections; + + int d_index, d_start, d_end; + std::vector<double*> d_buffers; + std::vector< std::vector<gr::tag_t> > d_tags; + + int d_argc; + char *d_argv; + QWidget *d_parent; + NumberDisplayForm *d_main_gui; + + std::vector<float> d_avg_value; + std::vector<filter::single_pole_iir<float,float,float> > d_iir; + + gr::high_res_timer_type d_update_time; + gr::high_res_timer_type d_last_time; + + void _reset(); + void _npoints_resize(); + void _gui_update_trigger(); + + public: + number_sink_impl(size_t itemsize, + const std::string &name, + float average=0, + graph_t graph_type=NUM_GRAPH_HORIZ, + int nconnections=1, + QWidget *parent=NULL); + ~number_sink_impl(); + + bool check_topology(int ninputs, int noutputs); + + void exec_(); + QWidget* qwidget(); + +#ifdef ENABLE_PYTHON + PyObject* pyqwidget(); +#endif + + void set_update_time(double t); + void set_title(const std::string &title); + void set_average(const float avg); + void set_graph_type(const graph_t type); + void set_color(int which, + const std::string &min, + const std::string &max); + void set_color(int which, int min, int max); + void set_label(int which, const std::string &label); + + std::string title(); + float average() const; + graph_t graph_type() const; + std::string color_min() const; + std::string color_max() const; + std::string label(int which) const; + + void enable_menu(bool en); + + void reset(); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace qtgui */ +} /* namespace gr */ + +#endif /* INCLUDED_QTGUI_NUMBER_SINK_IMPL_H */ diff --git a/gr-qtgui/lib/numberdisplayform.cc b/gr-qtgui/lib/numberdisplayform.cc new file mode 100644 index 0000000000..d22acd0e60 --- /dev/null +++ b/gr-qtgui/lib/numberdisplayform.cc @@ -0,0 +1,375 @@ +/* -*- c++ -*- */ +/* + * Copyright 2014 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include <cmath> +#include <QMessageBox> +#include <gnuradio/qtgui/numberdisplayform.h> +#include <iostream> +#include <qwt_color_map.h> + +NumberDisplayForm::NumberDisplayForm(int nplots, gr::qtgui::graph_t type, + QWidget* parent) + : QWidget(parent) +{ + d_nplots = nplots; + d_layout = new QGridLayout(this); + for(int i = 0; i < d_nplots; i++) { + d_min.push_back(+1e32); + d_max.push_back(-1e32); + d_label.push_back(new QLabel(QString("Data %1").arg(i))); + d_text_box.push_back(new QLabel(QString("0"))); + + d_indicator.push_back(new QwtThermo()); + d_indicator[i]->setScale(-1, 1); + d_indicator[i]->setOriginMode(QwtThermo::OriginCustom); + d_indicator[i]->setOrigin(0.0); + + switch(type) { + case(gr::qtgui::NUM_GRAPH_HORIZ): + d_indicator[i]->setOrientation(Qt::Horizontal); + d_layout->addWidget(d_label[i], 2*i, 0); + d_layout->addWidget(d_text_box[i], 2*i, 1); + d_layout->addWidget(d_indicator[i], 2*i+1, 1); + break; + case(gr::qtgui::NUM_GRAPH_VERT): + d_indicator[i]->setOrientation(Qt::Vertical); + d_layout->addWidget(d_label[i], 0, i); + d_layout->addWidget(d_text_box[i], 1, i); + d_layout->addWidget(d_indicator[i], 2, i); + break; + case(gr::qtgui::NUM_GRAPH_NONE): + default: + d_layout->addWidget(d_label[i], 0, i); + d_layout->addWidget(d_text_box[i], 1, i); + } + + setColor(i, QColor("black"), QColor("black")); + } + + d_avg = 0.0; + d_update_time = 0.1; + + d_menu_on = true; + d_menu = new QMenu(this); + + // Create a set of actions for the menu + d_stop_act = new QAction("Stop", this); + d_stop_act->setStatusTip(tr("Start/Stop")); + connect(d_stop_act, SIGNAL(triggered()), this, SLOT(setStop())); + d_stop_state = false; + d_menu->addAction(d_stop_act); + + // Menu items for each number line + for(int i = 0; i < d_nplots; i++) { + d_label_act.push_back(new LineTitleAction(i, this)); + connect(d_label_act[i], SIGNAL(whichTrigger(int, const QString&)), + this, SLOT(setLabel(int, const QString&))); + + d_label_menu.push_back(new QMenu(tr(""), this)); + d_label_menu[i]->addAction(d_label_act[i]); + + d_color_menu.push_back(new NumberColorMapMenu(i, this)); + connect(d_color_menu[i], SIGNAL(whichTrigger(int, const QColor&, const QColor&)), + this, SLOT(setColor(int, const QColor&, const QColor&))); + d_label_menu[i]->addMenu(d_color_menu[i]); + + d_menu->addMenu(d_label_menu[i]); + } + + d_avg_menu = new FFTAverageMenu(this); + d_avg_menu->setTitle("Average"); + d_avg_menu->setHigh(0.001); + d_avg_menu->setMedium(0.01); + d_avg_menu->setLow(0.1); + connect(d_avg_menu, SIGNAL(whichTrigger(float)), + this, SLOT(setAverage(const float))); + d_menu->addMenu(d_avg_menu); + + d_layout_menu = new NumberLayoutMenu(this); + connect(d_layout_menu, SIGNAL(whichTrigger(gr::qtgui::graph_t)), + this, SLOT(setGraphType(const gr::qtgui::graph_t))); + d_menu->addMenu(d_layout_menu); + + d_autoscale_act = new QAction("Auto Scale", this); + d_autoscale_act->setCheckable(true); + connect(d_autoscale_act, SIGNAL(triggered(bool)), + this, SLOT(autoScale(bool))); + d_autoscale_state = false; + d_menu->addAction(d_autoscale_act); + + d_update_time_menu = new PopupMenu("Update Time", this); + connect(d_update_time_menu, SIGNAL(whichTrigger(QString)), + this, SLOT(setUpdateTime(QString))); + d_menu->addAction(d_update_time_menu); + + d_save_act = new QAction("Save", this); + d_save_act->setStatusTip(tr("Save Figure")); + connect(d_save_act, SIGNAL(triggered()), this, SLOT(saveFigure())); + d_menu->addAction(d_save_act); + + setLayout(d_layout); +} + +NumberDisplayForm::~NumberDisplayForm() +{ + // Qt deletes children when parent is deleted +} + +void +NumberDisplayForm::mousePressEvent(QMouseEvent * e) +{ + bool ctrloff = Qt::ControlModifier != QApplication::keyboardModifiers(); + if((e->button() == Qt::MidButton) && ctrloff && (d_menu_on)) { + if(d_stop_state == false) + d_stop_act->setText(tr("Stop")); + else + d_stop_act->setText(tr("Start")); + + // Update the line titles if changed externally + for(int i = 0; i < d_nplots; i++) { + d_label_menu[i]->setTitle(label(i).c_str()); + } + d_menu->exec(e->globalPos()); + } +} + +void +NumberDisplayForm::setStop(bool on) +{ + if(!on) { + d_stop_state = false; + } + else { + d_stop_state = true; + } +} + +void +NumberDisplayForm::setStop() +{ + if(d_stop_state == false) + setStop(true); + else + setStop(false); +} + +void +NumberDisplayForm::saveFigure() +{ + QPixmap qpix = QPixmap::grabWidget(this); + + QString types = QString(tr("JPEG file (*.jpg);;Portable Network Graphics file (*.png);;Bitmap file (*.bmp);;TIFF file (*.tiff)")); + + QString filename, filetype; + QFileDialog *filebox = new QFileDialog(0, "Save Image", "./", types); + filebox->setViewMode(QFileDialog::Detail); + if(filebox->exec()) { + filename = filebox->selectedFiles()[0]; + filetype = filebox->selectedNameFilter(); + } + else { + return; + } + + if(filetype.contains(".jpg")) { + qpix.save(filename, "JPEG"); + } + else if(filetype.contains(".png")) { + qpix.save(filename, "PNG"); + } + else if(filetype.contains(".bmp")) { + qpix.save(filename, "BMP"); + } + else if(filetype.contains(".tiff")) { + qpix.save(filename, "TIFF"); + } + else { + qpix.save(filename, "JPEG"); + } + + delete filebox; +} + +void +NumberDisplayForm::newData(const QEvent* updateEvent) +{ + if(!d_stop_state) { + NumberUpdateEvent *tevent = (NumberUpdateEvent*)updateEvent; + const std::vector<float> samples = tevent->getSamples(); + + for(int i = 0; i < d_nplots; i++) { + d_text_box[i]->setText(QString("%1").arg(samples[i], 4, ' ')); + d_indicator[i]->setValue(samples[i]); + d_min[i] = std::min(d_min[i], samples[i]); + d_max[i] = std::max(d_max[i], samples[i]); + + if(d_autoscale_state) { + //d_indicator[i]->setRange(d_min[i], d_max[i], false); + d_indicator[i]->setScale(d_min[i], d_max[i]); + } + } + + } +} + +void +NumberDisplayForm::customEvent(QEvent * e) +{ + if(e->type() == NumberUpdateEvent::Type()) { + newData(e); + } +} + +void +NumberDisplayForm::setGraphType(const gr::qtgui::graph_t type) +{ + d_graph_type = type; + for(int i = 0; i < d_nplots; i++) { + d_layout->removeWidget(d_indicator[i]); + d_layout->removeWidget(d_label[i]); + d_layout->removeWidget(d_text_box[i]); + + switch(d_graph_type) { + case(gr::qtgui::NUM_GRAPH_HORIZ): + d_indicator[i]->setOrientation(Qt::Horizontal); + d_indicator[i]->setVisible(true); + d_layout->addWidget(d_label[i], 2*i, 0); + d_layout->addWidget(d_text_box[i], 2*i, 1); + d_layout->addWidget(d_indicator[i], 2*i+1, 1); + break; + case(gr::qtgui::NUM_GRAPH_VERT): + d_indicator[i]->setOrientation(Qt::Vertical); + d_indicator[i]->setVisible(true); + d_layout->addWidget(d_label[i], 0, i); + d_layout->addWidget(d_text_box[i], 1, i); + d_layout->addWidget(d_indicator[i], 2, i); + break; + case(gr::qtgui::NUM_GRAPH_NONE): + default: + d_indicator[i]->setVisible(false); + d_layout->addWidget(d_label[i], 0, i); + d_layout->addWidget(d_text_box[i], 1, i); + break; + } + } + +} + +void +NumberDisplayForm::setColor(int which, const QColor &min, const QColor &max) +{ + QwtLinearColorMap *map = new QwtLinearColorMap(); + map->setColorInterval(min, max); + d_indicator[which]->setColorMap(map); +} + +void +NumberDisplayForm::setColorMin(int which, QString min) +{ + setColor(which, QColor(min), colorMax()); +} + +void +NumberDisplayForm::setColorMax(int which, QString max) +{ + setColor(which, colorMin(), QColor(max)); +} + +void +NumberDisplayForm::setLabel(int which, const std::string &label) +{ + d_label[which]->setText(label.c_str()); +} + +void +NumberDisplayForm::setLabel(int which, QString label) +{ + d_label[which]->setText(label); +} + +void +NumberDisplayForm::setAverage(const float avg) +{ + d_avg = avg; +} + +void +NumberDisplayForm::setUpdateTime(const float time) +{ + d_update_time = time; +} + +void +NumberDisplayForm::setUpdateTime(QString time) +{ + setUpdateTime(time.toFloat()); +} + +gr::qtgui::graph_t +NumberDisplayForm::graphType() const +{ + return d_graph_type; +} + +QColor +NumberDisplayForm::colorMin() const +{ + QwtLinearColorMap *map = static_cast<QwtLinearColorMap*>(d_indicator[0]->colorMap()); + return map->color1(); +} + +QColor +NumberDisplayForm::colorMax() const +{ + QwtLinearColorMap *map = static_cast<QwtLinearColorMap*>(d_indicator[0]->colorMap()); + return map->color2(); +} + +std::string +NumberDisplayForm::label(int which) const +{ + return d_label[which]->text().toStdString(); +} + +float +NumberDisplayForm::average() const +{ + return d_avg; +} + +float +NumberDisplayForm::updateTime() const +{ + return d_update_time; +} + +void +NumberDisplayForm::autoScale(bool on) +{ + d_autoscale_state = on; + + // Reset the autoscale limits + for(int i = 0; i < d_nplots; i++) { + d_min.push_back(+1e32); + d_max.push_back(-1e32); + } +} diff --git a/gr-qtgui/lib/spectrumUpdateEvents.cc b/gr-qtgui/lib/spectrumUpdateEvents.cc index 8c822efb4f..f48e079861 100644 --- a/gr-qtgui/lib/spectrumUpdateEvents.cc +++ b/gr-qtgui/lib/spectrumUpdateEvents.cc @@ -490,4 +490,26 @@ HistogramUpdateEvent::getNumDataPoints() const } + +/***************************************************************************/ + + +NumberUpdateEvent::NumberUpdateEvent(const std::vector<float> samples) + : QEvent(QEvent::Type(SpectrumUpdateEventType)) +{ + _samples = samples; + _nplots = samples.size(); +} + +NumberUpdateEvent::~NumberUpdateEvent() +{ +} + +const std::vector<float> +NumberUpdateEvent::getSamples() const +{ + return _samples; +} + + #endif /* SPECTRUM_UPDATE_EVENTS_C */ diff --git a/gr-qtgui/swig/qtgui_swig.i b/gr-qtgui/swig/qtgui_swig.i index 234a8791b5..a6e64b060d 100644 --- a/gr-qtgui/swig/qtgui_swig.i +++ b/gr-qtgui/swig/qtgui_swig.i @@ -49,6 +49,7 @@ #include "gnuradio/qtgui/waterfall_sink_c.h" #include "gnuradio/qtgui/waterfall_sink_f.h" #include "gnuradio/qtgui/histogram_sink_f.h" +#include "gnuradio/qtgui/number_sink.h" %} %include "gnuradio/qtgui/sink_c.h" @@ -63,6 +64,7 @@ %include "gnuradio/qtgui/waterfall_sink_c.h" %include "gnuradio/qtgui/waterfall_sink_f.h" %include "gnuradio/qtgui/histogram_sink_f.h" +%include "gnuradio/qtgui/number_sink.h" GR_SWIG_BLOCK_MAGIC2(qtgui, sink_c); GR_SWIG_BLOCK_MAGIC2(qtgui, sink_f); @@ -76,3 +78,4 @@ GR_SWIG_BLOCK_MAGIC2(qtgui, const_sink_c); GR_SWIG_BLOCK_MAGIC2(qtgui, waterfall_sink_c); GR_SWIG_BLOCK_MAGIC2(qtgui, waterfall_sink_f); GR_SWIG_BLOCK_MAGIC2(qtgui, histogram_sink_f); +GR_SWIG_BLOCK_MAGIC2(qtgui, number_sink); |