diff options
author | Tom Rondeau | 2011-06-05 15:36:47 -0400 |
---|---|---|
committer | Tom Rondeau | 2011-06-05 15:36:47 -0400 |
commit | 233f960474f86bc8cc519ce7257b29d8615c4000 (patch) | |
tree | 1a4c846119a01a5a195a9e9ee5b854384b0b6535 /gr-qtgui | |
parent | 024c79a7fb13c08bae7b97079a245f711ecf12a7 (diff) | |
parent | a23a0a46c3bf446cbe09d71bc8e10b061256ef56 (diff) | |
download | gnuradio-233f960474f86bc8cc519ce7257b29d8615c4000.tar.gz gnuradio-233f960474f86bc8cc519ce7257b29d8615c4000.tar.bz2 gnuradio-233f960474f86bc8cc519ce7257b29d8615c4000.zip |
Merge branch 'master' into turbo
Diffstat (limited to 'gr-qtgui')
-rw-r--r-- | gr-qtgui/Makefile.am | 12 | ||||
-rw-r--r-- | gr-qtgui/apps/.gitignore | 3 | ||||
-rw-r--r-- | gr-qtgui/apps/Makefile.am | 46 | ||||
-rw-r--r-- | gr-qtgui/apps/grc_qt_example.grc | 441 | ||||
-rwxr-xr-x | gr-qtgui/apps/pyqt_example_c.py (renamed from gr-qtgui/src/python/pyqt_example.py) | 14 | ||||
-rwxr-xr-x | gr-qtgui/apps/pyqt_example_f.py (renamed from gr-qtgui/src/python/pyqt_example_f.py) | 23 | ||||
-rwxr-xr-x | gr-qtgui/apps/pyqt_time_c.py | 163 | ||||
-rwxr-xr-x | gr-qtgui/apps/pyqt_time_f.py | 163 | ||||
-rwxr-xr-x | gr-qtgui/apps/qt_digital.py (renamed from gr-qtgui/src/python/qt_digital.py) | 7 | ||||
-rw-r--r-- | gr-qtgui/apps/qt_digital_window.py (renamed from gr-qtgui/src/python/qt_digital_window.py) | 0 | ||||
-rw-r--r-- | gr-qtgui/apps/qt_digital_window.ui (renamed from gr-qtgui/src/python/qt_digital_window.ui) | 0 | ||||
-rwxr-xr-x | gr-qtgui/apps/usrp2_display.py (renamed from gr-qtgui/src/python/usrp2_display.py) | 2 | ||||
-rwxr-xr-x | gr-qtgui/apps/usrp_display.py (renamed from gr-qtgui/src/python/usrp_display.py) | 2 | ||||
-rw-r--r-- | gr-qtgui/apps/usrp_display_qtgui.py (renamed from gr-qtgui/src/python/usrp_display_qtgui.py) | 0 | ||||
-rw-r--r-- | gr-qtgui/apps/usrp_display_qtgui.ui (renamed from gr-qtgui/src/python/usrp_display_qtgui.ui) | 0 | ||||
-rw-r--r-- | gr-qtgui/gnuradio-qtgui.pc.in | 11 | ||||
-rw-r--r-- | gr-qtgui/grc/.gitignore (renamed from gr-qtgui/src/.gitignore) | 0 | ||||
-rw-r--r-- | gr-qtgui/grc/Makefile.am | 34 | ||||
-rw-r--r-- | gr-qtgui/grc/qtgui_check_box.xml | 83 | ||||
-rw-r--r-- | gr-qtgui/grc/qtgui_chooser.xml | 251 | ||||
-rw-r--r-- | gr-qtgui/grc/qtgui_entry.xml | 68 | ||||
-rw-r--r-- | gr-qtgui/grc/qtgui_label.xml | 66 | ||||
-rw-r--r-- | gr-qtgui/grc/qtgui_range.xml | 211 | ||||
-rw-r--r-- | gr-qtgui/grc/qtgui_sink_x.xml | 126 | ||||
-rw-r--r-- | gr-qtgui/grc/qtgui_tab_widget.xml | 84 | ||||
-rw-r--r-- | gr-qtgui/grc/qtgui_time_sink_x.xml | 78 | ||||
-rw-r--r-- | gr-qtgui/lib/.gitignore (renamed from gr-qtgui/src/lib/.gitignore) | 4 | ||||
-rw-r--r-- | gr-qtgui/lib/ConstellationDisplayPlot.cc (renamed from gr-qtgui/src/lib/ConstellationDisplayPlot.cc) | 55 | ||||
-rw-r--r-- | gr-qtgui/lib/ConstellationDisplayPlot.h (renamed from gr-qtgui/src/lib/ConstellationDisplayPlot.h) | 31 | ||||
-rw-r--r-- | gr-qtgui/lib/FrequencyDisplayPlot.cc (renamed from gr-qtgui/src/lib/FrequencyDisplayPlot.cc) | 79 | ||||
-rw-r--r-- | gr-qtgui/lib/FrequencyDisplayPlot.h (renamed from gr-qtgui/src/lib/FrequencyDisplayPlot.h) | 39 | ||||
-rw-r--r-- | gr-qtgui/lib/Makefile.am (renamed from gr-qtgui/src/lib/Makefile.am) | 68 | ||||
-rw-r--r-- | gr-qtgui/lib/SpectrumGUIClass.cc (renamed from gr-qtgui/src/lib/SpectrumGUIClass.cc) | 134 | ||||
-rw-r--r-- | gr-qtgui/lib/SpectrumGUIClass.h (renamed from gr-qtgui/src/lib/SpectrumGUIClass.h) | 53 | ||||
-rw-r--r-- | gr-qtgui/lib/TimeDomainDisplayPlot.cc (renamed from gr-qtgui/src/lib/TimeDomainDisplayPlot.cc) | 163 | ||||
-rw-r--r-- | gr-qtgui/lib/TimeDomainDisplayPlot.h | 95 | ||||
-rw-r--r-- | gr-qtgui/lib/WaterfallDisplayPlot.cc (renamed from gr-qtgui/src/lib/WaterfallDisplayPlot.cc) | 86 | ||||
-rw-r--r-- | gr-qtgui/lib/WaterfallDisplayPlot.h (renamed from gr-qtgui/src/lib/WaterfallDisplayPlot.h) | 43 | ||||
-rw-r--r-- | gr-qtgui/lib/gr_qtgui_api.h | 33 | ||||
-rw-r--r-- | gr-qtgui/lib/highResTimeFunctions.h (renamed from gr-qtgui/src/lib/highResTimeFunctions.h) | 0 | ||||
-rw-r--r-- | gr-qtgui/lib/plot_waterfall.cc (renamed from gr-qtgui/src/lib/plot_waterfall.cc) | 0 | ||||
-rw-r--r-- | gr-qtgui/lib/plot_waterfall.h (renamed from gr-qtgui/src/lib/plot_waterfall.h) | 4 | ||||
-rw-r--r-- | gr-qtgui/lib/qtgui_sink_c.cc (renamed from gr-qtgui/src/lib/qtgui_sink_c.cc) | 53 | ||||
-rw-r--r-- | gr-qtgui/lib/qtgui_sink_c.h (renamed from gr-qtgui/src/lib/qtgui_sink_c.h) | 31 | ||||
-rw-r--r-- | gr-qtgui/lib/qtgui_sink_f.cc (renamed from gr-qtgui/src/lib/qtgui_sink_f.cc) | 44 | ||||
-rw-r--r-- | gr-qtgui/lib/qtgui_sink_f.h (renamed from gr-qtgui/src/lib/qtgui_sink_f.h) | 30 | ||||
-rw-r--r-- | gr-qtgui/lib/qtgui_time_sink_c.cc | 199 | ||||
-rw-r--r-- | gr-qtgui/lib/qtgui_time_sink_c.h | 93 | ||||
-rw-r--r-- | gr-qtgui/lib/qtgui_time_sink_f.cc | 197 | ||||
-rw-r--r-- | gr-qtgui/lib/qtgui_time_sink_f.h | 93 | ||||
-rw-r--r-- | gr-qtgui/lib/qtgui_util.cc | 71 | ||||
-rw-r--r-- | gr-qtgui/lib/qtgui_util.h (renamed from gr-qtgui/src/lib/qtgui.h) | 62 | ||||
-rw-r--r-- | gr-qtgui/lib/spectrumUpdateEvents.cc (renamed from gr-qtgui/src/lib/spectrumUpdateEvents.cc) | 43 | ||||
-rw-r--r-- | gr-qtgui/lib/spectrumUpdateEvents.h (renamed from gr-qtgui/src/lib/spectrumUpdateEvents.h) | 24 | ||||
-rw-r--r-- | gr-qtgui/lib/spectrumdisplayform.cc (renamed from gr-qtgui/src/lib/spectrumdisplayform.cc) | 87 | ||||
-rw-r--r-- | gr-qtgui/lib/spectrumdisplayform.h (renamed from gr-qtgui/src/lib/spectrumdisplayform.h) | 35 | ||||
-rw-r--r-- | gr-qtgui/lib/spectrumdisplayform.ui (renamed from gr-qtgui/src/lib/spectrumdisplayform.ui) | 38 | ||||
-rw-r--r-- | gr-qtgui/lib/timedisplayform.cc | 177 | ||||
-rw-r--r-- | gr-qtgui/lib/timedisplayform.h | 85 | ||||
-rw-r--r-- | gr-qtgui/lib/waterfallGlobalData.cc (renamed from gr-qtgui/src/lib/waterfallGlobalData.cc) | 0 | ||||
-rw-r--r-- | gr-qtgui/lib/waterfallGlobalData.h (renamed from gr-qtgui/src/lib/waterfallGlobalData.h) | 0 | ||||
-rw-r--r-- | gr-qtgui/python/.gitignore (renamed from gr-qtgui/src/python/.gitignore) | 1 | ||||
-rw-r--r-- | gr-qtgui/python/Makefile.am (renamed from gr-qtgui/src/python/Makefile.am) | 20 | ||||
-rw-r--r-- | gr-qtgui/python/__init__.py | 25 | ||||
-rwxr-xr-x | gr-qtgui/python/qa_qtgui.py | 48 | ||||
-rw-r--r-- | gr-qtgui/python/run_tests.in | 10 | ||||
-rw-r--r-- | gr-qtgui/src/lib/Makefile.swig.gen | 259 | ||||
-rw-r--r-- | gr-qtgui/src/lib/TimeDomainDisplayPlot.h | 64 | ||||
-rw-r--r-- | gr-qtgui/src/python/__init__.py | 0 | ||||
-rw-r--r-- | gr-qtgui/swig/.gitignore | 2 | ||||
-rw-r--r-- | gr-qtgui/swig/Makefile.am | 57 | ||||
-rw-r--r-- | gr-qtgui/swig/Makefile.swig.gen | 145 | ||||
-rw-r--r-- | gr-qtgui/swig/__init__.py (renamed from gr-qtgui/src/Makefile.am) | 9 | ||||
-rw-r--r-- | gr-qtgui/swig/qtgui_sink_c.i | 66 | ||||
-rw-r--r-- | gr-qtgui/swig/qtgui_sink_f.i (renamed from gr-qtgui/src/lib/qtgui.i) | 68 | ||||
-rw-r--r-- | gr-qtgui/swig/qtgui_swig.i | 35 | ||||
-rw-r--r-- | gr-qtgui/swig/qtgui_time_sink_c.i | 56 | ||||
-rw-r--r-- | gr-qtgui/swig/qtgui_time_sink_f.i | 56 |
78 files changed, 4179 insertions, 879 deletions
diff --git a/gr-qtgui/Makefile.am b/gr-qtgui/Makefile.am index d53f96c1f..cc194e4c0 100644 --- a/gr-qtgui/Makefile.am +++ b/gr-qtgui/Makefile.am @@ -1,5 +1,5 @@ # -# Copyright 2008 Free Software Foundation, Inc. +# Copyright 2008-2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -21,5 +21,11 @@ include $(top_srcdir)/Makefile.common -SUBDIRS = src -DIST_SUBDIRS = src +SUBDIRS = lib + +if PYTHON +SUBDIRS += swig python apps grc +endif + +pkgconfigdir = $(libdir)/pkgconfig +dist_pkgconfig_DATA = gnuradio-qtgui.pc diff --git a/gr-qtgui/apps/.gitignore b/gr-qtgui/apps/.gitignore new file mode 100644 index 000000000..943275d5c --- /dev/null +++ b/gr-qtgui/apps/.gitignore @@ -0,0 +1,3 @@ +Makefile +Makefile.in +grc_qt_example.py diff --git a/gr-qtgui/apps/Makefile.am b/gr-qtgui/apps/Makefile.am new file mode 100644 index 000000000..7b35d949e --- /dev/null +++ b/gr-qtgui/apps/Makefile.am @@ -0,0 +1,46 @@ +# +# Copyright 2011 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 $(top_srcdir)/Makefile.common + +if PYTHON + +nodist_bin_SCRIPTS = \ + qt_digital_window.ui \ + usrp_display_qtgui.ui + +noinst_PYTHON = \ + pyqt_example_f.py \ + pyqt_example_c.py \ + pyqt_time_c.py \ + qt_digital.py \ + qt_digital_window.py \ + usrp2_display.py \ + usrp_display.py \ + qt_digital_window.py \ + usrp_display_qtgui.py + +EXTRA_DIST += \ + qt_digital_window.ui \ + usrp_display_qtgui.ui +endif + +EXTRA_DIST += diff --git a/gr-qtgui/apps/grc_qt_example.grc b/gr-qtgui/apps/grc_qt_example.grc new file mode 100644 index 000000000..170cd546a --- /dev/null +++ b/gr-qtgui/apps/grc_qt_example.grc @@ -0,0 +1,441 @@ +<?xml version='1.0' encoding='ASCII'?> +<flow_graph> + <timestamp>Sun Apr 10 16:49:13 2011</timestamp> + <block> + <key>options</key> + <param> + <key>id</key> + <value>grc_qt_example</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>title</key> + <value></value> + </param> + <param> + <key>author</key> + <value></value> + </param> + <param> + <key>description</key> + <value></value> + </param> + <param> + <key>window_size</key> + <value>1280, 1024</value> + </param> + <param> + <key>generate_options</key> + <value>qt_gui</value> + </param> + <param> + <key>category</key> + <value>Custom</value> + </param> + <param> + <key>run_options</key> + <value>prompt</value> + </param> + <param> + <key>run</key> + <value>True</value> + </param> + <param> + <key>realtime_scheduling</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(10, 10)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>samp_rate</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>32000</value> + </param> + <param> + <key>_coordinate</key> + <value>(10, 170)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_throttle</key> + <param> + <key>id</key> + <value>gr_throttle_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>samples_per_second</key> + <value>samp_rate</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>_coordinate</key> + <value>(511, 96)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable_qtgui_range</key> + <param> + <key>id</key> + <value>freq</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>label</key> + <value>Signal Frequency</value> + </param> + <param> + <key>value</key> + <value>1000</value> + </param> + <param> + <key>start</key> + <value>0</value> + </param> + <param> + <key>stop</key> + <value>samp_rate/2.0</value> + </param> + <param> + <key>step</key> + <value>samp_rate/100.0</value> + </param> + <param> + <key>widget</key> + <value>counter_slider</value> + </param> + <param> + <key>orient</key> + <value>Qt.Horizontal</value> + </param> + <param> + <key>min_len</key> + <value>200</value> + </param> + <param> + <key>gui_hint</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(169, 187)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_sig_source_x</key> + <param> + <key>id</key> + <value>gr_sig_source_x_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>samp_rate</key> + <value>samp_rate</value> + </param> + <param> + <key>waveform</key> + <value>gr.GR_COS_WAVE</value> + </param> + <param> + <key>freq</key> + <value>freq</value> + </param> + <param> + <key>amp</key> + <value>amp</value> + </param> + <param> + <key>offset</key> + <value>0</value> + </param> + <param> + <key>_coordinate</key> + <value>(295, 64)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable_qtgui_range</key> + <param> + <key>id</key> + <value>amp</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>label</key> + <value>Signal Amplitude</value> + </param> + <param> + <key>value</key> + <value>1</value> + </param> + <param> + <key>start</key> + <value>0</value> + </param> + <param> + <key>stop</key> + <value>1.0</value> + </param> + <param> + <key>step</key> + <value>0.01</value> + </param> + <param> + <key>widget</key> + <value>counter_slider</value> + </param> + <param> + <key>orient</key> + <value>Qt.Horizontal</value> + </param> + <param> + <key>min_len</key> + <value>200</value> + </param> + <param> + <key>gui_hint</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(311, 187)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable_qtgui_range</key> + <param> + <key>id</key> + <value>noise</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>label</key> + <value>Noise Amplitude</value> + </param> + <param> + <key>value</key> + <value>0.01</value> + </param> + <param> + <key>start</key> + <value>0</value> + </param> + <param> + <key>stop</key> + <value>1.0</value> + </param> + <param> + <key>step</key> + <value>0.01</value> + </param> + <param> + <key>widget</key> + <value>counter_slider</value> + </param> + <param> + <key>orient</key> + <value>Qt.Horizontal</value> + </param> + <param> + <key>min_len</key> + <value>200</value> + </param> + <param> + <key>gui_hint</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(723, 191)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_channel_model</key> + <param> + <key>id</key> + <value>gr_channel_model_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>noise_voltage</key> + <value>noise</value> + </param> + <param> + <key>freq_offset</key> + <value>0.0</value> + </param> + <param> + <key>epsilon</key> + <value>1.0</value> + </param> + <param> + <key>taps</key> + <value>1.0 + 0.0j</value> + </param> + <param> + <key>seed</key> + <value>42</value> + </param> + <param> + <key>_coordinate</key> + <value>(727, 64)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>qtgui_sink_x</key> + <param> + <key>id</key> + <value>qtgui_sink_x_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>name</key> + <value>QT GUI Plot</value> + </param> + <param> + <key>fftsize</key> + <value>1024</value> + </param> + <param> + <key>wintype</key> + <value>firdes.WIN_BLACKMAN_hARRIS</value> + </param> + <param> + <key>fc</key> + <value>0</value> + </param> + <param> + <key>bw</key> + <value>samp_rate</value> + </param> + <param> + <key>plotfreq</key> + <value>True</value> + </param> + <param> + <key>plotwaterfall</key> + <value>True</value> + </param> + <param> + <key>plottime</key> + <value>True</value> + </param> + <param> + <key>plotconst</key> + <value>False</value> + </param> + <param> + <key>gui_hint</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(958, 72)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <connection> + <source_block_id>gr_sig_source_x_0</source_block_id> + <sink_block_id>gr_throttle_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_throttle_0</source_block_id> + <sink_block_id>gr_channel_model_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_channel_model_0</source_block_id> + <sink_block_id>qtgui_sink_x_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> +</flow_graph> diff --git a/gr-qtgui/src/python/pyqt_example.py b/gr-qtgui/apps/pyqt_example_c.py index 7c0cfc698..607ab12ee 100755 --- a/gr-qtgui/src/python/pyqt_example.py +++ b/gr-qtgui/apps/pyqt_example_c.py @@ -1,7 +1,7 @@ #!/usr/bin/env python from gnuradio import gr -from gnuradio.qtgui import qtgui +from gnuradio import qtgui from PyQt4 import QtGui, QtCore import sys, sip @@ -28,11 +28,13 @@ class control_box(QtGui.QWidget): # Control the first signal self.freq1Edit = QtGui.QLineEdit(self) + self.freq1Edit.setMinimumWidth(100) self.layout.addRow("Signal 1 Frequency:", self.freq1Edit) self.connect(self.freq1Edit, QtCore.SIGNAL("editingFinished()"), self.freq1EditText) self.amp1Edit = QtGui.QLineEdit(self) + self.amp1Edit.setMinimumWidth(100) self.layout.addRow("Signal 1 Amplitude:", self.amp1Edit) self.connect(self.amp1Edit, QtCore.SIGNAL("editingFinished()"), self.amp1EditText) @@ -40,17 +42,20 @@ class control_box(QtGui.QWidget): # Control the second signal self.freq2Edit = QtGui.QLineEdit(self) + self.freq2Edit.setMinimumWidth(100) self.layout.addRow("Signal 2 Frequency:", self.freq2Edit) self.connect(self.freq2Edit, QtCore.SIGNAL("editingFinished()"), self.freq2EditText) self.amp2Edit = QtGui.QLineEdit(self) + self.amp2Edit.setMinimumWidth(100) self.layout.addRow("Signal 2 Amplitude:", self.amp2Edit) self.connect(self.amp2Edit, QtCore.SIGNAL("editingFinished()"), self.amp2EditText) self.quit = QtGui.QPushButton('Close', self) + self.quit.setMinimumWidth(100) self.layout.addWidget(self.quit) self.connect(self.quit, QtCore.SIGNAL('clicked()'), @@ -116,7 +121,7 @@ class my_top_block(gr.top_block): self.snk1 = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, 0, Rs, "Complex Signal Example", - True, True, False, True, False) + True, True, True, False) self.connect(src1, (src,0)) self.connect(src2, (src,1)) @@ -131,9 +136,9 @@ class my_top_block(gr.top_block): # Wrap the pointer as a PyQt SIP object # This can now be manipulated as a PyQt4.QtGui.QWidget - self.pyWin = sip.wrapinstance(pyQt, QtGui.QWidget) + pyWin = sip.wrapinstance(pyQt, QtGui.QWidget) - self.main_box = dialog_box(self.pyWin, self.ctrl_win) + self.main_box = dialog_box(pyWin, self.ctrl_win) self.main_box.show() @@ -141,4 +146,5 @@ if __name__ == "__main__": tb = my_top_block(); tb.start() tb.qapp.exec_() + tb.stop() diff --git a/gr-qtgui/src/python/pyqt_example_f.py b/gr-qtgui/apps/pyqt_example_f.py index 4e36ccca5..2d957c85a 100755 --- a/gr-qtgui/src/python/pyqt_example_f.py +++ b/gr-qtgui/apps/pyqt_example_f.py @@ -1,7 +1,7 @@ #!/usr/bin/env python -from gnuradio import gr, blks2 -from gnuradio.qtgui import qtgui +from gnuradio import gr +from gnuradio import qtgui from PyQt4 import QtGui, QtCore import sys, sip @@ -28,11 +28,13 @@ class control_box(QtGui.QWidget): # Control the first signal self.freq1Edit = QtGui.QLineEdit(self) + self.freq1Edit.setMinimumWidth(100) self.layout.addRow("Signal 1 Frequency:", self.freq1Edit) self.connect(self.freq1Edit, QtCore.SIGNAL("editingFinished()"), self.freq1EditText) self.amp1Edit = QtGui.QLineEdit(self) + self.amp1Edit.setMinimumWidth(100) self.layout.addRow("Signal 1 Amplitude:", self.amp1Edit) self.connect(self.amp1Edit, QtCore.SIGNAL("editingFinished()"), self.amp1EditText) @@ -40,17 +42,20 @@ class control_box(QtGui.QWidget): # Control the second signal self.freq2Edit = QtGui.QLineEdit(self) + self.freq2Edit.setMinimumWidth(100) self.layout.addRow("Signal 2 Frequency:", self.freq2Edit) self.connect(self.freq2Edit, QtCore.SIGNAL("editingFinished()"), self.freq2EditText) self.amp2Edit = QtGui.QLineEdit(self) + self.amp2Edit.setMinimumWidth(100) self.layout.addRow("Signal 2 Amplitude:", self.amp2Edit) self.connect(self.amp2Edit, QtCore.SIGNAL("editingFinished()"), self.amp2EditText) self.quit = QtGui.QPushButton('Close', self) + self.quit.setMinimumWidth(100) self.layout.addWidget(self.quit) self.connect(self.quit, QtCore.SIGNAL('clicked()'), @@ -112,14 +117,18 @@ class my_top_block(gr.top_block): src2 = gr.sig_source_f(Rs, gr.GR_SIN_WAVE, f2, 0.1, 0) src = gr.add_ff() thr = gr.throttle(gr.sizeof_float, 100*fftsize) + noise = gr.noise_source_f(gr.GR_GAUSSIAN, 0.001) + add = gr.add_ff() self.snk1 = qtgui.sink_f(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, 0, Rs, "Float Signal Example", - True, True, False, True, False) + True, True, True, False) self.connect(src1, (src,0)) self.connect(src2, (src,1)) - self.connect(src, thr, self.snk1) + self.connect(src, thr, (add,0)) + self.connect(noise, (add,1)) + self.connect(add, self.snk1) self.ctrl_win = control_box() self.ctrl_win.attach_signal1(src1) @@ -130,9 +139,9 @@ class my_top_block(gr.top_block): # Wrap the pointer as a PyQt SIP object # This can now be manipulated as a PyQt4.QtGui.QWidget - self.pyWin = sip.wrapinstance(pyQt, QtGui.QWidget) + pyWin = sip.wrapinstance(pyQt, QtGui.QWidget) - self.main_box = dialog_box(self.pyWin, self.ctrl_win) + self.main_box = dialog_box(pyWin, self.ctrl_win) self.main_box.show() @@ -140,4 +149,4 @@ if __name__ == "__main__": tb = my_top_block(); tb.start() tb.qapp.exec_() - + tb.stop() diff --git a/gr-qtgui/apps/pyqt_time_c.py b/gr-qtgui/apps/pyqt_time_c.py new file mode 100755 index 000000000..fa7d60e81 --- /dev/null +++ b/gr-qtgui/apps/pyqt_time_c.py @@ -0,0 +1,163 @@ +#!/usr/bin/env python + +from gnuradio import gr +from gnuradio import qtgui +from PyQt4 import QtGui, QtCore +import sys, sip + +class dialog_box(QtGui.QWidget): + def __init__(self, display, control): + QtGui.QWidget.__init__(self, None) + self.setWindowTitle('PyQt Test GUI') + + self.boxlayout = QtGui.QBoxLayout(QtGui.QBoxLayout.LeftToRight, self) + self.boxlayout.addWidget(display, 1) + self.boxlayout.addWidget(control) + + self.resize(800, 500) + +class control_box(QtGui.QWidget): + def __init__(self, parent=None): + QtGui.QWidget.__init__(self, parent) + self.setWindowTitle('Control Panel') + + self.setToolTip('Control the signals') + QtGui.QToolTip.setFont(QtGui.QFont('OldEnglish', 10)) + + self.layout = QtGui.QFormLayout(self) + + # Control the first signal + self.freq1Edit = QtGui.QLineEdit(self) + self.freq1Edit.setMinimumWidth(100) + self.layout.addRow("Signal 1 Frequency:", self.freq1Edit) + self.connect(self.freq1Edit, QtCore.SIGNAL("editingFinished()"), + self.freq1EditText) + + self.amp1Edit = QtGui.QLineEdit(self) + self.amp1Edit.setMinimumWidth(100) + self.layout.addRow("Signal 1 Amplitude:", self.amp1Edit) + self.connect(self.amp1Edit, QtCore.SIGNAL("editingFinished()"), + self.amp1EditText) + + + # Control the second signal + self.freq2Edit = QtGui.QLineEdit(self) + self.freq2Edit.setMinimumWidth(100) + self.layout.addRow("Signal 2 Frequency:", self.freq2Edit) + self.connect(self.freq2Edit, QtCore.SIGNAL("editingFinished()"), + self.freq2EditText) + + + self.amp2Edit = QtGui.QLineEdit(self) + self.amp2Edit.setMinimumWidth(100) + self.layout.addRow("Signal 2 Amplitude:", self.amp2Edit) + self.connect(self.amp2Edit, QtCore.SIGNAL("editingFinished()"), + self.amp2EditText) + + self.quit = QtGui.QPushButton('Close', self) + self.quit.setMinimumWidth(100) + self.layout.addWidget(self.quit) + + self.connect(self.quit, QtCore.SIGNAL('clicked()'), + QtGui.qApp, QtCore.SLOT('quit()')) + + def attach_signal1(self, signal): + self.signal1 = signal + self.freq1Edit.setText(QtCore.QString("%1").arg(self.signal1.frequency())) + self.amp1Edit.setText(QtCore.QString("%1").arg(self.signal1.amplitude())) + + def attach_signal2(self, signal): + self.signal2 = signal + self.freq2Edit.setText(QtCore.QString("%1").arg(self.signal2.frequency())) + self.amp2Edit.setText(QtCore.QString("%1").arg(self.signal2.amplitude())) + + def freq1EditText(self): + try: + newfreq = float(self.freq1Edit.text()) + self.signal1.set_frequency(newfreq) + except ValueError: + print "Bad frequency value entered" + + def amp1EditText(self): + try: + newamp = float(self.amp1Edit.text()) + self.signal1.set_amplitude(newamp) + except ValueError: + print "Bad amplitude value entered" + + + def freq2EditText(self): + try: + newfreq = float(self.freq2Edit.text()) + self.signal2.set_frequency(newfreq) + except ValueError: + print "Bad frequency value entered" + + def amp2EditText(self): + try: + newamp = float(self.amp2Edit.text()) + self.signal2.set_amplitude(newamp) + except ValueError: + print "Bad amplitude value entered" + + +class my_top_block(gr.top_block): + def __init__(self): + gr.top_block.__init__(self) + + Rs = 8000 + f1 = 100 + f2 = 200 + + npts = 2048 + + self.qapp = QtGui.QApplication(sys.argv) + + src1 = gr.sig_source_c(Rs, gr.GR_SIN_WAVE, f1, 0.1, 0) + src2 = gr.sig_source_c(Rs, gr.GR_SIN_WAVE, f2, 0.1, 0) + src = gr.add_cc() + channel = gr.channel_model(0.01) + thr = gr.throttle(gr.sizeof_gr_complex, 100*npts) + self.snk1 = qtgui.time_sink_c(npts, Rs, + "Complex Time Example", 3) + + self.connect(src1, (src,0)) + self.connect(src2, (src,1)) + self.connect(src, channel, thr, (self.snk1, 0)) + self.connect(src1, (self.snk1, 1)) + self.connect(src2, (self.snk1, 2)) + + self.ctrl_win = control_box() + self.ctrl_win.attach_signal1(src1) + self.ctrl_win.attach_signal2(src2) + + # Get the reference pointer to the SpectrumDisplayForm QWidget + pyQt = self.snk1.pyqwidget() + + # Wrap the pointer as a PyQt SIP object + # This can now be manipulated as a PyQt4.QtGui.QWidget + pyWin = sip.wrapinstance(pyQt, QtGui.QWidget) + + # Example of using signal/slot to set the title of a curve + pyWin.connect(pyWin, QtCore.SIGNAL("setTitle(int, QString)"), + pyWin, QtCore.SLOT("setTitle(int, QString)")) + pyWin.emit(QtCore.SIGNAL("setTitle(int, QString)"), 0, "Re{sum}") + self.snk1.set_title(1, "Im{Sum}") + self.snk1.set_title(2, "Re{src1}") + self.snk1.set_title(3, "Im{src1}") + self.snk1.set_title(4, "Re{src2}") + self.snk1.set_title(5, "Im{src2}") + + # Can also set the color of a curve + #self.snk1.set_color(5, "blue") + + #pyWin.show() + self.main_box = dialog_box(pyWin, self.ctrl_win) + self.main_box.show() + +if __name__ == "__main__": + tb = my_top_block(); + tb.start() + tb.qapp.exec_() + tb.stop() + diff --git a/gr-qtgui/apps/pyqt_time_f.py b/gr-qtgui/apps/pyqt_time_f.py new file mode 100755 index 000000000..1b9efa10d --- /dev/null +++ b/gr-qtgui/apps/pyqt_time_f.py @@ -0,0 +1,163 @@ +#!/usr/bin/env python + +from gnuradio import gr +from gnuradio import qtgui +from PyQt4 import QtGui, QtCore +import sys, sip + +class dialog_box(QtGui.QWidget): + def __init__(self, display, control): + QtGui.QWidget.__init__(self, None) + self.setWindowTitle('PyQt Test GUI') + + self.boxlayout = QtGui.QBoxLayout(QtGui.QBoxLayout.LeftToRight, self) + self.boxlayout.addWidget(display, 1) + self.boxlayout.addWidget(control) + + self.resize(800, 500) + +class control_box(QtGui.QWidget): + def __init__(self, parent=None): + QtGui.QWidget.__init__(self, parent) + self.setWindowTitle('Control Panel') + + self.setToolTip('Control the signals') + QtGui.QToolTip.setFont(QtGui.QFont('OldEnglish', 10)) + + self.layout = QtGui.QFormLayout(self) + + # Control the first signal + self.freq1Edit = QtGui.QLineEdit(self) + self.freq1Edit.setMinimumWidth(100) + self.layout.addRow("Signal 1 Frequency:", self.freq1Edit) + self.connect(self.freq1Edit, QtCore.SIGNAL("editingFinished()"), + self.freq1EditText) + + self.amp1Edit = QtGui.QLineEdit(self) + self.amp1Edit.setMinimumWidth(100) + self.layout.addRow("Signal 1 Amplitude:", self.amp1Edit) + self.connect(self.amp1Edit, QtCore.SIGNAL("editingFinished()"), + self.amp1EditText) + + + # Control the second signal + self.freq2Edit = QtGui.QLineEdit(self) + self.freq2Edit.setMinimumWidth(100) + self.layout.addRow("Signal 2 Frequency:", self.freq2Edit) + self.connect(self.freq2Edit, QtCore.SIGNAL("editingFinished()"), + self.freq2EditText) + + + self.amp2Edit = QtGui.QLineEdit(self) + self.amp2Edit.setMinimumWidth(100) + self.layout.addRow("Signal 2 Amplitude:", self.amp2Edit) + self.connect(self.amp2Edit, QtCore.SIGNAL("editingFinished()"), + self.amp2EditText) + + self.quit = QtGui.QPushButton('Close', self) + self.quit.setMinimumWidth(100) + self.layout.addWidget(self.quit) + + self.connect(self.quit, QtCore.SIGNAL('clicked()'), + QtGui.qApp, QtCore.SLOT('quit()')) + + def attach_signal1(self, signal): + self.signal1 = signal + self.freq1Edit.setText(QtCore.QString("%1").arg(self.signal1.frequency())) + self.amp1Edit.setText(QtCore.QString("%1").arg(self.signal1.amplitude())) + + def attach_signal2(self, signal): + self.signal2 = signal + self.freq2Edit.setText(QtCore.QString("%1").arg(self.signal2.frequency())) + self.amp2Edit.setText(QtCore.QString("%1").arg(self.signal2.amplitude())) + + def freq1EditText(self): + try: + newfreq = float(self.freq1Edit.text()) + self.signal1.set_frequency(newfreq) + except ValueError: + print "Bad frequency value entered" + + def amp1EditText(self): + try: + newamp = float(self.amp1Edit.text()) + self.signal1.set_amplitude(newamp) + except ValueError: + print "Bad amplitude value entered" + + + def freq2EditText(self): + try: + newfreq = float(self.freq2Edit.text()) + self.signal2.set_frequency(newfreq) + except ValueError: + print "Bad frequency value entered" + + def amp2EditText(self): + try: + newamp = float(self.amp2Edit.text()) + self.signal2.set_amplitude(newamp) + except ValueError: + print "Bad amplitude value entered" + + +class my_top_block(gr.top_block): + def __init__(self): + gr.top_block.__init__(self) + + Rs = 8000 + f1 = 100 + f2 = 200 + + npts = 2048 + + self.qapp = QtGui.QApplication(sys.argv) + + src1 = gr.sig_source_f(Rs, gr.GR_SIN_WAVE, f1, 0.1, 0) + src2 = gr.sig_source_f(Rs, gr.GR_SIN_WAVE, f2, 0.1, 0) + src = gr.add_ff() + thr = gr.throttle(gr.sizeof_float, 100*npts) + noise = gr.noise_source_f(gr.GR_GAUSSIAN, 0.001) + add = gr.add_ff() + self.snk1 = qtgui.time_sink_f(npts, Rs, + "Complex Time Example", 3) + + self.connect(src1, (src,0)) + self.connect(src2, (src,1)) + self.connect(src, thr, (add,0)) + self.connect(noise, (add,1)) + self.connect(add, self.snk1) + self.connect(src1, (self.snk1, 1)) + self.connect(src2, (self.snk1, 2)) + + self.ctrl_win = control_box() + self.ctrl_win.attach_signal1(src1) + self.ctrl_win.attach_signal2(src2) + + # Get the reference pointer to the SpectrumDisplayForm QWidget + pyQt = self.snk1.pyqwidget() + + # Wrap the pointer as a PyQt SIP object + # This can now be manipulated as a PyQt4.QtGui.QWidget + pyWin = sip.wrapinstance(pyQt, QtGui.QWidget) + + # Example of using signal/slot to set the title of a curve + pyWin.connect(pyWin, QtCore.SIGNAL("setTitle(int, QString)"), + pyWin, QtCore.SLOT("setTitle(int, QString)")) + pyWin.emit(QtCore.SIGNAL("setTitle(int, QString)"), 0, "sum") + self.snk1.set_title(1, "src1") + self.snk1.set_title(2, "src2") + + # Can also set the color of a curve + #self.snk1.set_color(5, "blue") + + #pyWin.show() + self.main_box = dialog_box(pyWin, self.ctrl_win) + self.main_box.show() + +if __name__ == "__main__": + tb = my_top_block(); + tb.start() + tb.qapp.exec_() + tb.stop() + diff --git a/gr-qtgui/src/python/qt_digital.py b/gr-qtgui/apps/qt_digital.py index 679f144ef..99c799f2a 100755 --- a/gr-qtgui/src/python/qt_digital.py +++ b/gr-qtgui/apps/qt_digital.py @@ -1,7 +1,7 @@ #!/usr/bin/env python from gnuradio import gr, blks2 -from gnuradio.qtgui import qtgui +from gnuradio import qtgui from gnuradio import eng_notation from PyQt4 import QtGui, QtCore import sys, sip @@ -185,11 +185,11 @@ class my_top_block(gr.top_block): self.thr = gr.throttle(gr.sizeof_char, self._sample_rate) self.snk_tx = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, 0, self._sample_rate*self.sps, - "Tx", True, True, False, True, True) + "Tx", True, True, True, True) self.snk_rx = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, 0, self._sample_rate, - "Rx", True, True, False, True, True) + "Rx", True, True, True, True) self.connect(self.src, self.thr, self.mod, self.channel, self.snk_tx) self.connect(self.channel, self.rx_rrc, self.receiver, self.snk_rx) @@ -274,3 +274,4 @@ if __name__ == "__main__": tb = my_top_block(); tb.start() tb.qapp.exec_() + tb.stop() diff --git a/gr-qtgui/src/python/qt_digital_window.py b/gr-qtgui/apps/qt_digital_window.py index 50dd53a92..50dd53a92 100644 --- a/gr-qtgui/src/python/qt_digital_window.py +++ b/gr-qtgui/apps/qt_digital_window.py diff --git a/gr-qtgui/src/python/qt_digital_window.ui b/gr-qtgui/apps/qt_digital_window.ui index 967252181..967252181 100644 --- a/gr-qtgui/src/python/qt_digital_window.ui +++ b/gr-qtgui/apps/qt_digital_window.ui diff --git a/gr-qtgui/src/python/usrp2_display.py b/gr-qtgui/apps/usrp2_display.py index 75d374c2b..ab1a6f742 100755 --- a/gr-qtgui/src/python/usrp2_display.py +++ b/gr-qtgui/apps/usrp2_display.py @@ -210,7 +210,7 @@ class my_top_block(gr.top_block): self.snk = qtgui.sink_c(options.fft_size, gr.firdes.WIN_BLACKMAN_hARRIS, self._freq, self._bandwidth, "USRP2 Display", - True, True, False, True, False) + True, True, True, False) # Set up internal amplifier self.amp = gr.multiply_const_cc(0.0) diff --git a/gr-qtgui/src/python/usrp_display.py b/gr-qtgui/apps/usrp_display.py index 432e74d9a..131bc4a7e 100755 --- a/gr-qtgui/src/python/usrp_display.py +++ b/gr-qtgui/apps/usrp_display.py @@ -229,7 +229,7 @@ class my_top_block(gr.top_block): self.snk = qtgui.sink_c(self._fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, self._freq, self._bandwidth, "USRP Display", - True, True, False, True, False) + True, True, True, False) # Set up internal amplifier self.amp = gr.multiply_const_cc(0.0) diff --git a/gr-qtgui/src/python/usrp_display_qtgui.py b/gr-qtgui/apps/usrp_display_qtgui.py index 4c9de3a53..4c9de3a53 100644 --- a/gr-qtgui/src/python/usrp_display_qtgui.py +++ b/gr-qtgui/apps/usrp_display_qtgui.py diff --git a/gr-qtgui/src/python/usrp_display_qtgui.ui b/gr-qtgui/apps/usrp_display_qtgui.ui index e88ca9dce..e88ca9dce 100644 --- a/gr-qtgui/src/python/usrp_display_qtgui.ui +++ b/gr-qtgui/apps/usrp_display_qtgui.ui diff --git a/gr-qtgui/gnuradio-qtgui.pc.in b/gr-qtgui/gnuradio-qtgui.pc.in new file mode 100644 index 000000000..27b6a21bf --- /dev/null +++ b/gr-qtgui/gnuradio-qtgui.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: gnuradio-qtgui +Description: GNU Radio blocks for QT GUI +Requires: gnuradio-core +Version: @LIBVER@ +Libs: -L${libdir} -lgnuradio-qtgui +Cflags: -I${includedir} diff --git a/gr-qtgui/src/.gitignore b/gr-qtgui/grc/.gitignore index b336cc7ce..b336cc7ce 100644 --- a/gr-qtgui/src/.gitignore +++ b/gr-qtgui/grc/.gitignore diff --git a/gr-qtgui/grc/Makefile.am b/gr-qtgui/grc/Makefile.am new file mode 100644 index 000000000..ccd459a13 --- /dev/null +++ b/gr-qtgui/grc/Makefile.am @@ -0,0 +1,34 @@ +# +# Copyright 2010-2011 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 $(top_srcdir)/Makefile.common + +grcblocksdir = $(grc_blocksdir) + +dist_grcblocks_DATA = \ + qtgui_check_box.xml \ + qtgui_entry.xml \ + qtgui_label.xml \ + qtgui_range.xml \ + qtgui_sink_x.xml \ + qtgui_time_sink_x.xml \ + qtgui_tab_widget.xml \ + qtgui_chooser.xml diff --git a/gr-qtgui/grc/qtgui_check_box.xml b/gr-qtgui/grc/qtgui_check_box.xml new file mode 100644 index 000000000..95f4f968a --- /dev/null +++ b/gr-qtgui/grc/qtgui_check_box.xml @@ -0,0 +1,83 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Variable Check Box: +## a gui check box form +################################################### + --> +<block> + <name>QT GUI Check Box</name> + <key>variable_qtgui_check_box</key> + <category>QT GUI Widgets</category> + <import>from PyQt4 import Qt</import> + <var_make>self.$(id) = $(id) = $value</var_make> + <make>#set $win = '_%s_check_box'%$id +#if not $label() + #set $label = '"%s"'%$id +#end if +$win = Qt.QCheckBox($label) +self._$(id)_choices = {True: $true, False: $false} +self._$(id)_choices_inv = dict((v,k) for k,v in self._$(id)_choices.iteritems()) +self._$(id)_callback = lambda i: $(win).setChecked(self._$(id)_choices_inv[i]) +self._$(id)_callback(self.$id) +$(win).stateChanged.connect(lambda i: self.set_$(id)(self._$(id)_choices[bool(i)])) +$(gui_hint()($win))</make> + <callback>self.set_$(id)($value)</callback> + <callback>self._$(id)_callback($id)</callback> + <param> + <name>Label</name> + <key>label</key> + <value></value> + <type>string</type> + <hide>#if $label() then 'none' else 'part'#</hide> + </param> + <param> + <name>Type</name> + <key>type</key> + <value>int</value> + <type>enum</type> + <hide>part</hide> + <option><name>Float</name><key>real</key><opt>conv:float</opt></option> + <option><name>Integer</name><key>int</key><opt>conv:int</opt></option> + <option><name>String</name><key>string</key><opt>conv:str</opt></option> + <option><name>Boolean</name><key>bool</key><opt>conv:bool</opt></option> + <option><name>Any</name><key>raw</key><opt>conv:eval</opt></option> + </param> + <param> + <name>Default Value</name> + <key>value</key> + <value>True</value> + <type>$type</type> + </param> + <param> + <name>True</name> + <key>true</key> + <value>True</value> + <type>$type</type> + </param> + <param> + <name>False</name> + <key>false</key> + <value>False</value> + <type>$type</type> + </param> + <param> + <name>GUI Hint</name> + <key>gui_hint</key> + <value></value> + <type>gui_hint</type> + <hide>part</hide> + </param> + <check>$value in ($true, $false)</check> + <doc> +This block creates a variable check box. \ +Leave the label blank to use the variable id as the label. + +A check box selects between two values of similar type. \ +Te values do not necessarily need to be of boolean type. + +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/grc/qtgui_chooser.xml b/gr-qtgui/grc/qtgui_chooser.xml new file mode 100644 index 000000000..cb5090289 --- /dev/null +++ b/gr-qtgui/grc/qtgui_chooser.xml @@ -0,0 +1,251 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Variable Chooser: +## A chooser, radio buttons +################################################### + --> +<block> + <name>QT GUI Chooser</name> + <key>variable_qtgui_chooser</key> + <category>QT GUI Widgets</category> + <import>from PyQt4 import Qt</import> + <var_make>self.$(id) = $(id) = $value</var_make> + <make>#slurp +#set $all_options = [$option0, $option1, $option2, $option3, $option4][:int($num_opts())] +#set $all_labels = [$label0, $label1, $label2, $label3, $label4][:int($num_opts())] +#if not $label() + #set $label = '"%s"'%$id +#end if +######################################################################## +## Create the options list +######################################################################## +#if int($num_opts()) +self._$(id)_options = (#slurp + #for $ch in $all_options +$ch, #slurp + #end for +) +#else +self._$(id)_options = $options +#end if +######################################################################## +## Create the labels list +######################################################################## +#if int($num_opts()) +self._$(id)_labels = (#slurp + #for i, $lbl in enumerate($all_labels) + #if $lbl() +$lbl, #slurp + #else +str(self._$(id)_options[$i]), #slurp + #end if + #end for +) +#elif $labels() +self._$(id)_labels = $labels +#else +self._$(id)_labels = map(str, self._$(id)_options) +#end if +######################################################################## +## Create the combo box +######################################################################## +#if $widget() == 'combo_box' +#set $win = 'self._%s_tool_bar'%$id +$win = Qt.QToolBar(self) +$(win).addWidget(Qt.QLabel($label+": ")) +self._$(id)_combo_box = Qt.QComboBox() +$(win).addWidget(self._$(id)_combo_box) +for label in self._$(id)_labels: self._$(id)_combo_box.addItem(label) +self._$(id)_callback = lambda i: self._$(id)_combo_box.setCurrentIndex(self._$(id)_options.index(i)) +self._$(id)_callback(self.$id) +self._$(id)_combo_box.currentIndexChanged.connect( + lambda i: self.set_$(id)(self._$(id)_options[i])) +#end if +######################################################################## +## Create the radio buttons +######################################################################## +#if $widget() == 'radio_buttons' +#set $win = 'self._%s_group_box'%$id +$win = Qt.QGroupBox($label) +self._$(id)_box = $(orient)() +self._$(id)_button_group = Qt.QButtonGroup() +$(win).setLayout(self._$(id)_box) +for i, label in enumerate(self._$(id)_labels): + radio_button = Qt.QRadioButton(label) + self._$(id)_box.addWidget(radio_button) + self._$(id)_button_group.addButton(radio_button, i) +self._$(id)_callback = lambda i: self._$(id)_button_group.button(self._$(id)_options.index(i)).setChecked(True) +self._$(id)_callback(self.$id) +self._$(id)_button_group.buttonClicked[int].connect( + lambda i: self.set_$(id)(self._$(id)_options[i])) +#end if +$(gui_hint()($win))</make> + <callback>self.set_$(id)($value)</callback> + <callback>self._$(id)_callback($id)</callback> + <param> + <name>Label</name> + <key>label</key> + <value></value> + <type>string</type> + <hide>#if $label() then 'none' else 'part'#</hide> + </param> + <param> + <name>Type</name> + <key>type</key> + <value>int</value> + <type>enum</type> + <hide>part</hide> + <option><name>Float</name><key>real</key></option> + <option><name>Integer</name><key>int</key></option> + <option><name>String</name><key>string</key></option> + <option><name>Any</name><key>raw</key></option> + </param> + <param> + <name>Num Options</name> + <key>num_opts</key> + <value>3</value> + <type>enum</type> + <option><name>List</name><key>0</key></option> + <option><name>1</name><key>1</key></option> + <option><name>2</name><key>2</key></option> + <option><name>3</name><key>3</key></option> + <option><name>4</name><key>4</key></option> + <option><name>5</name><key>5</key></option> + </param> + <param> + <name>Default Value</name> + <key>value</key> + <value>0</value> + <type>$type</type> + </param> + <param> + <name>Options</name> + <key>options</key> + <value>[0, 1, 2]</value> + <type>raw</type> + <hide>#if int($num_opts()) then 'all' else 'none'#</hide> + </param> + <param> + <name>Labels</name> + <key>labels</key> + <value>[]</value> + <type>raw</type> + <hide>#if int($num_opts()) then 'all' else 'none'#</hide> + </param> + <param> + <name>Option 0</name> + <key>option0</key> + <value>0</value> + <type>$type</type> + <hide>#if int($num_opts()) > 0 then 'none' else 'all'#</hide> + </param> + <param> + <name>Label 0</name> + <key>label0</key> + <value></value> + <type>string</type> + <hide>$((int($num_opts()) > 0) and ($label0() and 'none' or 'part') or 'all')</hide> + </param> + <param> + <name>Option 1</name> + <key>option1</key> + <value>1</value> + <type>$type</type> + <hide>#if int($num_opts()) > 1 then 'none' else 'all'#</hide> + </param> + <param> + <name>Label 1</name> + <key>label1</key> + <value></value> + <type>string</type> + <hide>$((int($num_opts()) > 1) and ($label1() and 'none' or 'part') or 'all')</hide> + </param> + <param> + <name>Option 2</name> + <key>option2</key> + <value>2</value> + <type>$type</type> + <hide>#if int($num_opts()) > 2 then 'none' else 'all'#</hide> + </param> + <param> + <name>Label 2</name> + <key>label2</key> + <value></value> + <type>string</type> + <hide>$((int($num_opts()) > 2) and ($label2() and 'none' or 'part') or 'all')</hide> + </param> + <param> + <name>Option 3</name> + <key>option3</key> + <value>3</value> + <type>$type</type> + <hide>#if int($num_opts()) > 3 then 'none' else 'all'#</hide> + </param> + <param> + <name>Label 3</name> + <key>label3</key> + <value></value> + <type>string</type> + <hide>$((int($num_opts()) > 3) and ($label3() and 'none' or 'part') or 'all')</hide> + </param> + <param> + <name>Option 4</name> + <key>option4</key> + <value>4</value> + <type>$type</type> + <hide>#if int($num_opts()) > 4 then 'none' else 'all'#</hide> + </param> + <param> + <name>Label 4</name> + <key>label4</key> + <value></value> + <type>string</type> + <hide>$((int($num_opts()) > 4) and ($label4() and 'none' or 'part') or 'all')</hide> + </param> + <param> + <name>Widget</name> + <key>widget</key> + <value>combo_box</value> + <type>enum</type> + <hide>part</hide> + <option><name>Combo Box</name><key>combo_box</key></option> + <option><name>Radio Buttons</name><key>radio_buttons</key></option> + </param> + <param> + <name>Orientation</name> + <key>orient</key> + <value>Qt.QVBoxLayout</value> + <type>enum</type> + <hide>#if $widget() == 'radio_buttons' then 'part' else 'all'#</hide> + <option> + <name>Horizontal</name> + <key>Qt.QHBoxLayout</key> + </option> + <option> + <name>Vertical</name> + <key>Qt.QVBoxLayout</key> + </option> + </param> + <param> + <name>GUI Hint</name> + <key>gui_hint</key> + <value></value> + <type>gui_hint</type> + <hide>part</hide> + </param> + <doc> +This block creates a variable with enumerated options. \ +The gui widget is implemented as a combo box or radio button group. \ +Leave the label blank to use the variable id as the label. + +Choose the number of options available to your chooser. \ +When the label is left blank, the option will be used as the label. \ +Set the number of options to "list" to enter a single list of options and labels. \ +When the labels is an empty list, the options will be used as the label. + +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/grc/qtgui_entry.xml b/gr-qtgui/grc/qtgui_entry.xml new file mode 100644 index 000000000..1a98402a0 --- /dev/null +++ b/gr-qtgui/grc/qtgui_entry.xml @@ -0,0 +1,68 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Variable Text Entry: +## a gui text box form +################################################### + --> +<block> + <name>QT GUI Entry</name> + <key>variable_qtgui_entry</key> + <category>QT GUI Widgets</category> + <import>from PyQt4 import Qt</import> + <import>from gnuradio import eng_notation</import> + <var_make>self.$(id) = $(id) = $value</var_make> + <make>#set $win = 'self._%s_tool_bar'%$id +$win = Qt.QToolBar(self) +#if not $label() + #set $label = '"%s"'%$id +#end if +$(win).addWidget(Qt.QLabel($label+": ")) +self._$(id)_line_edit = Qt.QLineEdit(str(self.$id)) +self._$(id)_tool_bar.addWidget(self._$(id)_line_edit) +self._$(id)_line_edit.returnPressed.connect( + lambda: self.set_$(id)($(type.conv)(self._$(id)_line_edit.text().toAscii()))) +$(gui_hint()($win))</make> + <callback>self.set_$(id)($value)</callback> + <callback>self._$(id)_line_edit.setText($(type.str)($id))</callback> + <param> + <name>Label</name> + <key>label</key> + <value></value> + <type>string</type> + <hide>#if $label() then 'none' else 'part'#</hide> + </param> + <param> + <name>Type</name> + <key>type</key> + <value>int</value> + <type>enum</type> + <hide>part</hide> + <option><name>Float</name><key>real</key><opt>conv:eng_notation.str_to_num</opt><opt>str:eng_notation.num_to_str</opt></option> + <option><name>Integer</name><key>int</key><opt>conv:int</opt><opt>str:str</opt></option> + <option><name>String</name><key>string</key><opt>conv:str</opt><opt>str:str</opt></option> + <option><name>Boolean</name><key>bool</key><opt>conv:bool</opt><opt>str:str</opt></option> + <option><name>Any</name><key>raw</key><opt>conv:eval</opt><opt>str:repr</opt></option> + </param> + <param> + <name>Default Value</name> + <key>value</key> + <value>0</value> + <type>$type</type> + </param> + <param> + <name>GUI Hint</name> + <key>gui_hint</key> + <value></value> + <type>gui_hint</type> + <hide>part</hide> + </param> + <doc> +This block creates a variable with a text entry box. \ +Leave the label blank to use the variable id as the label. + +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/grc/qtgui_label.xml b/gr-qtgui/grc/qtgui_label.xml new file mode 100644 index 000000000..5049118c4 --- /dev/null +++ b/gr-qtgui/grc/qtgui_label.xml @@ -0,0 +1,66 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Variable Label Text: +## a gui static text form +################################################### + --> +<block> + <name>QT GUI Label</name> + <key>variable_qtgui_label</key> + <category>QT GUI Widgets</category> + <import>from PyQt4 import Qt</import> + <import>from gnuradio import eng_notation</import> + <var_make>self.$(id) = $(id) = $value</var_make> + <make>#set $win = 'self._%s_tool_bar'%$id +$win = Qt.QToolBar(self) +#if not $label() + #set $label = '"%s"'%$id +#end if +$(win).addWidget(Qt.QLabel($label+": ")) +self._$(id)_label = Qt.QLabel(str(self.$id)) +self._$(id)_tool_bar.addWidget(self._$(id)_label) +$(gui_hint()($win))</make> + <callback>self.set_$(id)($value)</callback> + <callback>self._$(id)_label.setText($(type.str)($id))</callback> + <param> + <name>Label</name> + <key>label</key> + <value></value> + <type>string</type> + <hide>#if $label() then 'none' else 'part'#</hide> + </param> + <param> + <name>Type</name> + <key>type</key> + <value>int</value> + <type>enum</type> + <hide>part</hide> + <option><name>Float</name><key>real</key><opt>conv:eng_notation.str_to_num</opt><opt>str:eng_notation.num_to_str</opt></option> + <option><name>Integer</name><key>int</key><opt>conv:int</opt><opt>str:str</opt></option> + <option><name>String</name><key>string</key><opt>conv:str</opt><opt>str:str</opt></option> + <option><name>Boolean</name><key>bool</key><opt>conv:bool</opt><opt>str:str</opt></option> + <option><name>Any</name><key>raw</key><opt>conv:eval</opt><opt>str:repr</opt></option> + </param> + <param> + <name>Default Value</name> + <key>value</key> + <value>0</value> + <type>$type</type> + </param> + <param> + <name>GUI Hint</name> + <key>gui_hint</key> + <value></value> + <type>gui_hint</type> + <hide>part</hide> + </param> + <doc> +This block creates a variable with a label widget for text. \ +Leave the label blank to use the variable id as the label. + +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/grc/qtgui_range.xml b/gr-qtgui/grc/qtgui_range.xml new file mode 100644 index 000000000..6b0555f98 --- /dev/null +++ b/gr-qtgui/grc/qtgui_range.xml @@ -0,0 +1,211 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Variable Range: +## ranged widgets like a slider or a knob +################################################### + --> +<block> + <name>QT GUI Range</name> + <key>variable_qtgui_range</key> + <category>QT GUI Widgets</category> + <import>from PyQt4 import Qt</import> + <import>import PyQt4.Qwt5 as Qwt</import> + <var_make>self.$(id) = $(id) = $value</var_make> + <make>#set $win = 'self._%s_layout'%$id +#if not $label() + #set $label = '"%s"'%$id +#end if +######################################################################## +#if $widget() == "knob" +######################################################################## +$win = Qt.QVBoxLayout() +self._$(id)_knob = Qwt.QwtKnob() +self._$(id)_knob.setRange($start, $stop, $step) +self._$(id)_knob.setValue(self.$id) +self._$(id)_knob.valueChanged.connect(self.set_$(id)) +$(win).addWidget(self._$(id)_knob) +self._$(id)_label = Qt.QLabel($label) +self._$(id)_label.setAlignment(Qt.Qt.AlignTop | Qt.Qt.AlignHCenter) +$(win).addWidget(self._$(id)_label) +#end if +######################################################################## +#if $widget() == "thermo" +######################################################################## +$win = Qt.QVBoxLayout() +self._$(id)_label = Qt.QLabel($label) +self._$(id)_thermo = Qwt.QwtThermo() +self._$(id)_thermo.setScalePosition(Qwt.QwtThermo.$orient.scalepos) +self._$(id)_thermo.setRange($start, $stop) +self._$(id)_thermo.setValue(self.$id) +self._$(id)_thermo.$(orient.minfcn)($min_len) +#if 'horizontal' in $orient().lower() +self._$(id)_label.setAlignment(Qt.Qt.AlignBottom | Qt.Qt.AlignHCenter) +$(win).addWidget(self._$(id)_label) +$(win).addWidget(self._$(id)_thermo) +#elif 'vertical' in $orient().lower() +self._$(id)_label.setAlignment(Qt.Qt.AlignTop) +$(win).addWidget(self._$(id)_thermo) +$(win).addWidget(self._$(id)_label) +#end if +#end if +######################################################################## +#if $widget() == "counter" +######################################################################## +$win = Qt.QHBoxLayout() +$(win).addWidget(Qt.QLabel($label+": ")) +self._$(id)_counter = Qwt.QwtCounter() +self._$(id)_counter.setRange($start, $stop, $step) +self._$(id)_counter.setNumButtons(2) +self._$(id)_counter.setMinimumWidth($min_len) +self._$(id)_counter.setValue(self.$id) +$(win).addWidget(self._$(id)_counter) +self._$(id)_counter.valueChanged.connect(self.set_$(id)) +#end if +######################################################################## +#if $widget() == "slider" +######################################################################## +$win = Qt.QVBoxLayout() +self._$(id)_label = Qt.QLabel($label) +self._$(id)_slider = Qwt.QwtSlider(None, Qt.$orient, Qwt.QwtSlider.$orient.scalepos, Qwt.QwtSlider.BgSlot) +self._$(id)_slider.setRange($start, $stop, $step) +self._$(id)_slider.setValue(self.$id) +self._$(id)_slider.$(orient.minfcn)($min_len) +self._$(id)_slider.valueChanged.connect(self.set_$(id)) +#if 'horizontal' in $orient().lower() +self._$(id)_label.setAlignment(Qt.Qt.AlignBottom | Qt.Qt.AlignHCenter) +$(win).addWidget(self._$(id)_label) +$(win).addWidget(self._$(id)_slider) +#elif 'vertical' in $orient().lower() +self._$(id)_label.setAlignment(Qt.Qt.AlignTop) +$(win).addWidget(self._$(id)_slider) +$(win).addWidget(self._$(id)_label) +#end if +#end if +######################################################################## +#if $widget() == "counter_slider" +######################################################################## +$win = Qt.QVBoxLayout() +self._$(id)_tool_bar = Qt.QToolBar(self) +$(win).addWidget(self._$(id)_tool_bar) +self._$(id)_tool_bar.addWidget(Qt.QLabel($label+": ")) +self._$(id)_counter = Qwt.QwtCounter() +self._$(id)_counter.setRange($start, $stop, $step) +self._$(id)_counter.setNumButtons(2) +self._$(id)_counter.setValue(self.$id) +self._$(id)_tool_bar.addWidget(self._$(id)_counter) +self._$(id)_counter.valueChanged.connect(self.set_$(id)) +self._$(id)_slider = Qwt.QwtSlider(None, Qt.Qt.Horizontal, Qwt.QwtSlider.BottomScale, Qwt.QwtSlider.BgSlot) +self._$(id)_slider.setRange($start, $stop, $step) +self._$(id)_slider.setValue(self.$id) +self._$(id)_slider.setMinimumWidth($min_len) +self._$(id)_slider.valueChanged.connect(self.set_$(id)) +$(win).addWidget(self._$(id)_slider) +#end if +$(gui_hint()($win))</make> + <callback>self.set_$(id)($value)</callback> + <callback>#if $widget() == "knob" +self._$(id)_knob.setValue($id) +#end if +#if $widget() == "thermo" +self._$(id)_thermo.setValue($id) +#end if +#if $widget() == "counter" +self._$(id)_counter.setValue($id) +#end if +#if $widget() == "slider" +self._$(id)_slider.setValue($id) +#end if +#if $widget() == "counter_slider" +self._$(id)_counter.setValue($id) +self._$(id)_slider.setValue($id) +#end if</callback> + <param> + <name>Label</name> + <key>label</key> + <value></value> + <type>string</type> + <hide>#if $label() then 'none' else 'part'#</hide> + </param> + <param> + <name>Default Value</name> + <key>value</key> + <value>50</value> + <type>real</type> + </param> + <param> + <name>Start</name> + <key>start</key> + <value>0</value> + <type>real</type> + </param> + <param> + <name>Stop</name> + <key>stop</key> + <value>100</value> + <type>real</type> + </param> + <param> + <name>Step</name> + <key>step</key> + <value>1</value> + <type>real</type> + </param> + <param> + <name>Widget</name> + <key>widget</key> + <value>counter_slider</value> + <type>enum</type> + <hide>part</hide> + <option><name>Counter + Slider</name><key>counter_slider</key></option> + <option><name>Counter</name><key>counter</key></option> + <option><name>Slider</name><key>slider</key></option> + <option><name>Knob</name><key>knob</key></option> + <option><name>Thermo</name><key>thermo</key></option> + </param> + <param> + <name>Orientation</name> + <key>orient</key> + <value>Qt.Horizontal</value> + <type>enum</type> + <hide>#if $widget() in ("slider", "thermo") then 'part' else 'all'#</hide> + <option> + <name>Horizontal</name> + <key>Qt.Horizontal</key> + <opt>scalepos:BottomScale</opt> + <opt>minfcn:setMinimumWidth</opt> + </option> + <option> + <name>Vertical</name> + <key>Qt.Vertical</key> + <opt>scalepos:LeftScale</opt> + <opt>minfcn:setMinimumHeight</opt> + </option> + </param> + <param> + <name>Minimum Length</name> + <key>min_len</key> + <value>200</value> + <type>int</type> + <hide>#if $widget().split('_')[0] in ("slider", "counter", "thermo") then 'part' else 'all'#</hide> + </param> + <param> + <name>GUI Hint</name> + <key>gui_hint</key> + <value></value> + <type>gui_hint</type> + <hide>part</hide> + </param> + <check>$start <= $value <= $stop</check> + <check>$start < $stop</check> + <doc> +This block creates a variable with a slider. \ +Leave the label blank to use the variable id as the label. \ +The value must be a real number. \ +The value must be between the start and the stop. + +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/grc/qtgui_sink_x.xml b/gr-qtgui/grc/qtgui_sink_x.xml new file mode 100644 index 000000000..8c470a1a5 --- /dev/null +++ b/gr-qtgui/grc/qtgui_sink_x.xml @@ -0,0 +1,126 @@ +<?xml version="1.0"?> +<!-- +################################################### +##QT GUI Sink +################################################### + --> +<block> + <name>QT GUI Sink</name> + <key>qtgui_sink_x</key> + <category>QT GUI Widgets</category> + <import>from PyQt4 import Qt</import> + <import>from gnuradio.qtgui import qtgui</import> + <import>from gnuradio.gr import firdes</import> + <import>import sip</import> + <make>#set $win = 'self._%s_win'%$id +qtgui.$(type.fcn)( + $fftsize, \#fftsize + $wintype, \#wintype + $fc, \#fc + $bw, \#bw + $name, \#name + $plotfreq, \#plotfreq + $plotwaterfall, \#plotwaterfall + $plottime, \#plottime + $plotconst, \#plotconst +) +self._$(id)_win = sip.wrapinstance(self.$(id).pyqwidget(), Qt.QWidget) +$(gui_hint()($win))</make> + <callback>set_frequency_range($fc, $bw)</callback> + <param> + <name>Type</name> + <key>type</key> + <value>complex</value> + <type>enum</type> + <option><name>Complex</name><key>complex</key><opt>fcn:sink_c</opt></option> + <option><name>Float</name><key>float</key><opt>fcn:sink_f</opt></option> + </param> + <param> + <name>Name</name> + <key>name</key> + <value>QT GUI Plot</value> + <type>string</type> + </param> + <param> + <name>FFT Size</name> + <key>fftsize</key> + <value>1024</value> + <type>int</type> + </param> + <param> + <name>Window Type</name> + <key>wintype</key> + <value>firdes.WIN_BLACKMAN_hARRIS</value> + <type>int</type> + <hide>part</hide> + <option> + <name>Blackman-harris</name> + <key>firdes.WIN_BLACKMAN_hARRIS</key> + </option> + </param> + <param> + <name>Center Frequency (Hz)</name> + <key>fc</key> + <value>0</value> + <type>real</type> + </param> + <param> + <name>Bandwidth (Hz)</name> + <key>bw</key> + <value>samp_rate</value> + <type>real</type> + </param> + <param> + <name>Plot Frequency</name> + <key>plotfreq</key> + <value>True</value> + <type>bool</type> + <hide>part</hide> + <option><name>On</name><key>True</key></option> + <option><name>Off</name><key>False</key></option> + </param> + <param> + <name>Plot Waterfall</name> + <key>plotwaterfall</key> + <value>True</value> + <type>bool</type> + <hide>part</hide> + <option><name>On</name><key>True</key></option> + <option><name>Off</name><key>False</key></option> + </param> + <param> + <name>Plot Time</name> + <key>plottime</key> + <value>True</value> + <type>bool</type> + <hide>part</hide> + <option><name>On</name><key>True</key></option> + <option><name>Off</name><key>False</key></option> + </param> + <param> + <name>Plot Const</name> + <key>plotconst</key> + <value>True</value> + <type>bool</type> + <hide>part</hide> + <option><name>On</name><key>True</key></option> + <option><name>Off</name><key>False</key></option> + </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>$num_inputs</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/grc/qtgui_tab_widget.xml b/gr-qtgui/grc/qtgui_tab_widget.xml new file mode 100644 index 000000000..f90054109 --- /dev/null +++ b/gr-qtgui/grc/qtgui_tab_widget.xml @@ -0,0 +1,84 @@ +<?xml version="1.0"?> +<!-- +################################################### +##WX GUI Notebook +################################################### + --> +<block> + <name>QT GUI Tab Widget</name> + <key>qtgui_tab_widget</key> + <category>QT GUI Widgets</category> + <import>from PyQt4 import Qt</import> + <make>#set $win = 'self.%s'%$id +Qt.QTabWidget() +#set $all_labels = [$label0, $label1, $label2, $label3, $label4][:int($num_tabs())] +#for i, label in enumerate($all_labels) +self.$(id)_widget_$(i) = Qt.QWidget() +self.$(id)_layout_$(i) = Qt.QBoxLayout(Qt.QBoxLayout.TopToBottom, self.$(id)_widget_$(i)) +self.$(id)_grid_layout_$(i) = Qt.QGridLayout() +self.$(id)_layout_$(i).addLayout(self.$(id)_grid_layout_$(i)) +$(win).addTab(self.$(id)_widget_$(i), $label) +#end for +$(gui_hint()($win))</make> + <param> + <name>Num Tabs</name> + <key>num_tabs</key> + <value>1</value> + <type>enum</type> + <option><name>1</name><key>1</key></option> + <option><name>2</name><key>2</key></option> + <option><name>3</name><key>3</key></option> + <option><name>4</name><key>4</key></option> + <option><name>5</name><key>5</key></option> + </param> + <param> + <name>Label 0</name> + <key>label0</key> + <value>Tab 0</value> + <type>string</type> + <hide>#if int($num_tabs()) > 0 then 'none' else 'all'#</hide> + </param> + <param> + <name>Label 1</name> + <key>label1</key> + <value>Tab 1</value> + <type>string</type> + <hide>#if int($num_tabs()) > 1 then 'none' else 'all'#</hide> + </param> + <param> + <name>Label 2</name> + <key>label2</key> + <value>Tab 2</value> + <type>string</type> + <hide>#if int($num_tabs()) > 2 then 'none' else 'all'#</hide> + </param> + <param> + <name>Label 3</name> + <key>label3</key> + <value>Tab 3</value> + <type>string</type> + <hide>#if int($num_tabs()) > 3 then 'none' else 'all'#</hide> + </param> + <param> + <name>Label 4</name> + <key>label4</key> + <value>Tab 4</value> + <type>string</type> + <hide>#if int($num_tabs()) > 4 then 'none' else 'all'#</hide> + </param> + <param> + <name>GUI Hint</name> + <key>gui_hint</key> + <value></value> + <type>gui_hint</type> + <hide>part</hide> + </param> + <doc> +This block creates a tabbed widget to organize other widgets. \ +The ID of this block can be used as the tab_id in the GUI hints of other widgets. + +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/grc/qtgui_time_sink_x.xml b/gr-qtgui/grc/qtgui_time_sink_x.xml new file mode 100644 index 000000000..9c8da6fbc --- /dev/null +++ b/gr-qtgui/grc/qtgui_time_sink_x.xml @@ -0,0 +1,78 @@ +<?xml version="1.0"?> +<!-- +################################################### +##QT GUI Sink +################################################### + --> +<block> + <name>QT GUI Time Sink</name> + <key>qtgui_time_sink_x</key> + <category>QT GUI Widgets</category> + <import>from PyQt4 import Qt</import> + <import>from gnuradio.qtgui import qtgui</import> + <import>from gnuradio.gr import firdes</import> + <import>import sip</import> + <make>#set $win = 'self._%s_win'%$id +qtgui.$(type.fcn)( + $size, \#size + $bw, \#bw + $name, \#name + $nconnections \#number of inputs +) +self._$(id)_win = sip.wrapinstance(self.$(id).pyqwidget(), Qt.QWidget) +$(gui_hint()($win))</make> + <callback>set_time_domain_axis($min, $max)</callback> + <callback>set_update_time($t)</callback> + <callback>set_title($which, $title)</callback> + <callback>set_color($which, $color)</callback> + <param> + <name>Type</name> + <key>type</key> + <value>complex</value> + <type>enum</type> + <option><name>Complex</name><key>complex</key><opt>fcn:time_sink_c</opt></option> + <option><name>Float</name><key>float</key><opt>fcn:time_sink_f</opt></option> + </param> + <param> + <name>Name</name> + <key>name</key> + <value>QT GUI Plot</value> + <type>string</type> + </param> + <param> + <name>Number of Points</name> + <key>size</key> + <value>1024</value> + <type>int</type> + </param> + <param> + <name>Bandwidth (Hz)</name> + <key>bw</key> + <value>samp_rate</value> + <type>real</type> + </param> + <param> + <name>Number of Inputs</name> + <key>nconnections</key> + <value>1</value> + <type>int</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/src/lib/.gitignore b/gr-qtgui/lib/.gitignore index 11bb4342a..fc4f8cdfe 100644 --- a/gr-qtgui/src/lib/.gitignore +++ b/gr-qtgui/lib/.gitignore @@ -5,9 +5,11 @@ /qtgui.cc /qtgui.py /WaterfallDisplayPlot.moc.cc -/Waterfall3DDisplayPlot.moc.cc /TimeDomainDisplayPlot.moc.cc /spectrumdisplayform.moc.cc /spectrumdisplayform.ui.h /FrequencyDisplayPlot.moc.cc /ConstellationDisplayPlot.moc.cc +/gnuradio +/guile +/python diff --git a/gr-qtgui/src/lib/ConstellationDisplayPlot.cc b/gr-qtgui/lib/ConstellationDisplayPlot.cc index 9ad5bdd3c..7ec2db820 100644 --- a/gr-qtgui/src/lib/ConstellationDisplayPlot.cc +++ b/gr-qtgui/lib/ConstellationDisplayPlot.cc @@ -1,3 +1,25 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008,2009,2010,2011 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 CONSTELLATION_DISPLAY_PLOT_C #define CONSTELLATION_DISPLAY_PLOT_C @@ -5,7 +27,7 @@ #include <qwt_scale_draw.h> #include <qwt_legend.h> - +#include <iostream> class ConstellationDisplayZoomer: public QwtPlotZoomer { @@ -74,18 +96,12 @@ ConstellationDisplayPlot::ConstellationDisplayPlot(QWidget* parent) memset(_realDataPoints, 0x0, _numPoints*sizeof(double)); memset(_imagDataPoints, 0x0, _numPoints*sizeof(double)); - replot(); - _zoomer = new ConstellationDisplayZoomer(canvas()); -#if QT_VERSION < 0x040000 + _zoomer->setSelectionFlags(QwtPicker::RectSelection | QwtPicker::DragSelection); _zoomer->setMousePattern(QwtEventPattern::MouseSelect2, - Qt::RightButton, Qt::ControlModifier); -#else - _zoomer->setMousePattern(QwtEventPattern::MouseSelect2, - Qt::RightButton, Qt::ControlModifier); -#endif + Qt::RightButton, Qt::ControlModifier); _zoomer->setMousePattern(QwtEventPattern::MouseSelect3, - Qt::RightButton); + Qt::RightButton); _panner = new QwtPlotPanner(canvas()); _panner->setAxisEnabled(QwtPlot::yRight, false); @@ -102,8 +118,13 @@ ConstellationDisplayPlot::ConstellationDisplayPlot(QWidget* parent) _zoomer->setRubberBandPen(c); _zoomer->setTrackerPen(c); - connect(this, SIGNAL( legendChecked(QwtPlotItem *, bool ) ), - this, SLOT( LegendEntryChecked(QwtPlotItem *, bool ) )); + // emit the position of clicks on widget + _picker = new QwtDblClickPlotPicker(canvas()); + connect(_picker, SIGNAL(selected(const QwtDoublePoint &)), + this, SLOT(OnPickerPointSelected(const QwtDoublePoint &))); + + connect(this, SIGNAL(legendChecked(QwtPlotItem *, bool ) ), + this, SLOT(LegendEntryChecked(QwtPlotItem *, bool ) )); } ConstellationDisplayPlot::~ConstellationDisplayPlot() @@ -178,8 +199,6 @@ void ConstellationDisplayPlot::PlotNewData(const double* realDataPoints, memcpy(_realDataPoints, realDataPoints, numDataPoints*sizeof(double)); memcpy(_imagDataPoints, imagDataPoints, numDataPoints*sizeof(double)); - replot(); - _lastReplot = get_highres_clock(); } } @@ -190,4 +209,12 @@ ConstellationDisplayPlot::LegendEntryChecked(QwtPlotItem* plotItem, bool on) plotItem->setVisible(!on); } +void +ConstellationDisplayPlot::OnPickerPointSelected(const QwtDoublePoint & p) +{ + QPointF point = p; + //fprintf(stderr,"OnPickerPointSelected %f %f\n", point.x(), point.y()); + emit plotPointSelected(point); +} + #endif /* CONSTELLATION_DISPLAY_PLOT_C */ diff --git a/gr-qtgui/src/lib/ConstellationDisplayPlot.h b/gr-qtgui/lib/ConstellationDisplayPlot.h index a441a8bfe..3a85f3bc3 100644 --- a/gr-qtgui/src/lib/ConstellationDisplayPlot.h +++ b/gr-qtgui/lib/ConstellationDisplayPlot.h @@ -1,6 +1,29 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008,2009,2010,2011 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 CONSTELLATION_DISPLAY_PLOT_HPP #define CONSTELLATION_DISPLAY_PLOT_HPP +#include <stdint.h> #include <cstdio> #include <qwt_plot.h> #include <qwt_painter.h> @@ -13,6 +36,7 @@ #include <qwt_plot_marker.h> #include <highResTimeFunctions.h> #include <qwt_symbol.h> +#include <qtgui_util.h> class ConstellationDisplayPlot : public QwtPlot { @@ -38,6 +62,11 @@ public: public slots: void resizeSlot( QSize *s ); + void OnPickerPointSelected(const QwtDoublePoint & p); + +signals: + void plotPointSelected(const QPointF p); + protected slots: void LegendEntryChecked(QwtPlotItem *plotItem, bool on); @@ -49,6 +78,8 @@ private: QwtPlotPanner* _panner; QwtPlotZoomer* _zoomer; + QwtDblClickPlotPicker *_picker; + double* _realDataPoints; double* _imagDataPoints; diff --git a/gr-qtgui/src/lib/FrequencyDisplayPlot.cc b/gr-qtgui/lib/FrequencyDisplayPlot.cc index d150e2e4c..4d60cd9be 100644 --- a/gr-qtgui/src/lib/FrequencyDisplayPlot.cc +++ b/gr-qtgui/lib/FrequencyDisplayPlot.cc @@ -1,3 +1,25 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008,2009,2010,2011 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 FREQUENCY_DISPLAY_PLOT_C #define FREQUENCY_DISPLAY_PLOT_C @@ -148,7 +170,7 @@ FrequencyDisplayPlot::FrequencyDisplayPlot(QWidget* parent) _max_fft_plot_curve->setRawData(_xAxisPoints, _maxFFTPoints, _numPoints); _max_fft_plot_curve->setVisible(false); - _lower_intensity_marker = new QwtPlotMarker(); + _lower_intensity_marker= new QwtPlotMarker(); _lower_intensity_marker->setLineStyle(QwtPlotMarker::HLine); _lower_intensity_marker->setLinePen(QPen(Qt::cyan)); _lower_intensity_marker->attach(this); @@ -183,6 +205,12 @@ FrequencyDisplayPlot::FrequencyDisplayPlot(QWidget* parent) _markerNoiseFloorAmplitude->setLinePen(QPen(Qt::darkRed, 0, Qt::DotLine)); _markerNoiseFloorAmplitude->attach(this); + _markerCF= new QwtPlotMarker(); + _markerCF->setLineStyle(QwtPlotMarker::VLine); + _markerCF->setLinePen(QPen(Qt::lightGray, 0, Qt::DotLine)); + _markerCF->attach(this); + _markerCF->hide(); + _peakFrequency = 0; _peakAmplitude = -HUGE_VAL; @@ -190,14 +218,19 @@ FrequencyDisplayPlot::FrequencyDisplayPlot(QWidget* parent) replot(); + // emit the position of clicks on widget + _picker = new QwtDblClickPlotPicker(canvas()); + connect(_picker, SIGNAL(selected(const QwtDoublePoint &)), + this, SLOT(OnPickerPointSelected(const QwtDoublePoint &))); + + // Configure magnify on mouse wheel + _magnifier = new QwtPlotMagnifier(canvas()); + _magnifier->setAxisEnabled(QwtPlot::xBottom, false); + _zoomer = new FreqDisplayZoomer(canvas(), 0); -#if QT_VERSION < 0x040000 - _zoomer->setMousePattern(QwtEventPattern::MouseSelect2, - Qt::RightButton, Qt::ControlModifier); -#else + _zoomer->setSelectionFlags(QwtPicker::RectSelection | QwtPicker::DragSelection); _zoomer->setMousePattern(QwtEventPattern::MouseSelect2, Qt::RightButton, Qt::ControlModifier); -#endif _zoomer->setMousePattern(QwtEventPattern::MouseSelect3, Qt::RightButton); @@ -256,6 +289,7 @@ FrequencyDisplayPlot::SetFrequencyRange(const double constStartFreq, double stopFreq = constStopFreq / units; double centerFreq = constCenterFreq / units; + _xAxisMultiplier = units; _useCenterFrequencyFlag = useCenterFrequencyFlag; if(_useCenterFrequencyFlag){ @@ -367,8 +401,6 @@ FrequencyDisplayPlot::PlotNewData(const double* dataPoints, const int64_t numDat SetUpperIntensityLevel(_peakAmplitude); - replot(); - _lastReplot = get_highres_clock(); } } @@ -435,5 +467,36 @@ FrequencyDisplayPlot::SetUpperIntensityLevel(const double upperIntensityLevel) _upper_intensity_marker->setYValue( upperIntensityLevel ); } +void +FrequencyDisplayPlot::SetTraceColour (QColor c) +{ + _fft_plot_curve->setPen(QPen(c)); +} + +void +FrequencyDisplayPlot::SetBGColour (QColor c) +{ + QPalette palette; + palette.setColor(canvas()->backgroundRole(), c); + canvas()->setPalette(palette); +} + +void +FrequencyDisplayPlot::ShowCFMarker (const bool show) +{ + if (show) + _markerCF->show(); + else + _markerCF->hide(); +} + +void +FrequencyDisplayPlot::OnPickerPointSelected(const QwtDoublePoint & p) +{ + QPointF point = p; + //fprintf(stderr,"OnPickerPointSelected %f %f %d\n", point.x(), point.y(), _xAxisMultiplier); + point.setX(point.x() * _xAxisMultiplier); + emit plotPointSelected(point); +} #endif /* FREQUENCY_DISPLAY_PLOT_C */ diff --git a/gr-qtgui/src/lib/FrequencyDisplayPlot.h b/gr-qtgui/lib/FrequencyDisplayPlot.h index c78e1667e..6689703bc 100644 --- a/gr-qtgui/src/lib/FrequencyDisplayPlot.h +++ b/gr-qtgui/lib/FrequencyDisplayPlot.h @@ -1,6 +1,29 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008,2009,2010,2011 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 FREQUENCY_DISPLAY_PLOT_HPP #define FREQUENCY_DISPLAY_PLOT_HPP +#include <stdint.h> #include <cstdio> #include <qwt_plot.h> #include <qwt_painter.h> @@ -11,8 +34,10 @@ #include <qwt_plot_zoomer.h> #include <qwt_plot_panner.h> #include <qwt_plot_marker.h> +#include <qwt_plot_magnifier.h> #include <highResTimeFunctions.h> #include <qwt_symbol.h> +#include <qtgui_util.h> class FrequencyDisplayPlot:public QwtPlot{ Q_OBJECT @@ -42,11 +67,20 @@ public: void set_yaxis(double min, double max); + void SetTraceColour (QColor); + void SetBGColour (QColor c); + void ShowCFMarker (const bool); + public slots: void resizeSlot( QSize *e ); void SetLowerIntensityLevel(const double); void SetUpperIntensityLevel(const double); + void OnPickerPointSelected(const QwtDoublePoint & p); + +signals: + void plotPointSelected(const QPointF p); + protected: private: @@ -70,9 +104,14 @@ private: QwtPlotMarker *_markerPeakAmplitude; QwtPlotMarker *_markerNoiseFloorAmplitude; + QwtPlotMarker *_markerCF; + + QwtDblClickPlotPicker *_picker; + QwtPlotMagnifier *_magnifier; double* _dataPoints; double* _xAxisPoints; + int _xAxisMultiplier; double* _minFFTPoints; double* _maxFFTPoints; diff --git a/gr-qtgui/src/lib/Makefile.am b/gr-qtgui/lib/Makefile.am index 1ee3c8e3d..95b636d89 100644 --- a/gr-qtgui/src/lib/Makefile.am +++ b/gr-qtgui/lib/Makefile.am @@ -1,5 +1,5 @@ # -# Copyright 2008,2009,2010 Free Software Foundation, Inc. +# Copyright 2008-2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -21,22 +21,24 @@ include $(top_srcdir)/Makefile.common +EXTRA_DIST += spectrumdisplayform.ui + AM_CPPFLAGS = -I. $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) \ - $(QT_INCLUDES) $(WITH_INCLUDES) + $(QT_INCLUDES) $(BOOST_CPPFLAGS) $(WITH_INCLUDES) \ + -Dlibgnuradio_qtgui_EXPORTS # Only include these files in the build if qtgui passes configure checks # This is mostly to help make distcheck pass QMAKE_SOURCES = \ spectrumdisplayform.moc.cc \ + timedisplayform.moc.cc \ FrequencyDisplayPlot.moc.cc \ TimeDomainDisplayPlot.moc.cc \ WaterfallDisplayPlot.moc.cc \ ConstellationDisplayPlot.moc.cc \ spectrumdisplayform.ui.h -EXTRA_DIST = spectrumdisplayform.ui - -BUILT_SOURCES = $(QMAKE_SOURCES) +BUILT_SOURCES += $(QMAKE_SOURCES) # Build the normal library for C++ apps to link against lib_LTLIBRARIES = libgnuradio-qtgui.la @@ -49,13 +51,17 @@ libgnuradio_qtgui_la_SOURCES = \ waterfallGlobalData.cc \ ConstellationDisplayPlot.cc \ spectrumdisplayform.cc \ + timedisplayform.cc \ SpectrumGUIClass.cc \ spectrumUpdateEvents.cc \ plot_waterfall.cc \ qtgui_sink_c.cc \ - qtgui_sink_f.cc + qtgui_sink_f.cc \ + qtgui_time_sink_c.cc \ + qtgui_time_sink_f.cc \ + qtgui_util.cc -nodist_libgnuradio_qtgui_la_SOURCES=$(BUILT_SOURCES) +nodist_libgnuradio_qtgui_la_SOURCES=$(QMAKE_SOURCES) # These headers get installed in ${prefix}/include/gnuradio grinclude_HEADERS = \ @@ -67,13 +73,18 @@ grinclude_HEADERS = \ highResTimeFunctions.h \ plot_waterfall.h \ spectrumdisplayform.h \ + timedisplayform.h \ SpectrumGUIClass.h \ spectrumUpdateEvents.h \ - qtgui.h \ + gr_qtgui_api.h \ qtgui_sink_c.h \ - qtgui_sink_f.h + qtgui_sink_f.h \ + qtgui_time_sink_c.h \ + qtgui_time_sink_f.h \ + qtgui_util.h -QT_MOC_FLAGS=-DQT_SHARED -DQT_NO_DEBUG -DQT_OPENGL_LIB -DQT_GUI_LIB -DQT_CORE_LIB +#QT_MOC_FLAGS=-DQT_SHARED -DQT_NO_DEBUG -DQT_OPENGL_LIB -DQT_GUI_LIB -DQT_CORE_LIB +QT_MOC_FLAGS=-DQT_SHARED -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB %.moc.cc : %.h $(QT_MOC_EXEC) $(QT_MOC_FLAGS) -p $(srcdir) $< -o $@ @@ -81,38 +92,11 @@ QT_MOC_FLAGS=-DQT_SHARED -DQT_NO_DEBUG -DQT_OPENGL_LIB -DQT_GUI_LIB -DQT_CORE_LI $(QT_UIC_EXEC) $< -o $@ # magic flags -libgnuradio_qtgui_la_LDFLAGS = $(NO_UNDEFINED) $(LTVERSIONFLAGS) +libgnuradio_qtgui_la_LDFLAGS = $(NO_UNDEFINED) $(BOOST_LDFLAGS) $(LTVERSIONFLAGS) libgnuradio_qtgui_la_LIBADD = \ - $(GNURADIO_CORE_LA) \ - -lstdc++ \ + $(GNURADIO_CORE_LA) \ + $(BOOST_THREAD_LIB) \ + $(BOOST_DATE_TIME_LIB) \ + -lstdc++ \ $(QT_LIBS) - -if PYTHON -############################## -# SWIG interface and library - -TOP_SWIG_IFILES = \ - qtgui.i - -# Install so that they end up available as: -# import gnuradio.qtgui -# This ends up at: -# ${prefix}/lib/python${python_version}/site-packages/gnuradio -qtgui_pythondir_category = \ - gnuradio/qtgui - -# additional libraries for linking with the SWIG-generated library -qtgui_la_swig_libadd = \ - libgnuradio-qtgui.la - -include $(top_srcdir)/Makefile.swig - -# add some of the variables generated inside the Makefile.swig.gen -BUILT_SOURCES += \ - $(swig_built_sources) -endif - -# Do not distribute built sources, they may contain generated paths -# which are invalid on other systems -no_dist_files = $(BUILT_SOURCES) diff --git a/gr-qtgui/src/lib/SpectrumGUIClass.cc b/gr-qtgui/lib/SpectrumGUIClass.cc index 563ed34ba..b472470c6 100644 --- a/gr-qtgui/src/lib/SpectrumGUIClass.cc +++ b/gr-qtgui/lib/SpectrumGUIClass.cc @@ -1,3 +1,25 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008,2009,2010,2011 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 SPECTRUM_GUI_CLASS_CPP #define SPECTRUM_GUI_CLASS_CPP @@ -6,8 +28,8 @@ #include <QEvent> #include <QCustomEvent> -const long SpectrumGUIClass::MAX_FFT_SIZE; -const long SpectrumGUIClass::MIN_FFT_SIZE; +const long SpectrumGUIClass::MAX_FFT_SIZE = 32768; +const long SpectrumGUIClass::MIN_FFT_SIZE = 1024; SpectrumGUIClass::SpectrumGUIClass(const uint64_t maxDataSize, const uint64_t fftSize, @@ -37,34 +59,31 @@ SpectrumGUIClass::SpectrumGUIClass(const uint64_t maxDataSize, _windowOpennedFlag = false; _fftBuffersCreatedFlag = false; - // Create Mutex Lock - //_windowStateLock = new MutexClass("_windowStateLock"); - _powerValue = 1; } SpectrumGUIClass::~SpectrumGUIClass() { - if(GetWindowOpenFlag()){ - delete _spectrumDisplayForm; - } + // We don't need to delete this since as a QWidget, it is supposed to be destroyed + // with it's parent. Deleting it causes a segmentation fault, and not deleting it + // does not leave any extra memory. + //if(GetWindowOpenFlag()){ + //delete _spectrumDisplayForm; + //} if(_fftBuffersCreatedFlag){ delete[] _fftPoints; delete[] _realTimeDomainPoints; delete[] _imagTimeDomainPoints; } - - //delete _windowStateLock; } void SpectrumGUIClass::OpenSpectrumWindow(QWidget* parent, const bool frequency, const bool waterfall, - const bool time, const bool constellation, - const bool use_openGL) + const bool time, const bool constellation) { - //_windowStateLock->Lock(); + d_mutex.lock(); if(!_windowOpennedFlag){ @@ -81,7 +100,7 @@ SpectrumGUIClass::OpenSpectrumWindow(QWidget* parent, } // Called from the Event Thread - _spectrumDisplayForm = new SpectrumDisplayForm(use_openGL, parent); + _spectrumDisplayForm = new SpectrumDisplayForm(parent); // Toggle Windows on/off _spectrumDisplayForm->ToggleTabFrequency(frequency); @@ -95,8 +114,8 @@ SpectrumGUIClass::OpenSpectrumWindow(QWidget* parent, qApp->processEvents(); } + d_mutex.unlock(); - //_windowStateLock->Unlock(); SetDisplayTitle(_title); Reset(); @@ -104,8 +123,6 @@ SpectrumGUIClass::OpenSpectrumWindow(QWidget* parent, qApp->postEvent(_spectrumDisplayForm, new QEvent(QEvent::Type(QEvent::User+3))); - qApp->processEvents(); - timespec_reset(&_lastGUIUpdateTime); // Draw Blank Display @@ -147,10 +164,9 @@ SpectrumGUIClass::SetDisplayTitle(const std::string newString) bool SpectrumGUIClass::GetWindowOpenFlag() { + gruel::scoped_lock lock(d_mutex); bool returnFlag = false; - //_windowStateLock->Lock(); returnFlag = _windowOpennedFlag; - //_windowStateLock->Unlock(); return returnFlag; } @@ -158,9 +174,8 @@ SpectrumGUIClass::GetWindowOpenFlag() void SpectrumGUIClass::SetWindowOpenFlag(const bool newFlag) { - //_windowStateLock->Lock(); + gruel::scoped_lock lock(d_mutex); _windowOpennedFlag = newFlag; - //_windowStateLock->Unlock(); } void @@ -168,7 +183,7 @@ SpectrumGUIClass::SetFrequencyRange(const double centerFreq, const double startFreq, const double stopFreq) { - //_windowStateLock->Lock(); + gruel::scoped_lock lock(d_mutex); _centerFrequency = centerFreq; _startFrequency = startFreq; _stopFrequency = stopFreq; @@ -176,36 +191,32 @@ SpectrumGUIClass::SetFrequencyRange(const double centerFreq, _spectrumDisplayForm->SetFrequencyRange(_centerFrequency, _startFrequency, _stopFrequency); - //_windowStateLock->Unlock(); } double -SpectrumGUIClass::GetStartFrequency() const +SpectrumGUIClass::GetStartFrequency() { + gruel::scoped_lock lock(d_mutex); double returnValue = 0.0; - //_windowStateLock->Lock(); returnValue = _startFrequency; - //_windowStateLock->Unlock(); return returnValue; } double -SpectrumGUIClass::GetStopFrequency() const +SpectrumGUIClass::GetStopFrequency() { + gruel::scoped_lock lock(d_mutex); double returnValue = 0.0; - //_windowStateLock->Lock(); returnValue = _stopFrequency; - //_windowStateLock->Unlock(); return returnValue; } double -SpectrumGUIClass::GetCenterFrequency() const +SpectrumGUIClass::GetCenterFrequency() { + gruel::scoped_lock lock(d_mutex); double returnValue = 0.0; - //_windowStateLock->Lock(); returnValue = _centerFrequency; - //_windowStateLock->Unlock(); return returnValue; } @@ -221,6 +232,7 @@ SpectrumGUIClass::UpdateWindow(const bool updateDisplayFlag, const timespec timestamp, const bool lastOfMultipleFFTUpdateFlag) { + //gruel::scoped_lock lock(d_mutex); int64_t bufferSize = inputBufferSize; bool repeatDataFlag = false; if(bufferSize > _dataPoints){ @@ -302,54 +314,49 @@ SpectrumGUIClass::UpdateWindow(const bool updateDisplayFlag, } float -SpectrumGUIClass::GetPowerValue() const +SpectrumGUIClass::GetPowerValue() { + gruel::scoped_lock lock(d_mutex); float returnValue = 0; - //_windowStateLock->Lock(); returnValue = _powerValue; - //_windowStateLock->Unlock(); return returnValue; } void SpectrumGUIClass::SetPowerValue(const float value) { - //_windowStateLock->Lock(); + gruel::scoped_lock lock(d_mutex); _powerValue = value; - //_windowStateLock->Unlock(); } int -SpectrumGUIClass::GetWindowType() const +SpectrumGUIClass::GetWindowType() { + gruel::scoped_lock lock(d_mutex); int returnValue = 0; - //_windowStateLock->Lock(); returnValue = _windowType; - //_windowStateLock->Unlock(); return returnValue; } void SpectrumGUIClass::SetWindowType(const int newType) { - //_windowStateLock->Lock(); + gruel::scoped_lock lock(d_mutex); _windowType = newType; - //_windowStateLock->Unlock(); } int -SpectrumGUIClass::GetFFTSize() const +SpectrumGUIClass::GetFFTSize() { int returnValue = 0; - //_windowStateLock->Lock(); returnValue = _fftSize; - //_windowStateLock->Unlock(); return returnValue; } int -SpectrumGUIClass::GetFFTSizeIndex() const +SpectrumGUIClass::GetFFTSizeIndex() { + gruel::scoped_lock lock(d_mutex); int fftsize = GetFFTSize(); switch(fftsize) { case(1024): return 0; break; @@ -365,75 +372,70 @@ SpectrumGUIClass::GetFFTSizeIndex() const void SpectrumGUIClass::SetFFTSize(const int newSize) { - //_windowStateLock->Lock(); + gruel::scoped_lock lock(d_mutex); _fftSize = newSize; - //_windowStateLock->Unlock(); } timespec -SpectrumGUIClass::GetLastGUIUpdateTime() const +SpectrumGUIClass::GetLastGUIUpdateTime() { + gruel::scoped_lock lock(d_mutex); timespec returnValue; - //_windowStateLock->Lock(); returnValue = _lastGUIUpdateTime; - //_windowStateLock->Unlock(); return returnValue; } void SpectrumGUIClass::SetLastGUIUpdateTime(const timespec newTime) { - //_windowStateLock->Lock(); + gruel::scoped_lock lock(d_mutex); _lastGUIUpdateTime = newTime; - //_windowStateLock->Unlock(); } unsigned int -SpectrumGUIClass::GetPendingGUIUpdateEvents() const +SpectrumGUIClass::GetPendingGUIUpdateEvents() { + gruel::scoped_lock lock(d_mutex); unsigned int returnValue = 0; - //_windowStateLock->Lock(); returnValue = _pendingGUIUpdateEventsCount; - //_windowStateLock->Unlock(); return returnValue; } void SpectrumGUIClass::IncrementPendingGUIUpdateEvents() { - //_windowStateLock->Lock(); + gruel::scoped_lock lock(d_mutex); _pendingGUIUpdateEventsCount++; - //_windowStateLock->Unlock(); } void SpectrumGUIClass::DecrementPendingGUIUpdateEvents() { - //_windowStateLock->Lock(); + gruel::scoped_lock lock(d_mutex); if(_pendingGUIUpdateEventsCount > 0){ _pendingGUIUpdateEventsCount--; } - //_windowStateLock->Unlock(); } void SpectrumGUIClass::ResetPendingGUIUpdateEvents() { - //_windowStateLock->Lock(); + gruel::scoped_lock lock(d_mutex); _pendingGUIUpdateEventsCount = 0; - //_windowStateLock->Unlock(); } QWidget* SpectrumGUIClass::qwidget() { + gruel::scoped_lock lock(d_mutex); return (QWidget*)_spectrumDisplayForm; } void SpectrumGUIClass::SetTimeDomainAxis(double min, double max) { + gruel::scoped_lock lock(d_mutex); _spectrumDisplayForm->SetTimeDomainAxis(min, max); } @@ -441,12 +443,14 @@ void SpectrumGUIClass::SetConstellationAxis(double xmin, double xmax, double ymin, double ymax) { + gruel::scoped_lock lock(d_mutex); _spectrumDisplayForm->SetConstellationAxis(xmin, xmax, ymin, ymax); - } void -SpectrumGUIClass::SetConstellationPenSize(int size){ +SpectrumGUIClass::SetConstellationPenSize(int size) +{ + gruel::scoped_lock lock(d_mutex); _spectrumDisplayForm->SetConstellationPenSize(size); } @@ -454,12 +458,14 @@ SpectrumGUIClass::SetConstellationPenSize(int size){ void SpectrumGUIClass::SetFrequencyAxis(double min, double max) { + gruel::scoped_lock lock(d_mutex); _spectrumDisplayForm->SetFrequencyAxis(min, max); } void SpectrumGUIClass::SetUpdateTime(double t) { + gruel::scoped_lock lock(d_mutex); _updateTime = t; _spectrumDisplayForm->SetUpdateTime(_updateTime); } diff --git a/gr-qtgui/src/lib/SpectrumGUIClass.h b/gr-qtgui/lib/SpectrumGUIClass.h index 63a340c34..ad06674f5 100644 --- a/gr-qtgui/src/lib/SpectrumGUIClass.h +++ b/gr-qtgui/lib/SpectrumGUIClass.h @@ -1,15 +1,35 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008,2009,2010,2011 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 SPECTRUM_GUI_CLASS_HPP #define SPECTRUM_GUI_CLASS_HPP -//#include <mutexClass.hpp> +#include <gruel/thread.h> #include <qwidget.h> #include <qapplication.h> #include <qlabel.h> #include <qslider.h> #include <spectrumUpdateEvents.h> -//#include <Windowing.hpp> - class SpectrumDisplayForm; #include <spectrumdisplayform.h> @@ -31,17 +51,16 @@ public: void OpenSpectrumWindow(QWidget*, const bool frequency=true, const bool waterfall=true, - const bool time=true, const bool constellation=true, - const bool use_openGL=true); + const bool time=true, const bool constellation=true); void SetDisplayTitle(const std::string); bool GetWindowOpenFlag(); void SetWindowOpenFlag(const bool); void SetFrequencyRange(const double, const double, const double); - double GetStartFrequency()const; - double GetStopFrequency()const; - double GetCenterFrequency()const; + double GetStartFrequency(); + double GetStopFrequency(); + double GetCenterFrequency(); void UpdateWindow(const bool, const std::complex<float>*, const uint64_t, const float*, @@ -49,26 +68,26 @@ public: const uint64_t, const timespec, const bool); - float GetPowerValue()const; + float GetPowerValue(); void SetPowerValue(const float); - int GetWindowType()const; + int GetWindowType(); void SetWindowType(const int); - int GetFFTSize()const; - int GetFFTSizeIndex()const; + int GetFFTSize(); + int GetFFTSizeIndex(); void SetFFTSize(const int); - timespec GetLastGUIUpdateTime()const; + timespec GetLastGUIUpdateTime(); void SetLastGUIUpdateTime(const timespec); - unsigned int GetPendingGUIUpdateEvents()const; + unsigned int GetPendingGUIUpdateEvents(); void IncrementPendingGUIUpdateEvents(); void DecrementPendingGUIUpdateEvents(); void ResetPendingGUIUpdateEvents(); - static const long MAX_FFT_SIZE = /*1048576*/32768; - static const long MIN_FFT_SIZE = 1024; + static const long MAX_FFT_SIZE; + static const long MIN_FFT_SIZE; QWidget* qwidget(); @@ -84,7 +103,7 @@ protected: private: - //MutexClass* _windowStateLock; + gruel::mutex d_mutex; int64_t _dataPoints; std::string _title; double _centerFrequency; diff --git a/gr-qtgui/src/lib/TimeDomainDisplayPlot.cc b/gr-qtgui/lib/TimeDomainDisplayPlot.cc index 9c98cec5b..f635a2b0c 100644 --- a/gr-qtgui/src/lib/TimeDomainDisplayPlot.cc +++ b/gr-qtgui/lib/TimeDomainDisplayPlot.cc @@ -1,3 +1,25 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008,2009,2010,2011 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 TIME_DOMAIN_DISPLAY_PLOT_C #define TIME_DOMAIN_DISPLAY_PLOT_C @@ -5,7 +27,8 @@ #include <qwt_scale_draw.h> #include <qwt_legend.h> - +#include <QColor> +#include <iostream> class TimePrecisionClass { @@ -70,18 +93,17 @@ private: std::string _unitType; }; -TimeDomainDisplayPlot::TimeDomainDisplayPlot(QWidget* parent):QwtPlot(parent) +TimeDomainDisplayPlot::TimeDomainDisplayPlot(int nplots, QWidget* parent) + : QwtPlot(parent), _nplots(nplots) { - timespec_reset(&_lastReplot); - resize(parent->width(), parent->height()); _numPoints = 1024; - _realDataPoints = new double[_numPoints]; - _imagDataPoints = new double[_numPoints]; _xAxisPoints = new double[_numPoints]; + memset(_xAxisPoints, 0x0, _numPoints*sizeof(double)); _zoomer = new TimeDomainDisplayZoomer(canvas(), 0); + _zoomer->setSelectionFlags(QwtPicker::RectSelection | QwtPicker::DragSelection); // Disable polygon clipping QwtPainter::setDeviceClipping(false); @@ -95,48 +117,54 @@ TimeDomainDisplayPlot::TimeDomainDisplayPlot(QWidget* parent):QwtPlot(parent) canvas()->setPalette(palette); setAxisScaleEngine(QwtPlot::xBottom, new QwtLinearScaleEngine); - set_xaxis(0, _numPoints); + setXaxis(0, _numPoints); setAxisTitle(QwtPlot::xBottom, "Time (sec)"); setAxisScaleEngine(QwtPlot::yLeft, new QwtLinearScaleEngine); - set_yaxis(-2.0, 2.0); - setAxisTitle(QwtPlot::yLeft, "Normalized Voltage"); + setYaxis(-2.0, 2.0); + setAxisTitle(QwtPlot::yLeft, "Amplitude"); + + QList<QColor> colors; + colors << QColor(Qt::blue) << QColor(Qt::red) << QColor(Qt::green) + << QColor(Qt::black) << QColor(Qt::cyan) << QColor(Qt::magenta) + << QColor(Qt::yellow) << QColor(Qt::gray) << QColor(Qt::darkRed) + << QColor(Qt::darkGreen) << QColor(Qt::darkBlue) << QColor(Qt::darkGray); + int ncolors = colors.size(); + + // Setup dataPoints and plot vectors // Automatically deleted when parent is deleted - _real_plot_curve = new QwtPlotCurve("Real Data"); - _real_plot_curve->attach(this); - _real_plot_curve->setPen(QPen(Qt::blue)); - _real_plot_curve->setRawData(_xAxisPoints, _realDataPoints, _numPoints); - - _imag_plot_curve = new QwtPlotCurve("Imaginary Data"); - _imag_plot_curve->attach(this); - _imag_plot_curve->setPen(QPen(Qt::magenta)); - _imag_plot_curve->setRawData(_xAxisPoints, _imagDataPoints, _numPoints); - // _imag_plot_curve->setVisible(false); - - memset(_realDataPoints, 0x0, _numPoints*sizeof(double)); - memset(_imagDataPoints, 0x0, _numPoints*sizeof(double)); - memset(_xAxisPoints, 0x0, _numPoints*sizeof(double)); + for(int i = 0; i < _nplots; i++) { + _dataPoints.push_back(new double[_numPoints]); + memset(_dataPoints[i], 0x0, _numPoints*sizeof(double)); + + _plot_curve.push_back(new QwtPlotCurve(QString("Data %1").arg(i))); + _plot_curve[i]->attach(this); + _plot_curve[i]->setPen(QPen(colors[i])); + _plot_curve[i]->setRawData(_xAxisPoints, _dataPoints[i], _numPoints); + } _sampleRate = 1; _resetXAxisPoints(); - replot(); - -#if QT_VERSION < 0x040000 _zoomer->setMousePattern(QwtEventPattern::MouseSelect2, - Qt::RightButton, Qt::ControlModifier); -#else - _zoomer->setMousePattern(QwtEventPattern::MouseSelect2, - Qt::RightButton, Qt::ControlModifier); -#endif + Qt::RightButton, Qt::ControlModifier); _zoomer->setMousePattern(QwtEventPattern::MouseSelect3, - Qt::RightButton); + Qt::RightButton); _panner = new QwtPlotPanner(canvas()); _panner->setAxisEnabled(QwtPlot::yRight, false); _panner->setMouseButton(Qt::MidButton); + // emit the position of clicks on widget + _picker = new QwtDblClickPlotPicker(canvas()); + connect(_picker, SIGNAL(selected(const QwtDoublePoint &)), + this, SLOT(OnPickerPointSelected(const QwtDoublePoint &))); + + // Configure magnify on mouse wheel + _magnifier = new QwtPlotMagnifier(canvas()); + _magnifier->setAxisEnabled(QwtPlot::xBottom, false); + // Avoid jumping when labels with more/less digits // appear/disappear when scrolling vertically @@ -156,29 +184,40 @@ TimeDomainDisplayPlot::TimeDomainDisplayPlot(QWidget* parent):QwtPlot(parent) this, SLOT( LegendEntryChecked(QwtPlotItem *, bool ) )); } -TimeDomainDisplayPlot::~TimeDomainDisplayPlot(){ - delete[] _realDataPoints; - delete[] _imagDataPoints; +TimeDomainDisplayPlot::~TimeDomainDisplayPlot() +{ + for(int i = 0; i < _nplots; i++) + delete [] _dataPoints[i]; delete[] _xAxisPoints; - // _fft_plot_curves deleted when parent deleted // _zoomer and _panner deleted when parent deleted } void -TimeDomainDisplayPlot::set_yaxis(double min, double max) +TimeDomainDisplayPlot::setYaxis(double min, double max) { setAxisScale(QwtPlot::yLeft, min, max); _zoomer->setZoomBase(); } void -TimeDomainDisplayPlot::set_xaxis(double min, double max) +TimeDomainDisplayPlot::setXaxis(double min, double max) { setAxisScale(QwtPlot::xBottom, min, max); _zoomer->setZoomBase(); } +void +TimeDomainDisplayPlot::setTitle(int which, QString title) +{ + _plot_curve[which]->setTitle(title); +} + +void +TimeDomainDisplayPlot::setColor(int which, QString color) +{ + _plot_curve[which]->setPen(QPen(color)); +} void TimeDomainDisplayPlot::replot() { @@ -188,49 +227,37 @@ void TimeDomainDisplayPlot::replot() void TimeDomainDisplayPlot::resizeSlot( QSize *s ) { - resize(s->width(), s->height()); + // -10 is to spare some room for the legend and x-axis label + resize(s->width()-10, s->height()-10); } -void TimeDomainDisplayPlot::PlotNewData(const double* realDataPoints, - const double* imagDataPoints, +void TimeDomainDisplayPlot::PlotNewData(const std::vector<double*> dataPoints, const int64_t numDataPoints, const double timeInterval) { - if((numDataPoints > 0) && - (diff_timespec(get_highres_clock(), _lastReplot) > timeInterval)) { - + if((numDataPoints > 0)) { if(numDataPoints != _numPoints){ _numPoints = numDataPoints; - delete[] _realDataPoints; - delete[] _imagDataPoints; delete[] _xAxisPoints; - _realDataPoints = new double[_numPoints]; - _imagDataPoints = new double[_numPoints]; _xAxisPoints = new double[_numPoints]; - - _real_plot_curve->setRawData(_xAxisPoints, _realDataPoints, _numPoints); - _imag_plot_curve->setRawData(_xAxisPoints, _imagDataPoints, _numPoints); - - set_xaxis(0, numDataPoints); + for(int i = 0; i < _nplots; i++) { + delete[] _dataPoints[i]; + _dataPoints[i] = new double[_numPoints]; + _plot_curve[i]->setRawData(_xAxisPoints, _dataPoints[i], _numPoints); + } + + setXaxis(0, numDataPoints); _resetXAxisPoints(); } - memcpy(_realDataPoints, realDataPoints, numDataPoints*sizeof(double)); - memcpy(_imagDataPoints, imagDataPoints, numDataPoints*sizeof(double)); - - replot(); - - _lastReplot = get_highres_clock(); + for(int i = 0; i < _nplots; i++) { + memcpy(_dataPoints[i], dataPoints[i], numDataPoints*sizeof(double)); + } } } -void TimeDomainDisplayPlot::SetImaginaryDataVisible(const bool visibleFlag) -{ - _imag_plot_curve->setVisible(visibleFlag); -} - void TimeDomainDisplayPlot::_resetXAxisPoints() { double delt = 1.0/_sampleRate; @@ -273,4 +300,12 @@ TimeDomainDisplayPlot::SetSampleRate(double sr, double units, } } +void +TimeDomainDisplayPlot::OnPickerPointSelected(const QwtDoublePoint & p) +{ + QPointF point = p; + //fprintf(stderr,"OnPickerPointSelected %f %f\n", point.x(), point.y()); + emit plotPointSelected(point); +} + #endif /* TIME_DOMAIN_DISPLAY_PLOT_C */ diff --git a/gr-qtgui/lib/TimeDomainDisplayPlot.h b/gr-qtgui/lib/TimeDomainDisplayPlot.h new file mode 100644 index 000000000..4c7b1e319 --- /dev/null +++ b/gr-qtgui/lib/TimeDomainDisplayPlot.h @@ -0,0 +1,95 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008,2009,2010,2011 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 TIME_DOMAIN_DISPLAY_PLOT_HPP +#define TIME_DOMAIN_DISPLAY_PLOT_HPP + +#include <stdint.h> +#include <cstdio> +#include <vector> +#include <qwt_plot.h> +#include <qwt_painter.h> +#include <qwt_plot_canvas.h> +#include <qwt_plot_curve.h> +#include <qwt_scale_engine.h> +#include <qwt_scale_widget.h> +#include <qwt_plot_zoomer.h> +#include <qwt_plot_panner.h> +#include <qwt_plot_magnifier.h> +#include <qwt_plot_marker.h> +#include <highResTimeFunctions.h> +#include <qwt_symbol.h> +#include <qtgui_util.h> + +class TimeDomainDisplayPlot:public QwtPlot{ + Q_OBJECT + +public: + TimeDomainDisplayPlot(int nplots, QWidget*); + virtual ~TimeDomainDisplayPlot(); + + void PlotNewData(const std::vector<double*> dataPoints, + const int64_t numDataPoints, const double timeInterval); + + virtual void replot(); + +public slots: + void setYaxis(double min, double max); + void setXaxis(double min, double max); + void setTitle(int which, QString title); + void setColor(int which, QString color); + + void resizeSlot( QSize *s ); + void SetSampleRate(double sr, double units, + const std::string &strunits); + + void OnPickerPointSelected(const QwtDoublePoint & p); + +signals: + void plotPointSelected(const QPointF p); + +protected slots: + void LegendEntryChecked(QwtPlotItem *plotItem, bool on); + +protected: + +private: + void _resetXAxisPoints(); + + int _nplots; + std::vector<QwtPlotCurve*> _plot_curve; + + QwtPlotPanner* _panner; + QwtPlotZoomer* _zoomer; + + QwtDblClickPlotPicker *_picker; + QwtPlotMagnifier *_magnifier; + + std::vector<double*> _dataPoints; + double* _xAxisPoints; + + double _sampleRate; + + int64_t _numPoints; +}; + +#endif /* TIME_DOMAIN_DISPLAY_PLOT_HPP */ diff --git a/gr-qtgui/src/lib/WaterfallDisplayPlot.cc b/gr-qtgui/lib/WaterfallDisplayPlot.cc index 680c44756..52381a9f6 100644 --- a/gr-qtgui/src/lib/WaterfallDisplayPlot.cc +++ b/gr-qtgui/lib/WaterfallDisplayPlot.cc @@ -1,3 +1,25 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008,2009,2010,2011 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 WATERFALL_DISPLAY_PLOT_C #define WATERFALL_DISPLAY_PLOT_C @@ -12,6 +34,9 @@ #include <qapplication.h> +#include <boost/date_time/posix_time/posix_time.hpp> +namespace pt = boost::posix_time; + class FreqOffsetAndPrecisionClass { public: @@ -135,16 +160,14 @@ public: virtual QwtText label(double value) const { - QwtText returnLabel(""); - timespec lineTime = timespec_add(GetZeroTime(), (-value) * GetSecondsPerLine()); - struct tm timeTm; - gmtime_r(&lineTime.tv_sec, &timeTm); - returnLabel = (QString("").sprintf("%04d/%02d/%02d\n%02d:%02d:%02d.%03ld", - timeTm.tm_year+1900, timeTm.tm_mon+1, - timeTm.tm_mday, timeTm.tm_hour, timeTm.tm_min, - timeTm.tm_sec, lineTime.tv_nsec/1000000)); - return returnLabel; + std::string time_str = pt::to_simple_string(pt::from_time_t(lineTime.tv_sec)); + + // lops off the YYYY-mmm-DD part of the string + size_t ind = time_str.find(" "); + if(ind != std::string::npos) + time_str = time_str.substr(ind); + return QwtText(QString("").sprintf("%s.%03ld", time_str.c_str(), lineTime.tv_nsec/1000000)); } virtual void initiateUpdate() @@ -189,15 +212,14 @@ protected: using QwtPlotZoomer::trackerText; virtual QwtText trackerText( const QwtDoublePoint& p ) const { - QString yLabel(""); - timespec lineTime = timespec_add(GetZeroTime(), (-p.y()) * GetSecondsPerLine()); - struct tm timeTm; - gmtime_r(&lineTime.tv_sec, &timeTm); - yLabel = (QString("").sprintf("%04d/%02d/%02d %02d:%02d:%02d.%03ld", - timeTm.tm_year+1900, timeTm.tm_mon+1, - timeTm.tm_mday, timeTm.tm_hour, timeTm.tm_min, - timeTm.tm_sec, lineTime.tv_nsec/1000000)); + std::string time_str = pt::to_simple_string(pt::from_time_t(lineTime.tv_sec)); + + // lops off the YYYY-mmm-DD part of the string + size_t ind = time_str.find(" "); + if(ind != std::string::npos) + time_str = time_str.substr(ind); + QString yLabel(QString("").sprintf("%s.%03ld", time_str.c_str(), lineTime.tv_nsec/1000000)); QwtText t(QString("%1 %2, %3"). arg(p.x(), 0, 'f', GetFrequencyPrecision()). @@ -210,12 +232,6 @@ private: }; -const int WaterfallDisplayPlot::INTENSITY_COLOR_MAP_TYPE_MULTI_COLOR; -const int WaterfallDisplayPlot::INTENSITY_COLOR_MAP_TYPE_WHITE_HOT; -const int WaterfallDisplayPlot::INTENSITY_COLOR_MAP_TYPE_BLACK_HOT; -const int WaterfallDisplayPlot::INTENSITY_COLOR_MAP_TYPE_INCANDESCENT; -const int WaterfallDisplayPlot::INTENSITY_COLOR_MAP_TYPE_USER_DEFINED; - WaterfallDisplayPlot::WaterfallDisplayPlot(QWidget* parent) : QwtPlot(parent) { @@ -259,13 +275,9 @@ WaterfallDisplayPlot::WaterfallDisplayPlot(QWidget* parent) // Ctrl+RighButton: zoom out to full size _zoomer = new WaterfallZoomer(canvas(), 0); -#if QT_VERSION < 0x040000 - _zoomer->setMousePattern(QwtEventPattern::MouseSelect2, - Qt::RightButton, Qt::ControlModifier); -#else + _zoomer->setSelectionFlags(QwtPicker::RectSelection | QwtPicker::DragSelection); _zoomer->setMousePattern(QwtEventPattern::MouseSelect2, Qt::RightButton, Qt::ControlModifier); -#endif _zoomer->setMousePattern(QwtEventPattern::MouseSelect3, Qt::RightButton); @@ -273,6 +285,11 @@ WaterfallDisplayPlot::WaterfallDisplayPlot(QWidget* parent) _panner->setAxisEnabled(QwtPlot::yRight, false); _panner->setMouseButton(Qt::MidButton); + // emit the position of clicks on widget + _picker = new QwtDblClickPlotPicker(canvas()); + connect(_picker, SIGNAL(selected(const QwtDoublePoint &)), + this, SLOT(OnPickerPointSelected(const QwtDoublePoint &))); + // Avoid jumping when labels with more/less digits // appear/disappear when scrolling vertically @@ -285,6 +302,8 @@ WaterfallDisplayPlot::WaterfallDisplayPlot(QWidget* parent) _zoomer->setTrackerPen(c); _UpdateIntensityRangeDisplay(); + + _xAxisMultiplier = 1; } WaterfallDisplayPlot::~WaterfallDisplayPlot() @@ -321,6 +340,8 @@ WaterfallDisplayPlot::SetFrequencyRange(const double constStartFreq, double stopFreq = constStopFreq / units; double centerFreq = constCenterFreq / units; + _xAxisMultiplier = units; + _useCenterFrequencyFlag = useCenterFrequencyFlag; if(_useCenterFrequencyFlag){ @@ -550,4 +571,13 @@ WaterfallDisplayPlot::_UpdateIntensityRangeDisplay() _lastReplot = get_highres_clock(); } +void +WaterfallDisplayPlot::OnPickerPointSelected(const QwtDoublePoint & p) +{ + QPointF point = p; + //fprintf(stderr,"OnPickerPointSelected %f %f %d\n", point.x(), point.y(), _xAxisMultiplier); + point.setX(point.x() * _xAxisMultiplier); + emit plotPointSelected(point); +} + #endif /* WATERFALL_DISPLAY_PLOT_C */ diff --git a/gr-qtgui/src/lib/WaterfallDisplayPlot.h b/gr-qtgui/lib/WaterfallDisplayPlot.h index a5ccaec40..583bf9407 100644 --- a/gr-qtgui/src/lib/WaterfallDisplayPlot.h +++ b/gr-qtgui/lib/WaterfallDisplayPlot.h @@ -1,11 +1,35 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008,2009,2010,2011 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 WATERFALL_DISPLAY_PLOT_HPP #define WATERFALL_DISPLAY_PLOT_HPP +#include <stdint.h> #include <cstdio> #include <qwt_plot.h> #include <qwt_plot_zoomer.h> #include <qwt_plot_panner.h> +#include <qtgui_util.h> #include <plot_waterfall.h> #include <highResTimeFunctions.h> @@ -39,18 +63,22 @@ public: const QColor GetUserDefinedLowIntensityColor()const; const QColor GetUserDefinedHighIntensityColor()const; - static const int INTENSITY_COLOR_MAP_TYPE_MULTI_COLOR = 0; - static const int INTENSITY_COLOR_MAP_TYPE_WHITE_HOT = 1; - static const int INTENSITY_COLOR_MAP_TYPE_BLACK_HOT = 2; - static const int INTENSITY_COLOR_MAP_TYPE_INCANDESCENT = 3; - static const int INTENSITY_COLOR_MAP_TYPE_USER_DEFINED = 4; + enum{ + INTENSITY_COLOR_MAP_TYPE_MULTI_COLOR = 0, + INTENSITY_COLOR_MAP_TYPE_WHITE_HOT = 1, + INTENSITY_COLOR_MAP_TYPE_BLACK_HOT = 2, + INTENSITY_COLOR_MAP_TYPE_INCANDESCENT = 3, + INTENSITY_COLOR_MAP_TYPE_USER_DEFINED = 4 + }; public slots: void resizeSlot( QSize *s ); - + void OnPickerPointSelected(const QwtDoublePoint & p); + signals: void UpdatedLowerIntensityLevel(const double); void UpdatedUpperIntensityLevel(const double); + void plotPointSelected(const QPointF p); protected: @@ -59,12 +87,15 @@ private: double _startFrequency; double _stopFrequency; + int _xAxisMultiplier; PlotWaterfall *d_spectrogram; QwtPlotPanner* _panner; QwtPlotZoomer* _zoomer; + QwtDblClickPlotPicker *_picker; + WaterfallData* _waterfallData; timespec _lastReplot; diff --git a/gr-qtgui/lib/gr_qtgui_api.h b/gr-qtgui/lib/gr_qtgui_api.h new file mode 100644 index 000000000..65033a093 --- /dev/null +++ b/gr-qtgui/lib/gr_qtgui_api.h @@ -0,0 +1,33 @@ +/* + * Copyright 2010 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_GR_QTGUI_API_H +#define INCLUDED_GR_QTGUI_API_H + +#include <gruel/attributes.h> + +#ifdef libgnuradio_qtgui_EXPORTS +# define GR_QTGUI_API __GR_ATTR_EXPORT +#else +# define GR_QTGUI_API __GR_ATTR_IMPORT +#endif + +#endif /* INCLUDED_GR_QTGUI_API_H */ diff --git a/gr-qtgui/src/lib/highResTimeFunctions.h b/gr-qtgui/lib/highResTimeFunctions.h index 251bbad8b..251bbad8b 100644 --- a/gr-qtgui/src/lib/highResTimeFunctions.h +++ b/gr-qtgui/lib/highResTimeFunctions.h diff --git a/gr-qtgui/src/lib/plot_waterfall.cc b/gr-qtgui/lib/plot_waterfall.cc index 2b1447e03..2b1447e03 100644 --- a/gr-qtgui/src/lib/plot_waterfall.cc +++ b/gr-qtgui/lib/plot_waterfall.cc diff --git a/gr-qtgui/src/lib/plot_waterfall.h b/gr-qtgui/lib/plot_waterfall.h index 2be677b10..a11461611 100644 --- a/gr-qtgui/src/lib/plot_waterfall.h +++ b/gr-qtgui/lib/plot_waterfall.h @@ -16,12 +16,10 @@ class QwtColorMap; ( the intensity ) is displayed using colors. The colors are calculated from the values using a color map. - \image html spectrogram3.png - \sa QwtRasterData, QwtColorMap */ -class QWT_EXPORT PlotWaterfall: public QwtPlotRasterItem +class PlotWaterfall: public QwtPlotRasterItem { public: explicit PlotWaterfall(WaterfallData* data, const QString &title = QString::null); diff --git a/gr-qtgui/src/lib/qtgui_sink_c.cc b/gr-qtgui/lib/qtgui_sink_c.cc index c12c451b0..7b40dd01d 100644 --- a/gr-qtgui/src/lib/qtgui_sink_c.cc +++ b/gr-qtgui/lib/qtgui_sink_c.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2008,2009,2010 Free Software Foundation, Inc. + * Copyright 2008,2009,2010,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -35,27 +35,21 @@ qtgui_make_sink_c (int fftsize, int wintype, double fc, double bw, const std::string &name, bool plotfreq, bool plotwaterfall, - bool plotwaterfall3d, bool plottime, - bool plotconst, - bool use_openGL, + bool plottime, bool plotconst, QWidget *parent) { return gnuradio::get_initial_sptr(new qtgui_sink_c (fftsize, wintype, - fc, bw, name, - plotfreq, plotwaterfall, - plotwaterfall3d, plottime, - plotconst, - use_openGL, - parent)); + fc, bw, name, + plotfreq, plotwaterfall, + plottime, plotconst, + parent)); } qtgui_sink_c::qtgui_sink_c (int fftsize, int wintype, double fc, double bw, const std::string &name, bool plotfreq, bool plotwaterfall, - bool plotwaterfall3d, bool plottime, - bool plotconst, - bool use_openGL, + bool plottime, bool plotconst, QWidget *parent) : gr_block ("sink_c", gr_make_io_signature (1, -1, sizeof(gr_complex)), @@ -67,13 +61,7 @@ qtgui_sink_c::qtgui_sink_c (int fftsize, int wintype, d_plottime(plottime), d_plotconst(plotconst), d_parent(parent) { - if(plotwaterfall3d == true) { - fprintf(stderr, "Warning: plotting Waterfall3D has been removed; enabling plotwaterfall3d has no effect.\n"); - } - d_main_gui = NULL; - pthread_mutex_init(&d_pmutex, NULL); - lock(); // Perform fftshift operation; // this is usually desired when plotting @@ -86,7 +74,7 @@ qtgui_sink_c::qtgui_sink_c (int fftsize, int wintype, buildwindow(); - initialize(use_openGL); + initialize(); } qtgui_sink_c::~qtgui_sink_c() @@ -105,25 +93,14 @@ qtgui_sink_c::forecast(int noutput_items, gr_vector_int &ninput_items_required) } } -void qtgui_sink_c::lock() -{ - pthread_mutex_lock(&d_pmutex); -} - -void qtgui_sink_c::unlock() -{ - pthread_mutex_unlock(&d_pmutex); -} - - void -qtgui_sink_c::initialize(const bool opengl) +qtgui_sink_c::initialize() { if(qApp != NULL) { d_qApplication = qApp; } else { - int argc; + int argc=0; char **argv = NULL; d_qApplication = new QApplication(argc, argv); } @@ -144,14 +121,10 @@ qtgui_sink_c::initialize(const bool opengl) d_main_gui->OpenSpectrumWindow(d_parent, d_plotfreq, d_plotwaterfall, - d_plottime, d_plotconst, - opengl); + d_plottime, d_plotconst); // initialize update time to 10 times a second set_update_time(0.1); - - d_object = new qtgui_obj(d_qApplication); - qApp->postEvent(d_object, new qtgui_event(&d_pmutex)); } @@ -289,8 +262,6 @@ qtgui_sink_c::general_work (int noutput_items, int j=0; const gr_complex *in = (const gr_complex*)input_items[0]; - pthread_mutex_lock(&d_pmutex); - // Update the FFT size from the application fftresize(); windowreset(); @@ -322,8 +293,6 @@ qtgui_sink_c::general_work (int noutput_items, } } - pthread_mutex_unlock(&d_pmutex); - consume_each(j); return j; } diff --git a/gr-qtgui/src/lib/qtgui_sink_c.h b/gr-qtgui/lib/qtgui_sink_c.h index 9aee66503..b0946885c 100644 --- a/gr-qtgui/src/lib/qtgui_sink_c.h +++ b/gr-qtgui/lib/qtgui_sink_c.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2008,2009 Free Software Foundation, Inc. + * Copyright 2008,2009,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -24,50 +24,42 @@ #define INCLUDED_QTGUI_SINK_C_H #include <Python.h> +#include <gr_qtgui_api.h> #include <gr_block.h> #include <gr_firdes.h> #include <gri_fft.h> #include <qapplication.h> -#include <qtgui.h> #include "SpectrumGUIClass.h" class qtgui_sink_c; typedef boost::shared_ptr<qtgui_sink_c> qtgui_sink_c_sptr; -qtgui_sink_c_sptr qtgui_make_sink_c (int fftsize, int wintype, +GR_QTGUI_API qtgui_sink_c_sptr qtgui_make_sink_c (int fftsize, int wintype, double fc=0, double bandwidth=1.0, const std::string &name="Spectrum Display", bool plotfreq=true, bool plotwaterfall=true, - bool plotwaterfall3d=true, bool plottime=true, - bool plotconst=true, - bool use_openGL=true, + bool plottime=true, bool plotconst=true, QWidget *parent=NULL); -class qtgui_sink_c : public gr_block +class GR_QTGUI_API qtgui_sink_c : public gr_block { private: - friend qtgui_sink_c_sptr qtgui_make_sink_c (int fftsize, int wintype, + friend GR_QTGUI_API qtgui_sink_c_sptr qtgui_make_sink_c (int fftsize, int wintype, double fc, double bw, const std::string &name, bool plotfreq, bool plotwaterfall, - bool plotwaterfall3d, bool plottime, - bool plotconst, - bool use_openGL, + bool plottime, bool plotconst, QWidget *parent); qtgui_sink_c (int fftsize, int wintype, double fc, double bw, const std::string &name, bool plotfreq, bool plotwaterfall, - bool plotwaterfall3d, bool plottime, - bool plotconst, - bool use_openGL, + bool plottime, bool plotconst, QWidget *parent); void forecast(int noutput_items, gr_vector_int &ninput_items_required); - // use opengl to force OpenGL on or off - // this might be necessary for sessions over SSH - void initialize(const bool opengl=true); + void initialize(); int d_fftsize; gr_firdes::win_type d_wintype; @@ -76,8 +68,6 @@ private: double d_bandwidth; std::string d_name; - pthread_mutex_t d_pmutex; - bool d_shift; gri_fft_complex *d_fft; @@ -99,8 +89,6 @@ private: public: ~qtgui_sink_c(); void exec_(); - void lock(); - void unlock(); QWidget* qwidget(); PyObject* pyqwidget(); @@ -116,7 +104,6 @@ public: void set_update_time(double t); QApplication *d_qApplication; - qtgui_obj *d_object; int general_work (int noutput_items, gr_vector_int &ninput_items, diff --git a/gr-qtgui/src/lib/qtgui_sink_f.cc b/gr-qtgui/lib/qtgui_sink_f.cc index ab4fd082d..3312b9006 100644 --- a/gr-qtgui/src/lib/qtgui_sink_f.cc +++ b/gr-qtgui/lib/qtgui_sink_f.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2008,2009,2010 Free Software Foundation, Inc. + * Copyright 2008,2009,2010,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -35,17 +35,13 @@ qtgui_make_sink_f (int fftsize, int wintype, double fc, double bw, const std::string &name, bool plotfreq, bool plotwaterfall, - bool plotwaterfall3d, bool plottime, - bool plotconst, - bool use_openGL, + bool plottime, bool plotconst, QWidget *parent) { return gnuradio::get_initial_sptr(new qtgui_sink_f (fftsize, wintype, fc, bw, name, plotfreq, plotwaterfall, - plotwaterfall3d, plottime, - plotconst, - use_openGL, + plottime, plotconst, parent)); } @@ -53,9 +49,7 @@ qtgui_sink_f::qtgui_sink_f (int fftsize, int wintype, double fc, double bw, const std::string &name, bool plotfreq, bool plotwaterfall, - bool plotwaterfall3d, bool plottime, - bool plotconst, - bool use_openGL, + bool plottime, bool plotconst, QWidget *parent) : gr_block ("sink_f", gr_make_io_signature (1, 1, sizeof(float)), @@ -67,13 +61,7 @@ qtgui_sink_f::qtgui_sink_f (int fftsize, int wintype, d_plottime(plottime), d_plotconst(plotconst), d_parent(parent) { - if(plotwaterfall3d == true) { - fprintf(stderr, "Warning: plotting Waterfall3D has been removed; enabling plotwaterfall3d has no effect.\n"); - } - d_main_gui = NULL; - pthread_mutex_init(&d_pmutex, NULL); - lock(); // Perform fftshift operation; // this is usually desired when plotting @@ -86,7 +74,7 @@ qtgui_sink_f::qtgui_sink_f (int fftsize, int wintype, buildwindow(); - initialize(use_openGL); + initialize(); } qtgui_sink_f::~qtgui_sink_f() @@ -105,18 +93,8 @@ qtgui_sink_f::forecast(int noutput_items, gr_vector_int &ninput_items_required) } } -void qtgui_sink_f::lock() -{ - pthread_mutex_lock(&d_pmutex); -} - -void qtgui_sink_f::unlock() -{ - pthread_mutex_unlock(&d_pmutex); -} - void -qtgui_sink_f::initialize(const bool opengl) +qtgui_sink_f::initialize() { if(qApp != NULL) { d_qApplication = qApp; @@ -139,14 +117,10 @@ qtgui_sink_f::initialize(const bool opengl) d_main_gui->OpenSpectrumWindow(d_parent, d_plotfreq, d_plotwaterfall, - d_plottime, d_plotconst, - opengl); + d_plottime, d_plotconst); // initialize update time to 10 times a second set_update_time(0.1); - - d_object = new qtgui_obj(d_qApplication); - qApp->postEvent(d_object, new qtgui_event(&d_pmutex)); } void @@ -284,8 +258,6 @@ qtgui_sink_f::general_work (int noutput_items, int j=0; const float *in = (const float*)input_items[0]; - pthread_mutex_lock(&d_pmutex); - // Update the FFT size from the application fftresize(); windowreset(); @@ -317,8 +289,6 @@ qtgui_sink_f::general_work (int noutput_items, } } - pthread_mutex_unlock(&d_pmutex); - consume_each(j); return j; } diff --git a/gr-qtgui/src/lib/qtgui_sink_f.h b/gr-qtgui/lib/qtgui_sink_f.h index 0cac35d90..30db05eea 100644 --- a/gr-qtgui/src/lib/qtgui_sink_f.h +++ b/gr-qtgui/lib/qtgui_sink_f.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2008,2009 Free Software Foundation, Inc. + * Copyright 2008,2009,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -24,48 +24,43 @@ #define INCLUDED_QTGUI_SINK_F_H #include <Python.h> +#include <gr_qtgui_api.h> #include <gr_block.h> #include <gr_firdes.h> #include <gri_fft.h> #include <qapplication.h> -#include <qtgui.h> +//#include <qtgui.h> #include "SpectrumGUIClass.h" class qtgui_sink_f; typedef boost::shared_ptr<qtgui_sink_f> qtgui_sink_f_sptr; -qtgui_sink_f_sptr qtgui_make_sink_f (int fftsize, int wintype, +GR_QTGUI_API qtgui_sink_f_sptr qtgui_make_sink_f (int fftsize, int wintype, double fc=0, double bw=1.0, const std::string &name="Spectrum Display", bool plotfreq=true, bool plotwaterfall=true, - bool plotwaterfall3d=true, bool plottime=true, - bool plotconst=true, - bool use_openGL=true, + bool plottime=true, bool plotconst=true, QWidget *parent=NULL); -class qtgui_sink_f : public gr_block +class GR_QTGUI_API qtgui_sink_f : public gr_block { private: - friend qtgui_sink_f_sptr qtgui_make_sink_f (int fftsize, int wintype, + friend GR_QTGUI_API qtgui_sink_f_sptr qtgui_make_sink_f (int fftsize, int wintype, double fc, double bw, const std::string &name, bool plotfreq, bool plotwaterfall, - bool plotwaterfall3d, bool plottime, - bool plotconst, - bool use_openGL, + bool plottime, bool plotconst, QWidget *parent); qtgui_sink_f (int fftsize, int wintype, double fc, double bw, const std::string &name, bool plotfreq, bool plotwaterfall, - bool plotwaterfall3d, bool plottime, - bool plotconst, - bool use_openGL, + bool plottime, bool plotconst, QWidget *parent); void forecast(int noutput_items, gr_vector_int &ninput_items_required); - void initialize(const bool opengl=true); + void initialize(); int d_fftsize; gr_firdes::win_type d_wintype; @@ -74,8 +69,6 @@ private: double d_bandwidth; std::string d_name; - pthread_mutex_t d_pmutex; - bool d_shift; gri_fft_complex *d_fft; @@ -97,8 +90,6 @@ private: public: ~qtgui_sink_f(); void exec_(); - void lock(); - void unlock(); QWidget* qwidget(); PyObject* pyqwidget(); @@ -114,7 +105,6 @@ public: void set_update_time(double t); QApplication *d_qApplication; - qtgui_obj *d_object; int general_work (int noutput_items, gr_vector_int &ninput_items, diff --git a/gr-qtgui/lib/qtgui_time_sink_c.cc b/gr-qtgui/lib/qtgui_time_sink_c.cc new file mode 100644 index 000000000..6c4793ea1 --- /dev/null +++ b/gr-qtgui/lib/qtgui_time_sink_c.cc @@ -0,0 +1,199 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011 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 <qtgui_time_sink_c.h> +#include <gr_io_signature.h> +#include <string.h> + +#include <QTimer> + +qtgui_time_sink_c_sptr +qtgui_make_time_sink_c (int size, double bw, + const std::string &name, + int nconnections, + QWidget *parent) +{ + return gnuradio::get_initial_sptr(new qtgui_time_sink_c (size, bw, name, + nconnections, parent)); +} + +qtgui_time_sink_c::qtgui_time_sink_c (int size, double bw, + const std::string &name, + int nconnections, + QWidget *parent) + : gr_block ("time_sink_c", + gr_make_io_signature (nconnections, nconnections, sizeof(gr_complex)), + gr_make_io_signature (0, 0, 0)), + d_size(size), d_bandwidth(bw), d_name(name), + d_nconnections(2*nconnections), d_parent(parent) +{ + d_main_gui = NULL; + + d_index = 0; + + for(int i = 0; i < d_nconnections; i++) { + d_residbufs.push_back(new double[d_size]); + } + + initialize(); +} + +qtgui_time_sink_c::~qtgui_time_sink_c() +{ + // d_main_gui is a qwidget destroyed with its parent + for(int i = 0; i < d_nconnections; i++) { + delete [] d_residbufs[i]; + } +} + +void +qtgui_time_sink_c::forecast(int noutput_items, gr_vector_int &ninput_items_required) +{ + unsigned int ninputs = ninput_items_required.size(); + for (unsigned int i = 0; i < ninputs; i++) { + ninput_items_required[i] = std::min(d_size, 8191); + } +} + +void +qtgui_time_sink_c::initialize() +{ + if(qApp != NULL) { + d_qApplication = qApp; + } + else { + int argc=0; + char **argv = NULL; + d_qApplication = new QApplication(argc, argv); + } + + d_main_gui = new TimeDisplayForm(d_nconnections, d_parent); + + // initialize update time to 10 times a second + set_update_time(0.1); + timespec_reset(&d_last_time); +} + + +void +qtgui_time_sink_c::exec_() +{ + d_qApplication->exec(); +} + +QWidget* +qtgui_time_sink_c::qwidget() +{ + return d_main_gui; +} + +PyObject* +qtgui_time_sink_c::pyqwidget() +{ + PyObject *w = PyLong_FromVoidPtr((void*)d_main_gui); + PyObject *retarg = Py_BuildValue("N", w); + return retarg; +} + +void +qtgui_time_sink_c::set_time_domain_axis(double min, double max) +{ + d_main_gui->setTimeDomainAxis(min, max); +} + +void +qtgui_time_sink_c::set_update_time(double t) +{ + d_update_time = t; + d_main_gui->setUpdateTime(d_update_time); +} + +void +qtgui_time_sink_c::set_title(int which, const std::string &title) +{ + d_main_gui->setTitle(which, title.c_str()); +} + +void +qtgui_time_sink_c::set_color(int which, const std::string &color) +{ + d_main_gui->setColor(which, color.c_str()); +} + +int +qtgui_time_sink_c::general_work (int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + int n=0, j=0, idx=0; + const gr_complex *in = (const gr_complex*)input_items[idx]; + + for(int i=0; i < noutput_items; i+=d_size) { + unsigned int datasize = noutput_items - i; + unsigned int resid = d_size-d_index; + idx = 0; + + // If we have enough input for one full plot, do it + if(datasize >= resid) { + d_current_time = get_highres_clock(); + + // Fill up residbufs with d_size number of items + for(n = 0; n < d_nconnections; n+=2) { + in = (const gr_complex*)input_items[idx++]; + for(unsigned int k = 0; k < resid; k++) { + d_residbufs[n][d_index+k] = in[j+k].real(); + d_residbufs[n+1][d_index+k] = in[j+k].imag(); + } + } + + // Update the plot if its time + if(diff_timespec(d_current_time, d_last_time) > d_update_time) { + d_last_time = d_current_time; + d_qApplication->postEvent(d_main_gui, + new TimeUpdateEvent(d_residbufs, d_size)); + } + + d_index = 0; + j += resid; + } + // Otherwise, copy what we received into the residbufs for next time + else { + for(n = 0; n < d_nconnections; n+=2) { + in = (const gr_complex*)input_items[idx++]; + for(unsigned int k = 0; k < resid; k++) { + d_residbufs[n][d_index+k] = in[j+k].real(); + d_residbufs[n+1][d_index+k] = in[j+k].imag(); + } + } + d_index += datasize; + j += datasize; + } + } + + consume_each(j); + return j; +} diff --git a/gr-qtgui/lib/qtgui_time_sink_c.h b/gr-qtgui/lib/qtgui_time_sink_c.h new file mode 100644 index 000000000..aa46ab3a7 --- /dev/null +++ b/gr-qtgui/lib/qtgui_time_sink_c.h @@ -0,0 +1,93 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011 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_TIME_SINK_C_H +#define INCLUDED_QTGUI_TIME_SINK_C_H + +#include <Python.h> +#include <gr_qtgui_api.h> +#include <gr_block.h> +#include <gr_firdes.h> +#include <gri_fft.h> +#include <qapplication.h> +#include <timedisplayform.h> + +class qtgui_time_sink_c; +typedef boost::shared_ptr<qtgui_time_sink_c> qtgui_time_sink_c_sptr; + +GR_QTGUI_API qtgui_time_sink_c_sptr qtgui_make_time_sink_c(int size, double bw, + const std::string &name, + int nconnectons=1, + QWidget *parent=NULL); + +class GR_QTGUI_API qtgui_time_sink_c : public gr_block +{ +private: + friend GR_QTGUI_API qtgui_time_sink_c_sptr qtgui_make_time_sink_c(int size, double bw, + const std::string &name, + int nconnections, + QWidget *parent); + qtgui_time_sink_c(int size, double bw, + const std::string &name, + int nconnections, + QWidget *parent=NULL); + + void forecast(int noutput_items, gr_vector_int &ninput_items_required); + + void initialize(); + + int d_size; + double d_bandwidth; + std::string d_name; + int d_nconnections; + + int d_index; + std::vector<double*> d_residbufs; + + double d_update_time; + + QWidget *d_parent; + TimeDisplayForm *d_main_gui; + + timespec d_current_time; + timespec d_last_time; + +public: + ~qtgui_time_sink_c(); + void exec_(); + QWidget* qwidget(); + PyObject* pyqwidget(); + + void set_time_domain_axis(double min, double max); + void set_update_time(double t); + void set_title(int which, const std::string &title); + void set_color(int which, const std::string &color); + + QApplication *d_qApplication; + + int general_work (int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + +#endif /* INCLUDED_QTGUI_TIME_SINK_C_H */ diff --git a/gr-qtgui/lib/qtgui_time_sink_f.cc b/gr-qtgui/lib/qtgui_time_sink_f.cc new file mode 100644 index 000000000..28789c163 --- /dev/null +++ b/gr-qtgui/lib/qtgui_time_sink_f.cc @@ -0,0 +1,197 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011 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 <qtgui_time_sink_f.h> +#include <gr_io_signature.h> +#include <string.h> + +#include <QTimer> + +qtgui_time_sink_f_sptr +qtgui_make_time_sink_f (int size, double bw, + const std::string &name, + int nconnections, + QWidget *parent) +{ + return gnuradio::get_initial_sptr(new qtgui_time_sink_f (size, bw, name, + nconnections, parent)); +} + +qtgui_time_sink_f::qtgui_time_sink_f (int size, double bw, + const std::string &name, + int nconnections, + QWidget *parent) + : gr_block ("time_sink_f", + gr_make_io_signature (nconnections, nconnections, sizeof(float)), + gr_make_io_signature (0, 0, 0)), + d_size(size), d_bandwidth(bw), d_name(name), + d_nconnections(nconnections), d_parent(parent) +{ + d_main_gui = NULL; + + d_index = 0; + + for(int i = 0; i < d_nconnections; i++) { + d_residbufs.push_back(new double[d_size]); + } + + initialize(); +} + +qtgui_time_sink_f::~qtgui_time_sink_f() +{ + // d_main_gui is a qwidget destroyed with its parent + for(int i = 0; i < d_nconnections; i++) { + delete [] d_residbufs[i]; + } +} + +void +qtgui_time_sink_f::forecast(int noutput_items, gr_vector_int &ninput_items_required) +{ + unsigned int ninputs = ninput_items_required.size(); + for (unsigned int i = 0; i < ninputs; i++) { + ninput_items_required[i] = std::min(d_size, 8191); + } +} + +void +qtgui_time_sink_f::initialize() +{ + if(qApp != NULL) { + d_qApplication = qApp; + } + else { + int argc=0; + char **argv = NULL; + d_qApplication = new QApplication(argc, argv); + } + + d_main_gui = new TimeDisplayForm(d_nconnections, d_parent); + + // initialize update time to 10 times a second + set_update_time(0.1); + timespec_reset(&d_last_time); +} + + +void +qtgui_time_sink_f::exec_() +{ + d_qApplication->exec(); +} + +QWidget* +qtgui_time_sink_f::qwidget() +{ + return d_main_gui; +} + +PyObject* +qtgui_time_sink_f::pyqwidget() +{ + PyObject *w = PyLong_FromVoidPtr((void*)d_main_gui); + PyObject *retarg = Py_BuildValue("N", w); + return retarg; +} + +void +qtgui_time_sink_f::set_time_domain_axis(double min, double max) +{ + d_main_gui->setTimeDomainAxis(min, max); +} + +void +qtgui_time_sink_f::set_update_time(double t) +{ + d_update_time = t; + d_main_gui->setUpdateTime(d_update_time); +} + +void +qtgui_time_sink_f::set_title(int which, const std::string &title) +{ + d_main_gui->setTitle(which, title.c_str()); +} + +void +qtgui_time_sink_f::set_color(int which, const std::string &color) +{ + d_main_gui->setColor(which, color.c_str()); +} + +int +qtgui_time_sink_f::general_work (int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + int n=0, j=0, idx=0; + const float *in = (const float*)input_items[idx]; + + for(int i=0; i < noutput_items; i+=d_size) { + unsigned int datasize = noutput_items - i; + unsigned int resid = d_size-d_index; + idx = 0; + + // If we have enough input for one full plot, do it + if(datasize >= resid) { + d_current_time = get_highres_clock(); + + // Fill up residbufs with d_size number of items + for(n = 0; n < d_nconnections; n++) { + in = (const float*)input_items[idx++]; + for(unsigned int k = 0; k < resid; k++) { + d_residbufs[n][d_index+k] = in[j+k]; + } + } + + // Update the plot if its time + if(diff_timespec(d_current_time, d_last_time) > d_update_time) { + d_last_time = d_current_time; + d_qApplication->postEvent(d_main_gui, + new TimeUpdateEvent(d_residbufs, d_size)); + } + + d_index = 0; + j += resid; + } + // Otherwise, copy what we received into the residbufs for next time + else { + for(n = 0; n < d_nconnections; n++) { + in = (const float*)input_items[idx++]; + for(unsigned int k = 0; k < resid; k++) { + d_residbufs[n][d_index+k] = in[j+k]; + } + } + d_index += datasize; + j += datasize; + } + } + + consume_each(j); + return j; +} diff --git a/gr-qtgui/lib/qtgui_time_sink_f.h b/gr-qtgui/lib/qtgui_time_sink_f.h new file mode 100644 index 000000000..29fca79ee --- /dev/null +++ b/gr-qtgui/lib/qtgui_time_sink_f.h @@ -0,0 +1,93 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011 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_TIME_SINK_F_H +#define INCLUDED_QTGUI_TIME_SINK_F_H + +#include <Python.h> +#include <gr_qtgui_api.h> +#include <gr_block.h> +#include <gr_firdes.h> +#include <gri_fft.h> +#include <qapplication.h> +#include <timedisplayform.h> + +class qtgui_time_sink_f; +typedef boost::shared_ptr<qtgui_time_sink_f> qtgui_time_sink_f_sptr; + +GR_QTGUI_API qtgui_time_sink_f_sptr qtgui_make_time_sink_f(int size, double bw, + const std::string &name, + int nconnectons=1, + QWidget *parent=NULL); + +class GR_QTGUI_API qtgui_time_sink_f : public gr_block +{ +private: + friend GR_QTGUI_API qtgui_time_sink_f_sptr qtgui_make_time_sink_f(int size, double bw, + const std::string &name, + int nconnections, + QWidget *parent); + qtgui_time_sink_f(int size, double bw, + const std::string &name, + int nconnections, + QWidget *parent=NULL); + + void forecast(int noutput_items, gr_vector_int &ninput_items_required); + + void initialize(); + + int d_size; + double d_bandwidth; + std::string d_name; + int d_nconnections; + + int d_index; + std::vector<double*> d_residbufs; + + double d_update_time; + + QWidget *d_parent; + TimeDisplayForm *d_main_gui; + + timespec d_current_time; + timespec d_last_time; + +public: + ~qtgui_time_sink_f(); + void exec_(); + QWidget* qwidget(); + PyObject* pyqwidget(); + + void set_time_domain_axis(double min, double max); + void set_update_time(double t); + void set_title(int which, const std::string &title); + void set_color(int which, const std::string &color); + + QApplication *d_qApplication; + + int general_work (int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + +#endif /* INCLUDED_QTGUI_TIME_SINK_F_H */ diff --git a/gr-qtgui/lib/qtgui_util.cc b/gr-qtgui/lib/qtgui_util.cc new file mode 100644 index 000000000..87b90997a --- /dev/null +++ b/gr-qtgui/lib/qtgui_util.cc @@ -0,0 +1,71 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008,2009 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 <qtgui_util.h> + +QwtPickerDblClickPointMachine::QwtPickerDblClickPointMachine() + : QwtPickerMachine () +{ + +} + +QwtPickerDblClickPointMachine::~QwtPickerDblClickPointMachine() +{ + +} + +QwtPickerMachine::CommandList +QwtPickerDblClickPointMachine::transition(const QwtEventPattern &eventPattern, + const QEvent *e) +{ + QwtPickerMachine::CommandList cmdList; + switch(e->type()) { + case QEvent::MouseButtonDblClick: + if ( eventPattern.mouseMatch(QwtEventPattern::MouseSelect1, + (const QMouseEvent *)e) ) { + cmdList += QwtPickerMachine::Begin; + cmdList += QwtPickerMachine::Append; + cmdList += QwtPickerMachine::End; + } + break; + default: + break; + } + return cmdList; +} + +QwtDblClickPlotPicker::QwtDblClickPlotPicker(QwtPlotCanvas* canvas) + : QwtPlotPicker(canvas) +{ + setSelectionFlags(QwtPicker::PointSelection); +} + +QwtDblClickPlotPicker::~QwtDblClickPlotPicker() +{ +} + +QwtPickerMachine* +QwtDblClickPlotPicker::stateMachine(int n) const +{ + return new QwtPickerDblClickPointMachine; +} + diff --git a/gr-qtgui/src/lib/qtgui.h b/gr-qtgui/lib/qtgui_util.h index 6edbca12c..5b129c7b5 100644 --- a/gr-qtgui/src/lib/qtgui.h +++ b/gr-qtgui/lib/qtgui_util.h @@ -1,70 +1,50 @@ /* -*- c++ -*- */ /* - * Copyright 2008 Free Software Foundation, Inc. - * + * Copyright 2011 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_H -#define INCLUDED_QTGUI_H +#ifndef INCLUDED_QTGUI_UTIL_H +#define INCLUDED_QTGUI_UTIL_H -#include <qapplication.h> -#include "SpectrumGUIClass.h" +#include <qevent.h> +#include <gr_qtgui_api.h> +#include <qwt_plot_picker.h> +#include <qwt_picker_machine.h> -class qtgui_event : public QEvent -{ -private: - pthread_mutex_t *pmutex; +class GR_QTGUI_API QwtDblClickPlotPicker: public QwtPlotPicker +{ public: - qtgui_event(pthread_mutex_t *mut) - : QEvent((QEvent::Type)(QEvent::User+101)) - { - pmutex = mut; - } - - void lock() - { - pthread_mutex_lock(pmutex); - - } + QwtDblClickPlotPicker(QwtPlotCanvas *); + ~QwtDblClickPlotPicker(); - void unlock() - { - pthread_mutex_unlock(pmutex); - } + virtual QwtPickerMachine * stateMachine(int) const; }; -class qtgui_obj : public QObject +class GR_QTGUI_API QwtPickerDblClickPointMachine: public QwtPickerMachine { public: - qtgui_obj(QObject *p) - : QObject(p) - { - } + QwtPickerDblClickPointMachine(); + ~QwtPickerDblClickPointMachine(); - void customEvent(QEvent *e) - { - if(e->type() == (QEvent::Type)(QEvent::User+101)) { - qtgui_event *qt = (qtgui_event*)e; - qt->unlock(); - } - } + virtual CommandList transition( const QwtEventPattern &eventPattern, const QEvent *e); }; -#endif /* INCLUDED_QTGUI_H */ +#endif /* INCLUDED_QTGUI_UTIL_H */ diff --git a/gr-qtgui/src/lib/spectrumUpdateEvents.cc b/gr-qtgui/lib/spectrumUpdateEvents.cc index 53a205fb7..ae4caf31a 100644 --- a/gr-qtgui/src/lib/spectrumUpdateEvents.cc +++ b/gr-qtgui/lib/spectrumUpdateEvents.cc @@ -177,4 +177,47 @@ SpectrumFrequencyRangeEvent::GetStopFrequency() const return _stopFrequency; } + +/***************************************************************************/ +#include <iostream> +TimeUpdateEvent::TimeUpdateEvent(const std::vector<double*> timeDomainPoints, + const uint64_t numTimeDomainDataPoints) + : QEvent(QEvent::Type(10005)) +{ + if(numTimeDomainDataPoints < 1) { + _numTimeDomainDataPoints = 1; + } + else { + _numTimeDomainDataPoints = numTimeDomainDataPoints; + } + + _nplots = timeDomainPoints.size(); + for(size_t i = 0; i < _nplots; i++) { + _dataTimeDomainPoints.push_back(new double[_numTimeDomainDataPoints]); + if(numTimeDomainDataPoints > 0) { + memcpy(_dataTimeDomainPoints[i], timeDomainPoints[i], + _numTimeDomainDataPoints*sizeof(double)); + } + } +} + +TimeUpdateEvent::~TimeUpdateEvent() +{ + for(size_t i = 0; i < _nplots; i++) { + delete[] _dataTimeDomainPoints[i]; + } +} + +const std::vector<double*> +TimeUpdateEvent::getTimeDomainPoints() const +{ + return _dataTimeDomainPoints; +} + +uint64_t +TimeUpdateEvent::getNumTimeDomainDataPoints() const +{ + return _numTimeDomainDataPoints; +} + #endif /* SPECTRUM_UPDATE_EVENTS_C */ diff --git a/gr-qtgui/src/lib/spectrumUpdateEvents.h b/gr-qtgui/lib/spectrumUpdateEvents.h index ccc072c3e..a5e359a4c 100644 --- a/gr-qtgui/src/lib/spectrumUpdateEvents.h +++ b/gr-qtgui/lib/spectrumUpdateEvents.h @@ -5,6 +5,7 @@ #include <QEvent> #include <QString> #include <complex> +#include <vector> #include <highResTimeFunctions.h> class SpectrumUpdateEvent:public QEvent{ @@ -89,4 +90,27 @@ private: }; +class TimeUpdateEvent: public QEvent +{ +public: + TimeUpdateEvent(const std::vector<double*> timeDomainPoints, + const uint64_t numTimeDomainDataPoints); + + ~TimeUpdateEvent(); + + int which() const; + const std::vector<double*> getTimeDomainPoints() const; + uint64_t getNumTimeDomainDataPoints() const; + timespec getDataTimestamp() const; + bool getRepeatDataFlag() const; + +protected: + +private: + size_t _nplots; + std::vector<double*> _dataTimeDomainPoints; + uint64_t _numTimeDomainDataPoints; +}; + + #endif /* SPECTRUM_UPDATE_EVENTS_H */ diff --git a/gr-qtgui/src/lib/spectrumdisplayform.cc b/gr-qtgui/lib/spectrumdisplayform.cc index e0509a294..991f51f47 100644 --- a/gr-qtgui/src/lib/spectrumdisplayform.cc +++ b/gr-qtgui/lib/spectrumdisplayform.cc @@ -1,29 +1,51 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008,2009,2010,2011 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 <QColorDialog> #include <QMessageBox> #include <spectrumdisplayform.h> -int SpectrumDisplayForm::_openGLWaterfall3DFlag = -1; - -SpectrumDisplayForm::SpectrumDisplayForm(bool useOpenGL, QWidget* parent) +SpectrumDisplayForm::SpectrumDisplayForm(QWidget* parent) : QWidget(parent) { setupUi(this); - _useOpenGL = useOpenGL; _systemSpecifiedFlag = false; _intValidator = new QIntValidator(this); _intValidator->setBottom(0); _frequencyDisplayPlot = new FrequencyDisplayPlot(FrequencyPlotDisplayFrame); _waterfallDisplayPlot = new WaterfallDisplayPlot(WaterfallPlotDisplayFrame); - _timeDomainDisplayPlot = new TimeDomainDisplayPlot(TimeDomainDisplayFrame); + _timeDomainDisplayPlot = new TimeDomainDisplayPlot(2, TimeDomainDisplayFrame); _constellationDisplayPlot = new ConstellationDisplayPlot(ConstellationDisplayFrame); _numRealDataPoints = 1024; _realFFTDataPoints = new double[_numRealDataPoints]; _averagedValues = new double[_numRealDataPoints]; _historyVector = new std::vector<double*>; + _timeDomainDisplayPlot->setTitle(0, "real"); + _timeDomainDisplayPlot->setTitle(1, "imag"); + AvgLineEdit->setRange(0, 500); // Set range of Average box value from 0 to 500 MinHoldCheckBox_toggled( false ); MaxHoldCheckBox_toggled( false ); @@ -59,9 +81,25 @@ SpectrumDisplayForm::SpectrumDisplayForm(bool useOpenGL, QWidget* parent) ToggleTabTime(false); ToggleTabConstellation(false); + _historyEntry = 0; + _historyEntryCount = 0; + // Create a timer to update plots at the specified rate displayTimer = new QTimer(this); connect(displayTimer, SIGNAL(timeout()), this, SLOT(UpdateGuiTimer())); + + // Connect double click signals up + connect(_frequencyDisplayPlot, SIGNAL(plotPointSelected(const QPointF)), + this, SLOT(onFFTPlotPointSelected(const QPointF))); + + connect(_waterfallDisplayPlot, SIGNAL(plotPointSelected(const QPointF)), + this, SLOT(onWFallPlotPointSelected(const QPointF))); + + connect(_timeDomainDisplayPlot, SIGNAL(plotPointSelected(const QPointF)), + this, SLOT(onTimePlotPointSelected(const QPointF))); + + connect(_constellationDisplayPlot, SIGNAL(plotPointSelected(const QPointF)), + this, SLOT(onConstPlotPointSelected(const QPointF))); } SpectrumDisplayForm::~SpectrumDisplayForm() @@ -106,13 +144,17 @@ SpectrumDisplayForm::newFrequencyData( const SpectrumUpdateEvent* spectrumUpdate //_lastSpectrumEvent = (SpectrumUpdateEvent)(*spectrumUpdateEvent); const std::complex<float>* complexDataPoints = spectrumUpdateEvent->getFFTPoints(); const uint64_t numFFTDataPoints = spectrumUpdateEvent->getNumFFTDataPoints(); - const double* realTimeDomainDataPoints = spectrumUpdateEvent->getRealTimeDomainPoints(); - const double* imagTimeDomainDataPoints = spectrumUpdateEvent->getImagTimeDomainPoints(); const uint64_t numTimeDomainDataPoints = spectrumUpdateEvent->getNumTimeDomainDataPoints(); const timespec dataTimestamp = spectrumUpdateEvent->getDataTimestamp(); const bool repeatDataFlag = spectrumUpdateEvent->getRepeatDataFlag(); const bool lastOfMultipleUpdatesFlag = spectrumUpdateEvent->getLastOfMultipleUpdateFlag(); const timespec generatedTimestamp = spectrumUpdateEvent->getEventGeneratedTimestamp(); + double* realTimeDomainDataPoints = (double*)spectrumUpdateEvent->getRealTimeDomainPoints(); + double* imagTimeDomainDataPoints = (double*)spectrumUpdateEvent->getImagTimeDomainPoints(); + + std::vector<double*> timeDomainDataPoints; + timeDomainDataPoints.push_back(realTimeDomainDataPoints); + timeDomainDataPoints.push_back(imagTimeDomainDataPoints); // REMEMBER: The dataTimestamp is NOT valid when the repeat data flag is true... ResizeBuffers(numFFTDataPoints, numTimeDomainDataPoints); @@ -197,11 +239,10 @@ SpectrumDisplayForm::newFrequencyData( const SpectrumUpdateEvent* spectrumUpdate _peakAmplitude, d_update_time); } if(tabindex == d_plot_time) { - _timeDomainDisplayPlot->PlotNewData(realTimeDomainDataPoints, - imagTimeDomainDataPoints, + _timeDomainDisplayPlot->PlotNewData(timeDomainDataPoints, numTimeDomainDataPoints, d_update_time); - } + } if(tabindex == d_plot_constellation) { _constellationDisplayPlot->PlotNewData(realTimeDomainDataPoints, imagTimeDomainDataPoints, @@ -660,7 +701,7 @@ SpectrumDisplayForm::ToggleTabConstellation(const bool state) void SpectrumDisplayForm::SetTimeDomainAxis(double min, double max) { - _timeDomainDisplayPlot->set_yaxis(min, max); + _timeDomainDisplayPlot->setYaxis(min, max); } void @@ -689,3 +730,27 @@ SpectrumDisplayForm::SetUpdateTime(double t) // QTimer class takes millisecond input displayTimer->start(d_update_time*1000); } + +void +SpectrumDisplayForm::onFFTPlotPointSelected(const QPointF p) +{ + emit plotPointSelected(p, 1); +} + +void +SpectrumDisplayForm::onWFallPlotPointSelected(const QPointF p) +{ + emit plotPointSelected(p, 2); +} + +void +SpectrumDisplayForm::onTimePlotPointSelected(const QPointF p) +{ + emit plotPointSelected(p, 3); +} + +void +SpectrumDisplayForm::onConstPlotPointSelected(const QPointF p) +{ + emit plotPointSelected(p, 4); +} diff --git a/gr-qtgui/src/lib/spectrumdisplayform.h b/gr-qtgui/lib/spectrumdisplayform.h index fbd08349b..30303a36f 100644 --- a/gr-qtgui/src/lib/spectrumdisplayform.h +++ b/gr-qtgui/lib/spectrumdisplayform.h @@ -1,3 +1,25 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008,2009,2010,2011 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 SPECTRUM_DISPLAY_FORM_H #define SPECTRUM_DISPLAY_FORM_H @@ -20,7 +42,7 @@ class SpectrumDisplayForm : public QWidget, public Ui::SpectrumDisplayForm Q_OBJECT public: - SpectrumDisplayForm(bool useOpenGL = true, QWidget* parent = 0); + SpectrumDisplayForm(QWidget* parent = 0); ~SpectrumDisplayForm(); void setSystem( SpectrumGUIClass * newSystem, const uint64_t numFFTDataPoints, @@ -71,12 +93,17 @@ private slots: void newFrequencyData( const SpectrumUpdateEvent* ); void UpdateGuiTimer(); -protected: + void onFFTPlotPointSelected(const QPointF p); + void onWFallPlotPointSelected(const QPointF p); + void onTimePlotPointSelected(const QPointF p); + void onConstPlotPointSelected(const QPointF p); + +signals: + void plotPointSelected(const QPointF p, int type); private: void _AverageHistory( const double * newBuffer ); - bool _useOpenGL; int _historyEntryCount; int _historyEntry; std::vector<double*>* _historyVector; @@ -95,7 +122,6 @@ private: double _noiseFloorAmplitude; double _peakFrequency; double _peakAmplitude; - static int _openGLWaterfall3DFlag; double _stopFrequency; //SpectrumUpdateEvent _lastSpectrumEvent; @@ -103,7 +129,6 @@ private: // whether or not to use a particular display int d_plot_fft; int d_plot_waterfall; - int d_plot_waterfall3d; int d_plot_time; int d_plot_constellation; diff --git a/gr-qtgui/src/lib/spectrumdisplayform.ui b/gr-qtgui/lib/spectrumdisplayform.ui index 5a23bc8a9..049d4ffeb 100644 --- a/gr-qtgui/src/lib/spectrumdisplayform.ui +++ b/gr-qtgui/lib/spectrumdisplayform.ui @@ -7,7 +7,7 @@ <x>0</x> <y>0</y> <width>712</width> - <height>543</height> + <height>560</height> </rect> </property> <property name="windowTitle"> @@ -182,8 +182,8 @@ </property> <property name="minimumSize"> <size> - <width>400</width> - <height>350</height> + <width>617</width> + <height>400</height> </size> </property> <property name="sizeIncrement"> @@ -705,22 +705,6 @@ </hints> </connection> <connection> - <sender>Waterfall3DAutoScaleBtn</sender> - <signal>clicked()</signal> - <receiver>SpectrumDisplayForm</receiver> - <slot>Waterfall3DAutoScaleBtnCB()</slot> - <hints> - <hint type="sourcelabel"> - <x>22</x> - <y>349</y> - </hint> - <hint type="destinationlabel"> - <x>20</x> - <y>20</y> - </hint> - </hints> - </connection> - <connection> <sender>WaterfallIntensityComboBox</sender> <signal>activated(int)</signal> <receiver>SpectrumDisplayForm</receiver> @@ -737,22 +721,6 @@ </hints> </connection> <connection> - <sender>Waterfall3DIntensityComboBox</sender> - <signal>activated(int)</signal> - <receiver>SpectrumDisplayForm</receiver> - <slot>Waterfall3DIntensityColorTypeChanged(int)</slot> - <hints> - <hint type="sourcelabel"> - <x>92</x> - <y>44</y> - </hint> - <hint type="destinationlabel"> - <x>20</x> - <y>20</y> - </hint> - </hints> - </connection> - <connection> <sender>SpectrumTypeTab</sender> <signal>currentChanged(int)</signal> <receiver>SpectrumDisplayForm</receiver> diff --git a/gr-qtgui/lib/timedisplayform.cc b/gr-qtgui/lib/timedisplayform.cc new file mode 100644 index 000000000..cc4ac9951 --- /dev/null +++ b/gr-qtgui/lib/timedisplayform.cc @@ -0,0 +1,177 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011 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 <QColorDialog> +#include <QMessageBox> +#include <timedisplayform.h> +#include <iostream> + +TimeDisplayForm::TimeDisplayForm(int nplots, QWidget* parent) + : QWidget(parent) +{ + _systemSpecifiedFlag = false; + _intValidator = new QIntValidator(this); + _intValidator->setBottom(0); + + _layout = new QGridLayout(this); + _timeDomainDisplayPlot = new TimeDomainDisplayPlot(nplots, this); + _layout->addWidget(_timeDomainDisplayPlot, 0, 0); + + _numRealDataPoints = 1024; + + setLayout(_layout); + + Reset(); + + // Create a timer to update plots at the specified rate + displayTimer = new QTimer(this); + connect(displayTimer, SIGNAL(timeout()), this, SLOT(updateGuiTimer())); + + connect(_timeDomainDisplayPlot, SIGNAL(plotPointSelected(const QPointF)), + this, SLOT(onTimePlotPointSelected(const QPointF))); +} + +TimeDisplayForm::~TimeDisplayForm() +{ + // Qt deletes children when parent is deleted + + // Don't worry about deleting Display Plots - they are deleted when parents are deleted + delete _intValidator; + + displayTimer->stop(); + delete displayTimer; +} + +void +TimeDisplayForm::newData( const TimeUpdateEvent* spectrumUpdateEvent) +{ + const std::vector<double*> timeDomainDataPoints = spectrumUpdateEvent->getTimeDomainPoints(); + const uint64_t numTimeDomainDataPoints = spectrumUpdateEvent->getNumTimeDomainDataPoints(); + + _timeDomainDisplayPlot->PlotNewData(timeDomainDataPoints, + numTimeDomainDataPoints, + d_update_time); +} + +void +TimeDisplayForm::resizeEvent( QResizeEvent *e ) +{ + QSize s = size(); + emit _timeDomainDisplayPlot->resizeSlot(&s); +} + +void +TimeDisplayForm::customEvent( QEvent * e) +{ + if(e->type() == 10005) { + TimeUpdateEvent* timeUpdateEvent = (TimeUpdateEvent*)e; + newData(timeUpdateEvent); + } + //else if(e->type() == 10008){ + //setWindowTitle(((SpectrumWindowCaptionEvent*)e)->getLabel()); + //} + //else if(e->type() == 10009){ + //Reset(); + //if(_systemSpecifiedFlag){ + // _system->ResetPendingGUIUpdateEvents(); + //} + //} +} + +void +TimeDisplayForm::updateGuiTimer() +{ + _timeDomainDisplayPlot->canvas()->update(); +} + +void +TimeDisplayForm::onTimePlotPointSelected(const QPointF p) +{ + emit plotPointSelected(p, 3); +} + +void +TimeDisplayForm::setFrequencyRange(const double newCenterFrequency, + const double newStartFrequency, + const double newStopFrequency) +{ + double fdiff = std::max(fabs(newStartFrequency), fabs(newStopFrequency)); + + if(fdiff > 0) { + std::string strtime[4] = {"sec", "ms", "us", "ns"}; + double units10 = floor(log10(fdiff)); + double units3 = std::max(floor(units10 / 3.0), 0.0); + double units = pow(10, (units10-fmod(units10, 3.0))); + int iunit = static_cast<int>(units3); + + _startFrequency = newStartFrequency; + _stopFrequency = newStopFrequency; + + _timeDomainDisplayPlot->SetSampleRate(_stopFrequency - _startFrequency, + units, strtime[iunit]); + } +} + +void +TimeDisplayForm::Reset() +{ +} + + +void +TimeDisplayForm::closeEvent( QCloseEvent *e ) +{ + //if(_systemSpecifiedFlag){ + // _system->SetWindowOpenFlag(false); + //} + + qApp->processEvents(); + + QWidget::closeEvent(e); +} + +void +TimeDisplayForm::setTimeDomainAxis(double min, double max) +{ + _timeDomainDisplayPlot->setYaxis(min, max); +} + +void +TimeDisplayForm::setUpdateTime(double t) +{ + d_update_time = t; + // QTimer class takes millisecond input + displayTimer->start(d_update_time*1000); +} + +void +TimeDisplayForm::setTitle(int which, QString title) +{ + _timeDomainDisplayPlot->setTitle(which, title); +} + +void +TimeDisplayForm::setColor(int which, QString color) +{ + _timeDomainDisplayPlot->setColor(which, color); +} diff --git a/gr-qtgui/lib/timedisplayform.h b/gr-qtgui/lib/timedisplayform.h new file mode 100644 index 000000000..1216a1ef5 --- /dev/null +++ b/gr-qtgui/lib/timedisplayform.h @@ -0,0 +1,85 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011 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 TIME_DISPLAY_FORM_H +#define TIME_DISPLAY_FORM_H + +#include <spectrumUpdateEvents.h> +#include <FrequencyDisplayPlot.h> +#include <WaterfallDisplayPlot.h> +#include <TimeDomainDisplayPlot.h> +#include <ConstellationDisplayPlot.h> +#include <QtGui/QApplication> +#include <QtGui/QGridLayout> +#include <QValidator> +#include <QTimer> +#include <vector> + +class TimeDisplayForm : public QWidget +{ + Q_OBJECT + + public: + TimeDisplayForm(int nplots=1, QWidget* parent = 0); + ~TimeDisplayForm(); + + void Reset(); + +public slots: + void resizeEvent( QResizeEvent * e ); + void customEvent( QEvent * e ); + void setFrequencyRange( const double newCenterFrequency, + const double newStartFrequency, + const double newStopFrequency ); + void closeEvent( QCloseEvent * e ); + + void setTimeDomainAxis(double min, double max); + + void setUpdateTime(double t); + + void setTitle(int which, QString title); + void setColor(int which, QString color); + +private slots: + void newData( const TimeUpdateEvent* ); + void updateGuiTimer(); + + void onTimePlotPointSelected(const QPointF p); + +signals: + void plotPointSelected(const QPointF p, int type); + +private: + uint64_t _numRealDataPoints; + QIntValidator* _intValidator; + + QGridLayout *_layout; + TimeDomainDisplayPlot* _timeDomainDisplayPlot; + bool _systemSpecifiedFlag; + double _startFrequency; + double _stopFrequency; + + QTimer *displayTimer; + double d_update_time; +}; + +#endif /* TIME_DISPLAY_FORM_H */ diff --git a/gr-qtgui/src/lib/waterfallGlobalData.cc b/gr-qtgui/lib/waterfallGlobalData.cc index 1ba153f0d..1ba153f0d 100644 --- a/gr-qtgui/src/lib/waterfallGlobalData.cc +++ b/gr-qtgui/lib/waterfallGlobalData.cc diff --git a/gr-qtgui/src/lib/waterfallGlobalData.h b/gr-qtgui/lib/waterfallGlobalData.h index 51f65064c..51f65064c 100644 --- a/gr-qtgui/src/lib/waterfallGlobalData.h +++ b/gr-qtgui/lib/waterfallGlobalData.h diff --git a/gr-qtgui/src/python/.gitignore b/gr-qtgui/python/.gitignore index b336cc7ce..604b402c5 100644 --- a/gr-qtgui/src/python/.gitignore +++ b/gr-qtgui/python/.gitignore @@ -1,2 +1,3 @@ /Makefile /Makefile.in +/run_tests diff --git a/gr-qtgui/src/python/Makefile.am b/gr-qtgui/python/Makefile.am index 5544748df..f1bdf359b 100644 --- a/gr-qtgui/src/python/Makefile.am +++ b/gr-qtgui/python/Makefile.am @@ -21,18 +21,18 @@ include $(top_srcdir)/Makefile.common -noinst_PYTHON = \ - pyqt_example_f.py \ - pyqt_example.py \ - qt_digital.py \ - qt_digital_window.py \ - usrp2_display.py \ - usrp_display.py +TESTS = +EXTRA_DIST += run_tests.in -EXTRA_DIST = \ - qt_digital_window.ui +if PYTHON +TESTS += run_tests +DISTCLEANFILES += run_tests qtguipythondir = $(grpythondir)/qtgui -qtguipython_PYTHON = \ +noinst_PYTHON = \ + qa_qtgui.py + +qtguipython_PYTHON = \ __init__.py +endif diff --git a/gr-qtgui/python/__init__.py b/gr-qtgui/python/__init__.py new file mode 100644 index 000000000..db113bbd3 --- /dev/null +++ b/gr-qtgui/python/__init__.py @@ -0,0 +1,25 @@ +# +# Copyright 2011 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. +# + +# The presence of this file turns this directory into a Python package + +from qtgui_swig import * +import qtgui_swig as qtgui # to preserve the old interface diff --git a/gr-qtgui/python/qa_qtgui.py b/gr-qtgui/python/qa_qtgui.py new file mode 100755 index 000000000..9cafd4550 --- /dev/null +++ b/gr-qtgui/python/qa_qtgui.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python +# +# Copyright 2011 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. +# + +from gnuradio import gr, gr_unittest +import qtgui_swig + +class test_qtgui(gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block () + + def tearDown (self): + self.tb = None + + def test01 (self): + # Test to make sure we can instantiate the sink + self.qtsnk = qtgui_swig.sink_c(1024, gr.firdes.WIN_BLACKMAN_hARRIS, + 0, 1, "Test", + True, True, True, True) + + def test02 (self): + # Test to make sure we can instantiate the sink + self.qtsnk = qtgui_swig.sink_f(1024, gr.firdes.WIN_BLACKMAN_hARRIS, + 0, 1, "Test", + True, True, True, True) + + +if __name__ == '__main__': + gr_unittest.run(test_qtgui, "test_qtgui.xml") diff --git a/gr-qtgui/python/run_tests.in b/gr-qtgui/python/run_tests.in new file mode 100644 index 000000000..909194752 --- /dev/null +++ b/gr-qtgui/python/run_tests.in @@ -0,0 +1,10 @@ +#!/bin/sh + +# 1st parameter is absolute path to component source directory +# 2nd parameter is absolute path to component build directory +# 3rd parameter is path to Python QA directory + +@top_builddir@/run_tests.sh \ + @abs_top_srcdir@/gr-qtgui \ + @abs_top_builddir@/gr-qtgui \ + @srcdir@ diff --git a/gr-qtgui/src/lib/Makefile.swig.gen b/gr-qtgui/src/lib/Makefile.swig.gen deleted file mode 100644 index f40f0d881..000000000 --- a/gr-qtgui/src/lib/Makefile.swig.gen +++ /dev/null @@ -1,259 +0,0 @@ -# -*- Makefile -*- -# -# Copyright 2009 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. -# - -# Makefile.swig.gen for qtgui.i - -## Default install locations for these files: -## -## Default location for the Python directory is: -## ${prefix}/lib/python${python_version}/site-packages/[category]/qtgui -## Default location for the Python exec directory is: -## ${exec_prefix}/lib/python${python_version}/site-packages/[category]/qtgui -## -## The following can be overloaded to change the install location, but -## this has to be done in the including Makefile.am -before- -## Makefile.swig is included. - -qtgui_pythondir_category ?= gnuradio/qtgui -qtgui_pylibdir_category ?= $(qtgui_pythondir_category) -qtgui_pythondir = $(pythondir)/$(qtgui_pythondir_category) -qtgui_pylibdir = $(pyexecdir)/$(qtgui_pylibdir_category) - -## SWIG headers are always installed into the same directory. - -qtgui_swigincludedir = $(swigincludedir) - -## This is a template file for a "generated" Makefile addition (in -## this case, "Makefile.swig.gen"). By including the top-level -## Makefile.swig, this file will be used to generate the SWIG -## dependencies. Assign the variable TOP_SWIG_FILES to be the list of -## SWIG .i files to generated wrappings for; there can be more than 1 -## so long as the names are unique (no sorting is done on the -## TOP_SWIG_FILES list). This file explicitly assumes that a SWIG .i -## file will generate .cc, .py, and possibly .h files -- meaning that -## all of these files will have the same base name (that provided for -## the SWIG .i file). -## -## This code is setup to ensure parallel MAKE ("-j" or "-jN") does the -## right thing. For more info, see < -## http://sources.redhat.com/automake/automake.html#Multiple-Outputs > - -## Stamps used to ensure parallel make does the right thing. These -## are removed by "make clean", but otherwise unused except during the -## parallel built. These will not be included in a tarball, because -## the SWIG-generated files will be removed from the distribution. - -STAMPS += $(DEPDIR)/qtgui-generate-* - -## Other cleaned files: dependency files generated by SWIG or this Makefile - -MOSTLYCLEANFILES += $(DEPDIR)/*.S* - -## Add the .py and .cc files to the list of SWIG built sources. The -## .h file is sometimes built, but not always ... so that one has to -## be added manually by the including Makefile.am . - -swig_built_sources += qtgui.py qtgui.cc - -## Various SWIG variables. These can be overloaded in the including -## Makefile.am by setting the variable value there, then including -## Makefile.swig . - -qtgui_swiginclude_HEADERS = \ - qtgui.i \ - $(qtgui_swiginclude_headers) - -qtgui_pylib_LTLIBRARIES = \ - _qtgui.la - -_qtgui_la_SOURCES = \ - qtgui.cc \ - $(qtgui_la_swig_sources) - -_qtgui_la_LIBADD = \ - $(STD_SWIG_LA_LIB_ADD) \ - $(qtgui_la_swig_libadd) - -_qtgui_la_LDFLAGS = \ - $(STD_SWIG_LA_LD_FLAGS) \ - $(qtgui_la_swig_ldflags) - -_qtgui_la_CXXFLAGS = \ - $(STD_SWIG_CXX_FLAGS) \ - $(qtgui_la_swig_cxxflags) - -qtgui_python_PYTHON = \ - qtgui.py \ - $(qtgui_python) - -## Entry rule for running SWIG - -qtgui.h qtgui.py qtgui.cc: qtgui.i -## This rule will get called only when MAKE decides that one of the -## targets needs to be created or re-created, because: -## -## * The .i file is newer than any or all of the generated files; -## -## * Any or all of the .cc, .h, or .py files does not exist and is -## needed (in the case this file is not needed, the rule for it is -## ignored); or -## -## * Some SWIG-based dependecy of the .cc file isn't met and hence the -## .cc file needs be be regenerated. Explanation: Because MAKE -## knows how to handle dependencies for .cc files (regardless of -## their name or extension), then the .cc file is used as a target -## instead of the .i file -- but with the dependencies of the .i -## file. It is this last reason why the line: -## -## if test -f $@; then :; else -## -## cannot be used in this case: If a .i file dependecy is not met, -## then the .cc file needs to be rebuilt. But if the stamp is newer -## than the .cc file, and the .cc file exists, then in the original -## version (with the 'test' above) the internal MAKE call will not -## be issued and hence the .cc file will not be rebuilt. -## -## Once execution gets to here, it should always proceed no matter the -## state of a stamp (as discussed in link above). The -## $(DEPDIR)/qtgui-generate stuff is used to allow for parallel -## builds to "do the right thing". The stamp has no relationship with -## either the target files or dependency file; it is used solely for -## the protection of multiple builds during a given call to MAKE. -## -## Catch signals SIGHUP (1), SIGINT (2), SIGPIPE (13), and SIGTERM -## (15). At a caught signal, the quoted command will be issued before -## exiting. In this case, remove any stamp, whether temporary of not. -## The trap is valid until the process exits; the process includes all -## commands appended via "\"s. -## - trap 'rm -rf $(DEPDIR)/qtgui-generate-*' 1 2 13 15; \ -## -## Create a temporary directory, which acts as a lock. The first -## process to create the directory will succeed and issue the MAKE -## command to do the actual work, while all subsequent processes will -## fail -- leading them to wait for the first process to finish. -## - if mkdir $(DEPDIR)/qtgui-generate-lock 2>/dev/null; then \ -## -## This code is being executed by the first process to succeed in -## creating the directory lock. -## -## Remove the stamp associated with this filename. -## - rm -f $(DEPDIR)/qtgui-generate-stamp; \ -## -## Tell MAKE to run the rule for creating this stamp. -## - $(MAKE) $(AM_MAKEFLAGS) $(DEPDIR)/qtgui-generate-stamp WHAT=$<; \ -## -## Now that the .cc, .h, and .py files have been (re)created from the -## .i file, future checking of this rule during the same MAKE -## execution will come back that the rule doesn't need to be executed -## because none of the conditions mentioned at the start of this rule -## will be positive. Remove the the directory lock, which frees up -## any waiting process(es) to continue. -## - rmdir $(DEPDIR)/qtgui-generate-lock; \ - else \ -## -## This code is being executed by any follower processes while the -## directory lock is in place. -## -## Wait until the first process is done, testing once per second. -## - while test -d $(DEPDIR)/qtgui-generate-lock; do \ - sleep 1; \ - done; \ -## -## Succeed if and only if the first process succeeded; exit this -## process returning the status of the generated stamp. -## - test -f $(DEPDIR)/qtgui-generate-stamp; \ - exit $$?; \ - fi; - -$(DEPDIR)/qtgui-generate-stamp: -## This rule will be called only by the first process issuing the -## above rule to succeed in creating the lock directory, after -## removing the actual stamp file in order to guarantee that MAKE will -## execute this rule. -## -## Call SWIG to generate the various output files; special -## post-processing on 'mingw32' host OS for the dependency file. -## - if $(SWIG) $(STD_SWIG_PYTHON_ARGS) $(qtgui_swig_args) \ - -MD -MF $(DEPDIR)/qtgui.Std \ - -module qtgui -o qtgui.cc $(WHAT); then \ - if test $(host_os) = mingw32; then \ - $(RM) $(DEPDIR)/qtgui.Sd; \ - $(SED) 's,\\\\,/,g' < $(DEPDIR)/qtgui.Std \ - > $(DEPDIR)/qtgui.Sd; \ - $(RM) $(DEPDIR)/qtgui.Std; \ - $(MV) $(DEPDIR)/qtgui.Sd $(DEPDIR)/qtgui.Std; \ - fi; \ - else \ - $(RM) $(DEPDIR)/qtgui.S*; exit 1; \ - fi; -## -## Mess with the SWIG output .Std dependency file, to create a -## dependecy file valid for the input .i file: Basically, simulate the -## dependency file created for libraries by GNU's libtool for C++, -## where all of the dependencies for the target are first listed, then -## each individual dependency is listed as a target with no further -## dependencies. -## -## (1) remove the current dependency file -## - $(RM) $(DEPDIR)/qtgui.d -## -## (2) Copy the whole SWIG file: -## - cp $(DEPDIR)/qtgui.Std $(DEPDIR)/qtgui.d -## -## (3) all a carriage return to the end of the dependency file. -## - echo "" >> $(DEPDIR)/qtgui.d -## -## (4) from the SWIG file, remove the first line (the target); remove -## trailing " \" and " " from each line. Append ":" to each line, -## followed by 2 carriage returns, then append this to the end of -## the dependency file. -## - $(SED) -e '1d;s, \\,,g;s, ,,g' < $(DEPDIR)/qtgui.Std | \ - awk '{ printf "%s:\n\n", $$0 }' >> $(DEPDIR)/qtgui.d -## -## (5) remove the SWIG-generated file -## - $(RM) $(DEPDIR)/qtgui.Std -## -## Create the stamp for this filename generation, to signal success in -## executing this rule; allows other threads waiting on this process -## to continue. -## - touch $(DEPDIR)/qtgui-generate-stamp - -# KLUDGE: Force runtime include of a SWIG dependency file. This is -# not guaranteed to be portable, but will probably work. If it works, -# we have accurate dependencies for our swig stuff, which is good. - -@am__include@ @am__quote@./$(DEPDIR)/qtgui.d@am__quote@ - diff --git a/gr-qtgui/src/lib/TimeDomainDisplayPlot.h b/gr-qtgui/src/lib/TimeDomainDisplayPlot.h deleted file mode 100644 index 5525bbabe..000000000 --- a/gr-qtgui/src/lib/TimeDomainDisplayPlot.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef TIME_DOMAIN_DISPLAY_PLOT_HPP -#define TIME_DOMAIN_DISPLAY_PLOT_HPP - -#include <cstdio> -#include <qwt_plot.h> -#include <qwt_painter.h> -#include <qwt_plot_canvas.h> -#include <qwt_plot_curve.h> -#include <qwt_scale_engine.h> -#include <qwt_scale_widget.h> -#include <qwt_plot_zoomer.h> -#include <qwt_plot_panner.h> -#include <qwt_plot_marker.h> -#include <highResTimeFunctions.h> -#include <qwt_symbol.h> - -class TimeDomainDisplayPlot:public QwtPlot{ - Q_OBJECT - -public: - TimeDomainDisplayPlot(QWidget*); - virtual ~TimeDomainDisplayPlot(); - - void PlotNewData(const double* realDataPoints, const double* imagDataPoints, - const int64_t numDataPoints, const double timeInterval); - - void SetImaginaryDataVisible(const bool); - - virtual void replot(); - - void set_yaxis(double min, double max); - void set_xaxis(double min, double max); - -public slots: - void resizeSlot( QSize *s ); - void SetSampleRate(double sr, double units, - const std::string &strunits); - -protected slots: - void LegendEntryChecked(QwtPlotItem *plotItem, bool on); - -protected: - -private: - void _resetXAxisPoints(); - - QwtPlotCurve* _real_plot_curve; - QwtPlotCurve* _imag_plot_curve; - - QwtPlotPanner* _panner; - QwtPlotZoomer* _zoomer; - - double* _realDataPoints; - double* _imagDataPoints; - double* _xAxisPoints; - - double _sampleRate; - - timespec _lastReplot; - - int64_t _numPoints; -}; - -#endif /* TIME_DOMAIN_DISPLAY_PLOT_HPP */ diff --git a/gr-qtgui/src/python/__init__.py b/gr-qtgui/src/python/__init__.py deleted file mode 100644 index e69de29bb..000000000 --- a/gr-qtgui/src/python/__init__.py +++ /dev/null diff --git a/gr-qtgui/swig/.gitignore b/gr-qtgui/swig/.gitignore new file mode 100644 index 000000000..282522db0 --- /dev/null +++ b/gr-qtgui/swig/.gitignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/gr-qtgui/swig/Makefile.am b/gr-qtgui/swig/Makefile.am new file mode 100644 index 000000000..1d8319987 --- /dev/null +++ b/gr-qtgui/swig/Makefile.am @@ -0,0 +1,57 @@ +# +# Copyright 2004-2006,2008-2011 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 $(top_srcdir)/Makefile.common +include $(top_srcdir)/Makefile.swig + +TESTS = +EXTRA_DIST += $(nobase_guile_DATA) + +AM_CPPFLAGS = \ + -I$(top_srcdir)/gr-qtgui/lib \ + -I$(top_builddir)/gr-qtgui/lib \ + $(STD_DEFINES_AND_INCLUDES) \ + $(PYTHON_CPPFLAGS) \ + $(QT_INCLUDES) \ + $(WITH_INCLUDES) + +############################## +# SWIG interface and library +TOP_SWIG_IFILES = \ + qtgui_swig.i + +# Install so that they end up available as: +# import gnuradio.qtgui +# This ends up at: +# ${prefix}/lib/python${python_version}/site-packages/gnuradio/qtgui +qtgui_swig_pythondir_category = \ + gnuradio/qtgui + +# additional libraries for linking with the SWIG-generated library +qtgui_swig_la_swig_libadd = \ + $(abs_top_builddir)/gr-qtgui/lib/libgnuradio-qtgui.la + +# additional SWIG files to be installed +qtgui_swig_swiginclude_headers = \ + qtgui_sink_c.i \ + qtgui_sink_f.i \ + qtgui_time_sink_c.i \ + qtgui_time_sink_f.i diff --git a/gr-qtgui/swig/Makefile.swig.gen b/gr-qtgui/swig/Makefile.swig.gen new file mode 100644 index 000000000..3659601c3 --- /dev/null +++ b/gr-qtgui/swig/Makefile.swig.gen @@ -0,0 +1,145 @@ +# -*- Makefile -*- +# +# Copyright 2009 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. +# + +# Makefile.swig.gen for qtgui_swig.i + +## Default install locations for these files: +## +## Default location for the Python directory is: +## ${prefix}/lib/python${python_version}/site-packages/[category]/qtgui_swig +## Default location for the Python exec directory is: +## ${exec_prefix}/lib/python${python_version}/site-packages/[category]/qtgui_swig +## +## The following can be overloaded to change the install location, but +## this has to be done in the including Makefile.am -before- +## Makefile.swig is included. + +qtgui_swig_pythondir_category ?= gnuradio/qtgui_swig +qtgui_swig_pylibdir_category ?= $(qtgui_swig_pythondir_category) +qtgui_swig_pythondir = $(pythondir)/$(qtgui_swig_pythondir_category) +qtgui_swig_pylibdir = $(pyexecdir)/$(qtgui_swig_pylibdir_category) + +# The .so libraries for the guile modules get installed whereever guile +# is installed, usually /usr/lib/guile/gnuradio/ +# FIXME: determince whether these should be installed with gnuradio. +qtgui_swig_scmlibdir = $(libdir) + +# The scm files for the guile modules get installed where ever guile +# is installed, usually /usr/share/guile/site/qtgui_swig +# FIXME: determince whether these should be installed with gnuradio. +qtgui_swig_scmdir = $(guiledir) + +## SWIG headers are always installed into the same directory. + +qtgui_swig_swigincludedir = $(swigincludedir) + +## This is a template file for a "generated" Makefile addition (in +## this case, "Makefile.swig.gen"). By including the top-level +## Makefile.swig, this file will be used to generate the SWIG +## dependencies. Assign the variable TOP_SWIG_FILES to be the list of +## SWIG .i files to generated wrappings for; there can be more than 1 +## so long as the names are unique (no sorting is done on the +## TOP_SWIG_FILES list). This file explicitly assumes that a SWIG .i +## file will generate .cc, .py, and possibly .h files -- meaning that +## all of these files will have the same base name (that provided for +## the SWIG .i file). +## +## This code is setup to ensure parallel MAKE ("-j" or "-jN") does the +## right thing. For more info, see < +## http://sources.redhat.com/automake/automake.html#Multiple-Outputs > + +## Other cleaned files: dependency files generated by SWIG or this Makefile + +MOSTLYCLEANFILES += $(DEPDIR)/*.S* + +## Various SWIG variables. These can be overloaded in the including +## Makefile.am by setting the variable value there, then including +## Makefile.swig . + +qtgui_swig_swiginclude_HEADERS = \ + qtgui_swig.i \ + $(qtgui_swig_swiginclude_headers) + +if PYTHON +qtgui_swig_pylib_LTLIBRARIES = \ + _qtgui_swig.la + +_qtgui_swig_la_SOURCES = \ + python/qtgui_swig.cc \ + $(qtgui_swig_la_swig_sources) + +qtgui_swig_python_PYTHON = \ + qtgui_swig.py \ + $(qtgui_swig_python) + +_qtgui_swig_la_LIBADD = \ + $(STD_SWIG_LA_LIB_ADD) \ + $(qtgui_swig_la_swig_libadd) + +_qtgui_swig_la_LDFLAGS = \ + $(STD_SWIG_LA_LD_FLAGS) \ + $(qtgui_swig_la_swig_ldflags) + +_qtgui_swig_la_CXXFLAGS = \ + $(STD_SWIG_CXX_FLAGS) \ + -I$(top_builddir) \ + $(qtgui_swig_la_swig_cxxflags) + +python/qtgui_swig.cc: qtgui_swig.py +qtgui_swig.py: qtgui_swig.i + +# Include the python dependencies for this file +-include python/qtgui_swig.d + +endif # end of if python + +if GUILE + +qtgui_swig_scmlib_LTLIBRARIES = \ + libguile-gnuradio-qtgui_swig.la +libguile_gnuradio_qtgui_swig_la_SOURCES = \ + guile/qtgui_swig.cc \ + $(qtgui_swig_la_swig_sources) +nobase_qtgui_swig_scm_DATA = \ + gnuradio/qtgui_swig.scm \ + gnuradio/qtgui_swig-primitive.scm +libguile_gnuradio_qtgui_swig_la_LIBADD = \ + $(STD_SWIG_LA_LIB_ADD) \ + $(qtgui_swig_la_swig_libadd) +libguile_gnuradio_qtgui_swig_la_LDFLAGS = \ + $(STD_SWIG_LA_LD_FLAGS) \ + $(qtgui_swig_la_swig_ldflags) +libguile_gnuradio_qtgui_swig_la_CXXFLAGS = \ + $(STD_SWIG_CXX_FLAGS) \ + -I$(top_builddir) \ + $(qtgui_swig_la_swig_cxxflags) + +guile/qtgui_swig.cc: gnuradio/qtgui_swig.scm +gnuradio/qtgui_swig.scm: qtgui_swig.i +gnuradio/qtgui_swig-primitive.scm: gnuradio/qtgui_swig.scm + +# Include the guile dependencies for this file +-include guile/qtgui_swig.d + +endif # end of GUILE + + diff --git a/gr-qtgui/src/Makefile.am b/gr-qtgui/swig/__init__.py index 52b06fbc4..3986f2513 100644 --- a/gr-qtgui/src/Makefile.am +++ b/gr-qtgui/swig/__init__.py @@ -1,5 +1,5 @@ # -# Copyright 2008 Free Software Foundation, Inc. +# Copyright 2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -19,7 +19,6 @@ # Boston, MA 02110-1301, USA. # -SUBDIRS = lib -if PYTHON -SUBDIRS += python -endif +# The presence of this file turns this directory into a Python package + +from qtgui_swig import * diff --git a/gr-qtgui/swig/qtgui_sink_c.i b/gr-qtgui/swig/qtgui_sink_c.i new file mode 100644 index 000000000..ff6241482 --- /dev/null +++ b/gr-qtgui/swig/qtgui_sink_c.i @@ -0,0 +1,66 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008,2009,2011 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 "gnuradio.i" + +%{ +#include <qtgui_sink_c.h> +%} + +GR_SWIG_BLOCK_MAGIC(qtgui,sink_c) + +qtgui_sink_c_sptr qtgui_make_sink_c (int fftsize, int wintype, + double fc=0, double bw=1.0, + const std::string &name="Display", + bool plotfreq=true, bool plotwaterfall=true, + bool plottime=true, bool plotconst=true, + QWidget *parent=NULL); + +class qtgui_sink_c : public gr_block +{ +private: + friend qtgui_sink_c_sptr qtgui_make_sink_c (int fftsize, int wintype, + double fc, double bw, + const std::string &name, + bool plotfreq, bool plotwaterfall, + bool plottime, bool plotconst, + QWidget *parent); + qtgui_sink_c (int fftsize, int wintype, + double fc, double bw, + const std::string &name, + bool plotfreq, bool plotwaterfall, + bool plottime, bool plotconst, + QWidget *parent); + +public: + void exec_(); + PyObject* pyqwidget(); + + void set_frequency_range(const double centerfreq, + const double bandwidth); + void set_time_domain_axis(double min, double max); + void set_constellation_axis(double xmin, double xmax, + double ymin, double ymax); + void set_frequency_axis(double min, double max); + void set_constellation_pen_size(int size); + void set_update_time(double t); +}; diff --git a/gr-qtgui/src/lib/qtgui.i b/gr-qtgui/swig/qtgui_sink_f.i index 1f50bf43c..c5eb656b9 100644 --- a/gr-qtgui/src/lib/qtgui.i +++ b/gr-qtgui/swig/qtgui_sink_f.i @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2008,2009 Free Software Foundation, Inc. + * Copyright 2008,2009,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -23,68 +23,16 @@ %include "gnuradio.i" %{ -#include "qtgui_sink_c.h" -#include "qtgui_sink_f.h" +#include <qtgui_sink_f.h> %} -GR_SWIG_BLOCK_MAGIC(qtgui,sink_c) - - qtgui_sink_c_sptr qtgui_make_sink_c (int fftsize, int wintype, - double fc=0, double bw=1.0, - const std::string &name="Display", - bool plotfreq=true, bool plotwaterfall=true, - bool plotwaterfall3d=true, bool plottime=true, - bool plotconst=true, - bool use_openGL=true, - QWidget *parent=NULL); - -class qtgui_sink_c : public gr_block -{ -private: - friend qtgui_sink_c_sptr qtgui_make_sink_c (int fftsize, int wintype, - double fc, double bw, - const std::string &name, - bool plotfreq, bool plotwaterfall, - bool plotwaterfall3d, bool plottime, - bool plotconst, - bool use_openGL, - QWidget *parent); - qtgui_sink_c (int fftsize, int wintype, - double fc, double bw, - const std::string &name, - bool plotfreq, bool plotwaterfall, - bool plotwaterfall3d, bool plottime, - bool plotconst, - bool use_openGL, - QWidget *parent); - -public: - void exec_(); - PyObject* pyqwidget(); - - void set_frequency_range(const double centerfreq, - const double bandwidth); - void set_time_domain_axis(double min, double max); - void set_constellation_axis(double xmin, double xmax, - double ymin, double ymax); - void set_frequency_axis(double min, double max); - void set_constellation_pen_size(int size); -}; - - - -/*********************************************************************/ - - GR_SWIG_BLOCK_MAGIC(qtgui,sink_f) qtgui_sink_f_sptr qtgui_make_sink_f (int fftsize, int wintype, double fc=0, double bw=0.0, const std::string &name="Display", bool plotfreq=true, bool plotwaterfall=true, - bool plotwaterfall3d=true, bool plottime=true, - bool plotconst=true, - bool use_openGL=true, + bool plottime=true, bool plotconst=true, QWidget *parent=NULL); class qtgui_sink_f : public gr_block @@ -94,17 +42,13 @@ private: double fc, double bw, const std::string &name, bool plotfreq, bool plotwaterfall, - bool plotwaterfall3d, bool plottime, - bool plotconst, - bool use_openGL, + bool plottime, bool plotconst, QWidget *parent); qtgui_sink_f (int fftsize, int wintype, double fc, double bw, const std::string &name, bool plotfreq, bool plotwaterfall, - bool plotwaterfall3d, bool plottime, - bool plotconst, - bool use_openGL, + bool plottime, bool plotconst, QWidget *parent); public: @@ -118,5 +62,5 @@ public: double ymin, double ymax); void set_frequency_axis(double min, double max); void set_constellation_pen_size(int size); + void set_update_time(double t); }; - diff --git a/gr-qtgui/swig/qtgui_swig.i b/gr-qtgui/swig/qtgui_swig.i new file mode 100644 index 000000000..5a4ffd6fb --- /dev/null +++ b/gr-qtgui/swig/qtgui_swig.i @@ -0,0 +1,35 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008,2009,2011 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 "gnuradio.i" + +%{ +#include <qtgui_sink_c.h> +#include <qtgui_sink_f.h> +#include <qtgui_time_sink_c.h> +#include <qtgui_time_sink_f.h> +%} + +%include "qtgui_sink_c.i" +%include "qtgui_sink_f.i" +%include "qtgui_time_sink_c.i" +%include "qtgui_time_sink_f.i" diff --git a/gr-qtgui/swig/qtgui_time_sink_c.i b/gr-qtgui/swig/qtgui_time_sink_c.i new file mode 100644 index 000000000..8f5c9f4f0 --- /dev/null +++ b/gr-qtgui/swig/qtgui_time_sink_c.i @@ -0,0 +1,56 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011 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 "gnuradio.i" + +%{ +#include <qtgui_time_sink_c.h> +%} + +GR_SWIG_BLOCK_MAGIC(qtgui,time_sink_c) + +qtgui_time_sink_c_sptr qtgui_make_time_sink_c(int size, double bw, + const std::string &name, + int nconnections=1, + QWidget *parent=NULL); + +class qtgui_time_sink_c : public gr_block +{ +private: + friend qtgui_time_sink_c_sptr qtgui_make_time_sink_c(int size, double bw, + const std::string &name, + int nconnections, + QWidget *parent); + qtgui_time_sink_c(int size, double bw, + const std::string &name, + int nconnections, + QWidget *parent=NULL); + +public: + void exec_(); + PyObject* pyqwidget(); + + void set_time_domain_axis(double min, double max); + void set_update_time(double t); + void set_title(int which, const std::string &title); + void set_color(int which, const std::string &color); +}; diff --git a/gr-qtgui/swig/qtgui_time_sink_f.i b/gr-qtgui/swig/qtgui_time_sink_f.i new file mode 100644 index 000000000..b92efe7be --- /dev/null +++ b/gr-qtgui/swig/qtgui_time_sink_f.i @@ -0,0 +1,56 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011 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 "gnuradio.i" + +%{ +#include <qtgui_time_sink_f.h> +%} + +GR_SWIG_BLOCK_MAGIC(qtgui,time_sink_f) + +qtgui_time_sink_f_sptr qtgui_make_time_sink_f(int size, double bw, + const std::string &name, + int nconnections=1, + QWidget *parent=NULL); + +class qtgui_time_sink_f : public gr_block +{ +private: + friend qtgui_time_sink_f_sptr qtgui_make_time_sink_f(int size, double bw, + const std::string &name, + int nconnections, + QWidget *parent); + qtgui_time_sink_f(int size, double bw, + const std::string &name, + int nconnections, + QWidget *parent=NULL); + +public: + void exec_(); + PyObject* pyqwidget(); + + void set_time_domain_axis(double min, double max); + void set_update_time(double t); + void set_title(int which, const std::string &title); + void set_color(int which, const std::string &color); +}; |